diff --git a/DEPS b/DEPS index 81f205d..5977187 100644 --- a/DEPS +++ b/DEPS
@@ -105,11 +105,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': '92d10833de63e85e933629bb27c5ab274479cd95', + 'skia_revision': '032f2756df640c217690be4cd6ad3ec84093700d', # 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': 'be4324e992f9750839062a195c08b365f73ab176', + 'v8_revision': '949f77f4a144d0167cf046d76f8da0ca7d318f49', # 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. @@ -117,7 +117,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '14246813a110fe2f67ed01dfb2102b6d72cc7ec4', + 'angle_revision': '5476e805a321d786f8b6a003ab95b1bee0c30964', # 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. @@ -165,7 +165,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': '56216d7832a46730d5d9d6bba7fa5742d9601390', + 'catapult_revision': 'de52d9ad295ecc6401de6d7cc3b468a0e8292308', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -213,7 +213,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': '3b5960174f6d652feb4fb912b7fd84a23bbcde7d', + 'spv_tools_revision': '497958d899c3f5fb4a4bda1a942c6fd7c0132ba6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -595,7 +595,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '15082f69653d10a9173e18fe883effd6187bfb1a', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '39be1c969580eea5b7d66fc258174da505cb11ce', 'condition': 'checkout_linux', }, @@ -620,7 +620,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'f98905e8f03cd79d132cdd72bf4af1bb5fa3ca0b', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2fb6310237302dd249452470fcddeaaf2eb3941d', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -954,7 +954,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '7a4d068d23a61a4ad7ec0fe333e2597ef686157c', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f8ef3c03bb5d6ac52975a4a571d28fc5582f8cb6', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1106,7 +1106,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6d2f3f4cb8bac1f7c4a945c73d07a33df74f22f9', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '0a74e09b39c192dddaa9bd1f1015a897c2c5eea8', + Var('webrtc_git') + '/src.git' + '@' + 'a1134509c91d8e38635f8800347d50ddeb22def6', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1137,7 +1137,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@30f82e022cc45f924314bbfa23e3ed3e67e1dd8b', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@263549ba0d66a016ca4fe4d8a8eabc1e799b8e02', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_safe_browsing_blocking_page.cc b/android_webview/browser/aw_safe_browsing_blocking_page.cc index b2a6cae..384a495 100644 --- a/android_webview/browser/aw_safe_browsing_blocking_page.cc +++ b/android_webview/browser/aw_safe_browsing_blocking_page.cc
@@ -103,7 +103,7 @@ false, // is_off_the_record false, // is_unified_consent_enabled safe_browsing::IsExtendedReportingEnabled(*pref_service), - safe_browsing::IsScout(*pref_service), + true, // is_scout_reporting_enabled safe_browsing::IsExtendedReportingPolicyManaged(*pref_service), pref_service->GetBoolean( ::prefs::kSafeBrowsingProceedAnywayDisabled),
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 79a86bd..7758983 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -92,11 +92,7 @@ "accelerators/accelerator_confirmation_dialog.cc", "accelerators/accelerator_confirmation_dialog.h", "accelerators/accelerator_controller.cc", - "accelerators/accelerator_delegate.cc", - "accelerators/accelerator_delegate.h", "accelerators/accelerator_ids.h", - "accelerators/accelerator_router.cc", - "accelerators/accelerator_router.h", "accelerators/accelerator_table.cc", "accelerators/accelerator_table.h", "accelerators/ash_focus_manager_factory.cc", @@ -109,6 +105,8 @@ "accelerators/key_hold_detector.h", "accelerators/magnifier_key_scroller.cc", "accelerators/magnifier_key_scroller.h", + "accelerators/pre_target_accelerator_handler.cc", + "accelerators/pre_target_accelerator_handler.h", "accelerators/spoken_feedback_toggler.cc", "accelerators/spoken_feedback_toggler.h", "accessibility/accessibility_controller.cc",
diff --git a/ash/accelerators/README.md b/ash/accelerators/README.md index ea6f75d8..a060492 100644 --- a/ash/accelerators/README.md +++ b/ash/accelerators/README.md
@@ -3,17 +3,17 @@ 1. wm::AcceleratorFilter() sees events first as it's a pre-target handler on Shell. -2. wm::AcceleratorFilter calls to AcceleratorDelegate. -3. AcceleratorDelegate calls AcceleratorRouter. AcceleratorRouter handles -accelerators that need to be handled early on, such as system keys. This does -not include accelerators such as control-n (for new window). +2. wm::AcceleratorFilter calls to PreTargetAcceleratorHandler. +3. PreTargetAcceleratorHandler handles accelerators that need to be handled +early on, such as system keys. This does not include accelerators such as +control-n (for new window). 4. If focus is on a Widget, then views handles the accelerator. 5. Views does normally processing first (meaning sends to the focused view). If the focused view doesn't handle the event, then Views sends to the FocusManager. 6. FocusManager::OnKeyEvent() calls -AshFocusManagerFactory::Delegate::ProcessAccelerator(). -7. AshFocusManagerFactory::Delegate::ProcessAccelerator() calls to +PostTargerAcceleratorHandler::ProcessAccelerator(). +7. PostTargerAcceleratorHandler::ProcessAccelerator() calls to Ash's AcceleratorController. Steps 1-3 give Ash the opportunity to have accelerators before the target
diff --git a/ash/accelerators/accelerator_delegate.cc b/ash/accelerators/accelerator_delegate.cc deleted file mode 100644 index fdd2fb5..0000000 --- a/ash/accelerators/accelerator_delegate.cc +++ /dev/null
@@ -1,24 +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 "ash/accelerators/accelerator_delegate.h" - -#include "ash/accelerators/accelerator_router.h" -#include "ui/aura/window.h" -#include "ui/events/event.h" - -namespace ash { - -AcceleratorDelegate::AcceleratorDelegate() : router_(new AcceleratorRouter) {} - -AcceleratorDelegate::~AcceleratorDelegate() = default; - -bool AcceleratorDelegate::ProcessAccelerator( - const ui::KeyEvent& key_event, - const ui::Accelerator& accelerator) { - return router_->ProcessAccelerator( - static_cast<aura::Window*>(key_event.target()), key_event, accelerator); -} - -} // namespace ash
diff --git a/ash/accelerators/accelerator_delegate.h b/ash/accelerators/accelerator_delegate.h deleted file mode 100644 index 61545045..0000000 --- a/ash/accelerators/accelerator_delegate.h +++ /dev/null
@@ -1,36 +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 ASH_ACCELERATORS_ACCELERATOR_DELEGATE_H_ -#define ASH_ACCELERATORS_ACCELERATOR_DELEGATE_H_ - -#include <memory> - -#include "ash/ash_export.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "ui/wm/core/accelerator_delegate.h" - -namespace ash { - -class AcceleratorRouter; - -class ASH_EXPORT AcceleratorDelegate : public ::wm::AcceleratorDelegate { - public: - AcceleratorDelegate(); - ~AcceleratorDelegate() override; - - // wm::AcceleratorDelegate: - bool ProcessAccelerator(const ui::KeyEvent& event, - const ui::Accelerator& accelerator) override; - - private: - std::unique_ptr<AcceleratorRouter> router_; - - DISALLOW_COPY_AND_ASSIGN(AcceleratorDelegate); -}; - -} // namespace ash - -#endif // ASH_ACCELERATORS_ACCELERATOR_DELEGATE_H_
diff --git a/ash/accelerators/accelerator_filter_unittest.cc b/ash/accelerators/accelerator_filter_unittest.cc index 85d17bc..722e02e 100644 --- a/ash/accelerators/accelerator_filter_unittest.cc +++ b/ash/accelerators/accelerator_filter_unittest.cc
@@ -7,7 +7,7 @@ #include <memory> #include "ash/accelerators/accelerator_controller.h" -#include "ash/accelerators/accelerator_delegate.h" +#include "ash/accelerators/pre_target_accelerator_handler.h" #include "ash/app_list/test/app_list_test_helper.h" #include "ash/session/session_controller.h" #include "ash/shell.h" @@ -90,7 +90,7 @@ std::unique_ptr<ui::AcceleratorHistory> accelerator_history( new ui::AcceleratorHistory()); ::wm::AcceleratorFilter filter( - std::unique_ptr<::wm::AcceleratorDelegate>(new AcceleratorDelegate), + std::make_unique<PreTargetAcceleratorHandler>(), accelerator_history.get()); aura::Window* root_window = Shell::GetPrimaryRootWindow();
diff --git a/ash/accelerators/accelerator_router.h b/ash/accelerators/accelerator_router.h deleted file mode 100644 index 9734811c..0000000 --- a/ash/accelerators/accelerator_router.h +++ /dev/null
@@ -1,60 +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 ASH_ACCELERATORS_ACCELERATOR_ROUTER_H_ -#define ASH_ACCELERATORS_ACCELERATOR_ROUTER_H_ - -#include "ash/ash_export.h" -#include "base/macros.h" -#include "base/time/time.h" - -namespace aura { -class Window; -} - -namespace ui { -class Accelerator; -class KeyEvent; -} - -namespace ash { - -// AcceleratorRouter does a minimal amount of processing before routing the -// accelerator to the AcceleratorController. AcceleratorRouter may also decide -// not to process certain accelerators. -class ASH_EXPORT AcceleratorRouter { - public: - AcceleratorRouter(); - ~AcceleratorRouter(); - - // Returns true if event should be consumed. |target| is the target of the - // event. - bool ProcessAccelerator(aura::Window* target, - const ui::KeyEvent& event, - const ui::Accelerator& accelerator); - - private: - // Returns true if the window should be allowed a chance to handle - // system keys. - bool CanConsumeSystemKeys(aura::Window* target, const ui::KeyEvent& event); - - // Returns true if the |accelerator| should be processed now. - bool ShouldProcessAcceleratorNow(aura::Window* target, - const ui::KeyEvent& event, - const ui::Accelerator& accelerator); - - // Records a histogram on how long the "Search" key is held when a user - // presses an accelerator that involes the "Search" key. - void RecordSearchKeyStats(const ui::Accelerator& accelerator); - - enum SearchKeyState { RELEASED = 0, PRESSED, RECORDED }; - SearchKeyState search_key_state_ = RELEASED; - base::TimeTicks search_key_pressed_timestamp_; - - DISALLOW_COPY_AND_ASSIGN(AcceleratorRouter); -}; - -} // namespace ash - -#endif // ASH_ACCELERATORS_ACCELERATOR_ROUTER_H_
diff --git a/ash/accelerators/ash_focus_manager_factory.cc b/ash/accelerators/ash_focus_manager_factory.cc index 9db834f..ff179ec 100644 --- a/ash/accelerators/ash_focus_manager_factory.cc +++ b/ash/accelerators/ash_focus_manager_factory.cc
@@ -13,32 +13,38 @@ #include "ash/shell.h" #include "ui/base/ime/text_input_client.h" #include "ui/views/focus/focus_manager.h" +#include "ui/views/focus/focus_manager_delegate.h" #include "ui/views/view.h" namespace ash { +namespace { -AshFocusManagerFactory::AshFocusManagerFactory() = default; -AshFocusManagerFactory::~AshFocusManagerFactory() = default; +// As the name implies, this class is responsible for handling accelerators +// *after* pre-target accelerators and after the target is given a chance to +// process the accelerator. +class PostTargetAcceleratorHandler : public views::FocusManagerDelegate { + public: + PostTargetAcceleratorHandler() = default; + ~PostTargetAcceleratorHandler() override = default; -std::unique_ptr<views::FocusManager> AshFocusManagerFactory::CreateFocusManager( - views::Widget* widget, - bool desktop_widget) { - return std::make_unique<views::FocusManager>( - widget, desktop_widget ? nullptr : std::make_unique<Delegate>()); -} + // views::FocusManagerDelegate overrides: + bool ProcessAccelerator(const ui::Accelerator& accelerator) override; + void OnDidChangeFocus(views::View* focused_before, + views::View* focused_now) override; -AshFocusManagerFactory::Delegate::Delegate() = default; -AshFocusManagerFactory::Delegate::~Delegate() = default; + private: + DISALLOW_COPY_AND_ASSIGN(PostTargetAcceleratorHandler); +}; -bool AshFocusManagerFactory::Delegate::ProcessAccelerator( +bool PostTargetAcceleratorHandler::ProcessAccelerator( const ui::Accelerator& accelerator) { AcceleratorController* controller = Shell::Get()->accelerator_controller(); return controller && controller->Process(accelerator); } -void AshFocusManagerFactory::Delegate::OnDidChangeFocus( - views::View* focused_before, - views::View* focused_now) { +void PostTargetAcceleratorHandler::OnDidChangeFocus(views::View* focused_before, + views::View* focused_now) { + // TODO: seems as though this code should live closer to magnification code. if (!focused_now || focused_now == focused_before) return; @@ -89,4 +95,18 @@ fullscreen_magnifier->CenterOnPoint(point_of_interest); } +} // namespace + +AshFocusManagerFactory::AshFocusManagerFactory() = default; +AshFocusManagerFactory::~AshFocusManagerFactory() = default; + +std::unique_ptr<views::FocusManager> AshFocusManagerFactory::CreateFocusManager( + views::Widget* widget, + bool desktop_widget) { + return std::make_unique<views::FocusManager>( + widget, desktop_widget + ? nullptr + : std::make_unique<PostTargetAcceleratorHandler>()); +} + } // namespace ash
diff --git a/ash/accelerators/ash_focus_manager_factory.h b/ash/accelerators/ash_focus_manager_factory.h index 4788f89..f3d34727 100644 --- a/ash/accelerators/ash_focus_manager_factory.h +++ b/ash/accelerators/ash_focus_manager_factory.h
@@ -6,7 +6,6 @@ #define ASH_ACCELERATORS_ASH_FOCUS_MANAGER_FACTORY_H_ #include "base/macros.h" -#include "ui/views/focus/focus_manager_delegate.h" #include "ui/views/focus/focus_manager_factory.h" namespace ash { @@ -25,17 +24,6 @@ bool desktop_widget) override; private: - class Delegate : public views::FocusManagerDelegate { - public: - Delegate(); - ~Delegate() override; - - // views::FocusManagerDelegate overrides: - bool ProcessAccelerator(const ui::Accelerator& accelerator) override; - void OnDidChangeFocus(views::View* focused_before, - views::View* focused_now) override; - }; - DISALLOW_COPY_AND_ASSIGN(AshFocusManagerFactory); };
diff --git a/ash/accelerators/accelerator_router.cc b/ash/accelerators/pre_target_accelerator_handler.cc similarity index 86% rename from ash/accelerators/accelerator_router.cc rename to ash/accelerators/pre_target_accelerator_handler.cc index 65500631..5551f15 100644 --- a/ash/accelerators/accelerator_router.cc +++ b/ash/accelerators/pre_target_accelerator_handler.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 "ash/accelerators/accelerator_router.h" +#include "ash/accelerators/pre_target_accelerator_handler.h" #include "ash/accelerators/accelerator_controller.h" #include "ash/app_list/app_list_controller_impl.h" @@ -41,13 +41,14 @@ } // namespace -AcceleratorRouter::AcceleratorRouter() = default; +PreTargetAcceleratorHandler::PreTargetAcceleratorHandler() = default; -AcceleratorRouter::~AcceleratorRouter() = default; +PreTargetAcceleratorHandler::~PreTargetAcceleratorHandler() = default; -bool AcceleratorRouter::ProcessAccelerator(aura::Window* target, - const ui::KeyEvent& key_event, - const ui::Accelerator& accelerator) { +bool PreTargetAcceleratorHandler::ProcessAccelerator( + const ui::KeyEvent& key_event, + const ui::Accelerator& accelerator) { + aura::Window* target = static_cast<aura::Window*>(key_event.target()); // Callers should never supply null. DCHECK(target); RecordSearchKeyStats(accelerator); @@ -67,7 +68,7 @@ return Shell::Get()->accelerator_controller()->Process(accelerator); } -void AcceleratorRouter::RecordSearchKeyStats( +void PreTargetAcceleratorHandler::RecordSearchKeyStats( const ui::Accelerator& accelerator) { if (accelerator.IsCmdDown()) { if (search_key_state_ == RELEASED) { @@ -87,15 +88,16 @@ } } -bool AcceleratorRouter::CanConsumeSystemKeys(aura::Window* target, - const ui::KeyEvent& event) { +bool PreTargetAcceleratorHandler::CanConsumeSystemKeys( + aura::Window* target, + const ui::KeyEvent& event) { // Uses the top level window so if the target is a web contents window the // containing parent window will be checked for the property. aura::Window* top_level = ::wm::GetToplevelWindow(target); return top_level && wm::GetWindowState(top_level)->CanConsumeSystemKeys(); } -bool AcceleratorRouter::ShouldProcessAcceleratorNow( +bool PreTargetAcceleratorHandler::ShouldProcessAcceleratorNow( aura::Window* target, const ui::KeyEvent& event, const ui::Accelerator& accelerator) { @@ -112,7 +114,7 @@ AcceleratorController* accelerator_controller = Shell::Get()->accelerator_controller(); - // Reserved accelerators (such as Power button) always have a prority. + // Reserved accelerators (such as Power button) always have a priority. if (accelerator_controller->IsReserved(accelerator)) return true;
diff --git a/ash/accelerators/pre_target_accelerator_handler.h b/ash/accelerators/pre_target_accelerator_handler.h new file mode 100644 index 0000000..8640067 --- /dev/null +++ b/ash/accelerators/pre_target_accelerator_handler.h
@@ -0,0 +1,62 @@ +// 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 ASH_ACCELERATORS_PRE_TARGET_ACCELERATOR_HANDLER_H_ +#define ASH_ACCELERATORS_PRE_TARGET_ACCELERATOR_HANDLER_H_ + +#include "ash/ash_export.h" +#include "base/macros.h" +#include "base/time/time.h" +#include "ui/wm/core/accelerator_delegate.h" + +namespace aura { +class Window; +} + +namespace ui { +class Accelerator; +class KeyEvent; +} // namespace ui + +namespace ash { + +// PreTargetAcceleratorHandler is responsible for handling accelerators that +// are processed before the target is given a chance to process the +// accelerator. This typically includes system or reserved accelerators. +// PreTargetAcceleratorHandler does not actually handle the accelerators, rather +// it calls to AcceleratorController to actually process the accelerator. +class ASH_EXPORT PreTargetAcceleratorHandler + : public ::wm::AcceleratorDelegate { + public: + PreTargetAcceleratorHandler(); + ~PreTargetAcceleratorHandler() override; + + // wm::AcceleratorDelegate: + bool ProcessAccelerator(const ui::KeyEvent& event, + const ui::Accelerator& accelerator) override; + + private: + // Returns true if the window should be allowed a chance to handle + // system keys. + bool CanConsumeSystemKeys(aura::Window* target, const ui::KeyEvent& event); + + // Returns true if the |accelerator| should be processed now. + bool ShouldProcessAcceleratorNow(aura::Window* target, + const ui::KeyEvent& event, + const ui::Accelerator& accelerator); + + // Records a histogram on how long the "Search" key is held when a user + // presses an accelerator that involes the "Search" key. + void RecordSearchKeyStats(const ui::Accelerator& accelerator); + + enum SearchKeyState { RELEASED = 0, PRESSED, RECORDED }; + SearchKeyState search_key_state_ = RELEASED; + base::TimeTicks search_key_pressed_timestamp_; + + DISALLOW_COPY_AND_ASSIGN(PreTargetAcceleratorHandler); +}; + +} // namespace ash + +#endif // ASH_ACCELERATORS_PRE_TARGET_ACCELERATOR_HANDLER_H_
diff --git a/ash/shell.cc b/ash/shell.cc index 83ff62b..dd5c0886 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -10,9 +10,9 @@ #include <utility> #include "ash/accelerators/accelerator_controller.h" -#include "ash/accelerators/accelerator_delegate.h" #include "ash/accelerators/ash_focus_manager_factory.h" #include "ash/accelerators/magnifier_key_scroller.h" +#include "ash/accelerators/pre_target_accelerator_handler.h" #include "ash/accelerators/spoken_feedback_toggler.h" #include "ash/accessibility/accessibility_controller.h" #include "ash/accessibility/accessibility_delegate.h" @@ -1142,7 +1142,7 @@ AddPreTargetHandler(overlay_filter_.get()); accelerator_filter_.reset(new ::wm::AcceleratorFilter( - std::unique_ptr<::wm::AcceleratorDelegate>(new AcceleratorDelegate), + std::make_unique<PreTargetAcceleratorHandler>(), accelerator_controller_->accelerator_history())); AddPreTargetHandler(accelerator_filter_.get());
diff --git a/base/BUILD.gn b/base/BUILD.gn index 7bc8a57..0a48a16d 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -730,8 +730,8 @@ #"sys_info_openbsd.cc", # Unused in Chromium build. "syslog_logging.cc", "syslog_logging.h", - "system_monitor/system_monitor.cc", - "system_monitor/system_monitor.h", + "system/system_monitor.cc", + "system/system_monitor.h", "task/cancelable_task_tracker.cc", "task/cancelable_task_tracker.h", "task/lazy_task_runner.cc", @@ -2434,7 +2434,7 @@ "synchronization/waitable_event_watcher_unittest.cc", "sys_byteorder_unittest.cc", "sys_info_unittest.cc", - "system_monitor/system_monitor_unittest.cc", + "system/system_monitor_unittest.cc", "task/cancelable_task_tracker_unittest.cc", "task/lazy_task_runner_unittest.cc", "task/post_task_unittest.cc",
diff --git a/base/system_monitor/system_monitor.cc b/base/system/system_monitor.cc similarity index 93% rename from base/system_monitor/system_monitor.cc rename to base/system/system_monitor.cc index 71e4f07..35367200 100644 --- a/base/system_monitor/system_monitor.cc +++ b/base/system/system_monitor.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 "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include <utility> @@ -14,7 +14,7 @@ static SystemMonitor* g_system_monitor = nullptr; SystemMonitor::SystemMonitor() - : devices_changed_observer_list_( + : devices_changed_observer_list_( new ObserverListThreadSafe<DevicesChangedObserver>()) { DCHECK(!g_system_monitor); g_system_monitor = this;
diff --git a/base/system_monitor/system_monitor.h b/base/system/system_monitor.h similarity index 91% rename from base/system_monitor/system_monitor.h rename to base/system/system_monitor.h index 7f21e47..1e7ea4e 100644 --- a/base/system_monitor/system_monitor.h +++ b/base/system/system_monitor.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BASE_SYSTEM_MONITOR_SYSTEM_MONITOR_H_ -#define BASE_SYSTEM_MONITOR_SYSTEM_MONITOR_H_ +#ifndef BASE_SYSTEM_SYSTEM_MONITOR_H_ +#define BASE_SYSTEM_SYSTEM_MONITOR_H_ #include "base/base_export.h" #include "base/macros.h" @@ -64,7 +64,7 @@ // Functions to trigger notifications. void NotifyDevicesChanged(DeviceType device_type); - scoped_refptr<ObserverListThreadSafe<DevicesChangedObserver> > + scoped_refptr<ObserverListThreadSafe<DevicesChangedObserver>> devices_changed_observer_list_; DISALLOW_COPY_AND_ASSIGN(SystemMonitor); @@ -72,4 +72,4 @@ } // namespace base -#endif // BASE_SYSTEM_MONITOR_SYSTEM_MONITOR_H_ +#endif // BASE_SYSTEM_SYSTEM_MONITOR_H_
diff --git a/base/system_monitor/system_monitor_unittest.cc b/base/system/system_monitor_unittest.cc similarity index 91% rename from base/system_monitor/system_monitor_unittest.cc rename to base/system/system_monitor_unittest.cc index 8963f7b..f4ef68f 100644 --- a/base/system_monitor/system_monitor_unittest.cc +++ b/base/system/system_monitor_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 "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/macros.h" #include "base/message_loop/message_loop.h" @@ -17,9 +17,7 @@ class SystemMonitorTest : public testing::Test { protected: - SystemMonitorTest() { - system_monitor_.reset(new SystemMonitor); - } + SystemMonitorTest() { system_monitor_.reset(new SystemMonitor); } MessageLoop message_loop_; std::unique_ptr<SystemMonitor> system_monitor_;
diff --git a/base/test/mock_devices_changed_observer.h b/base/test/mock_devices_changed_observer.h index 0734fb4f..42b8c3f 100644 --- a/base/test/mock_devices_changed_observer.h +++ b/base/test/mock_devices_changed_observer.h
@@ -8,7 +8,7 @@ #include <string> #include "base/macros.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "testing/gmock/include/gmock/gmock.h" namespace base {
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h index 38528aa..271022e 100644 --- a/base/trace_event/trace_event.h +++ b/base/trace_event/trace_event.h
@@ -1099,38 +1099,30 @@ // Used by TRACE_EVENTx macros. Do not use directly. class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer { public: - // Note: members of data_ intentionally left uninitialized. See Initialize. - ScopedTracer() : p_data_(NULL) {} + ScopedTracer() = default; ~ScopedTracer() { - if (p_data_ && *data_.category_group_enabled) { - TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( - data_.category_group_enabled, data_.name, data_.event_handle); + if (category_group_enabled_ && *category_group_enabled_) { + TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, + name_, event_handle_); } } void Initialize(const unsigned char* category_group_enabled, const char* name, base::trace_event::TraceEventHandle event_handle) { - data_.category_group_enabled = category_group_enabled; - data_.name = name; - data_.event_handle = event_handle; - p_data_ = &data_; + category_group_enabled_ = category_group_enabled; + name_ = name; + event_handle_ = event_handle; } private: - // This Data struct workaround is to avoid initializing all the members - // in Data during construction of this object, since this object is always - // constructed, even when tracing is disabled. If the members of Data were - // members of this class instead, compiler warnings occur about potential - // uninitialized accesses. - struct Data { - const unsigned char* category_group_enabled; - const char* name; - base::trace_event::TraceEventHandle event_handle; - }; - Data* p_data_; - Data data_; + // NOTE: Only initialize the first member to reduce generated code size, + // since there is no point in initializing the other members if Initialize() + // is never called. + const unsigned char* category_group_enabled_ = nullptr; + const char* name_; + base::trace_event::TraceEventHandle event_handle_; }; // Used by TRACE_EVENT_BINARY_EFFICIENTx macro. Do not use directly.
diff --git a/build/chromeos/run_vm_test.py b/build/chromeos/run_vm_test.py index bc374b49..347dec1 100755 --- a/build/chromeos/run_vm_test.py +++ b/build/chromeos/run_vm_test.py
@@ -317,9 +317,9 @@ def __init__(self, args, unknown_args): super(BrowserSanityTest, self).__init__(args, unknown_args) - # 5 min should be enough time for the sanity test to pass. - self._retries = 2 - self._timeout = 300 + # 10 min should be enough time for the sanity test to pass. + self._retries = 1 + self._timeout = 600 @property def suite_name(self):
diff --git a/chrome/android/java/res/layout/autofill_assistant_sheet.xml b/chrome/android/java/res/layout/autofill_assistant_sheet.xml index c3f6afe..56d8f1e8 100644 --- a/chrome/android/java/res/layout/autofill_assistant_sheet.xml +++ b/chrome/android/java/res/layout/autofill_assistant_sheet.xml
@@ -83,10 +83,44 @@ android:contentDescription="@string/close" /> </LinearLayout> - <ViewStub + <RelativeLayout android:id="@+id/details" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> + android:layout_width="match_parent" + android:layout_height="60dp" + android:layout_marginBottom="8dp" + android:visibility="gone"> + <TextView + android:id="@+id/details_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_alignParentStart="true" + android:layout_toStartOf="@+id/details_image"/> + <TextView + android:id="@+id/details_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@+id/details_title" + android:layout_above="@+id/details_time" + android:layout_alignParentStart="true" + android:layout_toStartOf="@+id/details_image" + android:gravity="center_vertical" /> + <TextView + android:id="@+id/details_time" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_alignParentStart="true" + android:layout_toStartOf="@+id/details_image"/> + <android.support.v7.widget.AppCompatImageView + android:id="@+id/details_image" + android:layout_width="@dimen/autofill_assistant_details_image_size" + android:layout_height="@dimen/autofill_assistant_details_image_size" + android:layout_alignParentEnd="true" + android:layout_marginStart="24dp" + android:scaleType="centerCrop"> + </android.support.v7.widget.AppCompatImageView> + </RelativeLayout> <HorizontalScrollView android:layout_width="match_parent"
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 1aaaca9..997b5a8 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -555,4 +555,7 @@ <!-- Explicit Language Ask Prompt dimensions --> <dimen name="explicit_ask_checkbox_end_padding">4dp</dimen> + + <!-- Autofill Assistant dimensions --> + <dimen name="autofill_assistant_details_image_size">60dp</dimen> </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java index cb051ae..5682b0a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -19,6 +19,7 @@ import org.chromium.content_public.browser.WebContents; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -182,6 +183,22 @@ true /* includeServerCards */)); } + @CalledByNative + private void onHideDetails() { + mUiDelegate.hideDetails(); + } + + @CalledByNative + private void onShowDetails(String title, String url, long msSinceEpoch, String description) { + Date date = null; + if (msSinceEpoch > 0) { + date = new Date(msSinceEpoch); + } + + mUiDelegate.showDetails( + new AutofillAssistantUiDelegate.Details(title, url, date, description)); + } + // native methods. private native long nativeInit( WebContents webContents, String[] parameterNames, String[] parameterValues);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java index 1927b62..8e7e2bb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java
@@ -5,22 +5,43 @@ package org.chromium.chrome.browser.autofill_assistant; import android.app.Activity; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.Drawable; +import android.media.ThumbnailUtils; +import android.os.AsyncTask; +import android.support.annotation.Nullable; +import android.support.v4.graphics.drawable.RoundedBitmapDrawable; +import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; +import android.support.v7.widget.AppCompatImageView; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; +import org.chromium.base.Promise; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard; +import java.io.InputStream; +import java.net.URL; +import java.text.SimpleDateFormat; import java.util.ArrayList; - -import javax.annotation.Nullable; +import java.util.Date; +import java.util.List; +import java.util.Locale; /** Delegate to interact with the assistant UI. */ class AutofillAssistantUiDelegate { + // TODO(crbug.com/806868): Use correct user locale. + private static final SimpleDateFormat sDetailsTimeFormat = + new SimpleDateFormat("H:mma", Locale.getDefault()); + private static final SimpleDateFormat sDetailsDateFormat = + new SimpleDateFormat("EEE, MMM d", Locale.getDefault()); + private final Activity mActivity; private final Client mClient; private final View mFullContainer; @@ -29,6 +50,14 @@ private final ViewGroup mChipsViewContainer; private final TextView mStatusMessageView; + private final ViewGroup mDetails; + private final AppCompatImageView mDetailsImage; + private final TextView mDetailsTitle; + private final TextView mDetailsText; + private final TextView mDetailsTime; + private final int mDetailsImageWidth; + private final int mDetailsImageHeight; + /** * This is a client interface that relays interactions from the UI. * @@ -94,6 +123,41 @@ } /** + * Java side equivalent of autofill_assistant::DetailsProto. + */ + protected static class Details { + private final String mTitle; + private final String mUrl; + @Nullable + private final Date mDate; + private final String mDescription; + + public Details(String title, String url, @Nullable Date date, String description) { + this.mTitle = title; + this.mUrl = url; + this.mDate = date; + this.mDescription = description; + } + + public String getTitle() { + return mTitle; + } + + public String getUrl() { + return mUrl; + } + + @Nullable + public Date getDate() { + return mDate; + } + + public String getDescription() { + return mDescription; + } + } + + /** * Constructs an assistant UI delegate. * * @param activity The Activity @@ -109,29 +173,27 @@ .findViewById(R.id.autofill_assistant); // TODO(crbug.com/806868): Set hint text on overlay. mOverlay = mFullContainer.findViewById(R.id.overlay); - mOverlay.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mClient.onClickOverlay(); - } - }); + mOverlay.setOnClickListener(unusedView -> mClient.onClickOverlay()); mBottomBar = mFullContainer.findViewById(R.id.bottombar); - mBottomBar.findViewById(R.id.close_button).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - shutdown(); - } - }); + mBottomBar.findViewById(R.id.close_button).setOnClickListener(unusedView -> shutdown()); mBottomBar.findViewById(R.id.feedback_button) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - // TODO(crbug.com/806868): Send feedback. - } - }); + .setOnClickListener(unusedView + -> { + // TODO(crbug.com/806868): Send feedback. + }); mChipsViewContainer = mBottomBar.findViewById(R.id.carousel); mStatusMessageView = mBottomBar.findViewById(R.id.status_message); + mDetails = (ViewGroup) mBottomBar.findViewById(R.id.details); + mDetailsImage = (AppCompatImageView) mDetails.findViewById(R.id.details_image); + mDetailsTitle = (TextView) mDetails.findViewById(R.id.details_title); + mDetailsText = (TextView) mDetails.findViewById(R.id.details_text); + mDetailsTime = (TextView) mDetails.findViewById(R.id.details_time); + mDetailsImageWidth = mActivity.getResources().getDimensionPixelSize( + R.dimen.autofill_assistant_details_image_size); + mDetailsImageHeight = mActivity.getResources().getDimensionPixelSize( + R.dimen.autofill_assistant_details_image_size); + // TODO(crbug.com/806868): Listen for contextual search shown so as to hide this UI. } @@ -165,8 +227,10 @@ for (int i = 0; i < scriptHandles.size(); i++) { ScriptHandle scriptHandle = scriptHandles.get(i); TextView chipView = createChipView(scriptHandle.getName()); - chipView.setOnClickListener( - (unusedView) -> mClient.onScriptSelected(scriptHandle.getPath())); + chipView.setOnClickListener((unusedView) -> { + mChipsViewContainer.removeAllViews(); + mClient.onScriptSelected(scriptHandle.getPath()); + }); mChipsViewContainer.addView(chipView); } @@ -190,6 +254,60 @@ mOverlay.setVisibility(View.GONE); } + public void hideDetails() { + mDetails.setVisibility(View.GONE); + } + + /** Called to show contextual information. */ + public void showDetails(Details details) { + mDetailsTitle.setText(details.getTitle()); + mDetailsText.setText(getDetailsText(details)); + mDetailsTime.setText(getDetailsTime(details.getDate())); + + mDetailsImage.setVisibility(View.GONE); + mDetails.setVisibility(View.VISIBLE); + ensureFullContainerIsShown(); + + String url = details.getUrl(); + if (!url.isEmpty()) { + // The URL is safe given because it comes from the knowledge graph and is hosted on + // Google servers. + downloadImage(url).then(image -> { + mDetailsImage.setImageDrawable(getRoundedImage(image)); + mDetailsImage.setVisibility(View.VISIBLE); + }, ignoredError -> {}); + } + } + + private String getDetailsText(Details details) { + List<String> parts = new ArrayList<>(); + Date date = details.getDate(); + if (date != null) { + parts.add(sDetailsDateFormat.format(date)); + } + + String description = details.getDescription(); + if (description != null && !description.isEmpty()) { + parts.add(description); + } + + // TODO(crbug.com/806868): Use a view instead of this dot text. + return TextUtils.join(" • ", parts); + } + + private String getDetailsTime(@Nullable Date date) { + return date != null ? sDetailsTimeFormat.format(date).toLowerCase(Locale.getDefault()) : ""; + } + + private Drawable getRoundedImage(Bitmap bitmap) { + RoundedBitmapDrawable roundedBitmap = RoundedBitmapDrawableFactory.create( + mActivity.getResources(), + ThumbnailUtils.extractThumbnail(bitmap, mDetailsImageWidth, mDetailsImageHeight)); + // TODO(crbug.com/806868): Get radius from resources dimensions. + roundedBitmap.setCornerRadius(10); + return roundedBitmap; + } + /** * Shuts down the Autofill Assistant. The UI disappears and any associated state goes away. */ @@ -204,16 +322,21 @@ * @param profiles List of profiles to show. */ public void showProfiles(ArrayList<AutofillProfile> profiles) { - mChipsViewContainer.removeAllViews(); + if (profiles.isEmpty()) { + mClient.onAddressSelected(""); + return; + } - if (profiles.isEmpty()) return; + mChipsViewContainer.removeAllViews(); for (int i = 0; i < profiles.size(); i++) { AutofillProfile profile = profiles.get(i); // TODO(crbug.com/806868): Show more information than the street. TextView chipView = createChipView(profile.getStreetAddress()); - chipView.setOnClickListener( - (unusedView) -> mClient.onAddressSelected(profile.getGUID())); + chipView.setOnClickListener((unusedView) -> { + mChipsViewContainer.removeAllViews(); + mClient.onAddressSelected(profile.getGUID()); + }); mChipsViewContainer.addView(chipView); } @@ -226,18 +349,59 @@ * @param cards List of cards to show. */ public void showCards(ArrayList<CreditCard> cards) { - mChipsViewContainer.removeAllViews(); + if (cards.isEmpty()) { + mClient.onCardSelected(""); + return; + } - if (cards.isEmpty()) return; + mChipsViewContainer.removeAllViews(); for (int i = 0; i < cards.size(); i++) { CreditCard card = cards.get(i); // TODO(crbug.com/806868): Show more information than the card number. TextView chipView = createChipView(card.getObfuscatedNumber()); - chipView.setOnClickListener((unusedView) -> mClient.onCardSelected(card.getGUID())); + chipView.setOnClickListener((unusedView) -> { + mChipsViewContainer.removeAllViews(); + mClient.onCardSelected(card.getGUID()); + }); mChipsViewContainer.addView(chipView); } ensureFullContainerIsShown(); } + + private Promise<Bitmap> downloadImage(String url) { + Promise<Bitmap> promise = new Promise<>(); + new DownloadImageTask(promise).execute(url); + return promise; + } + + private static class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { + private final Promise<Bitmap> mPromise; + private Exception mError = null; + + private DownloadImageTask(Promise<Bitmap> promise) { + this.mPromise = promise; + } + + @Override + protected Bitmap doInBackground(String... urls) { + try (InputStream in = new URL(urls[0]).openStream()) { + return BitmapFactory.decodeStream(in); + } catch (Exception e) { + mError = e; + return null; + } + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (mError != null) { + mPromise.reject(mError); + return; + } + + mPromise.fulfill(bitmap); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java index 53b3637..2e84b3cb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java
@@ -247,8 +247,6 @@ // If all items have been selected, only show the Undo button if there's a meaningful // state to revert to (one might not exist if they were all selected manually). - // TODO(finnur): Add automatic test that exercises the visibility of the action button, - // including when all items are selected manually (special case). mActionButton.setVisibility(!mToolbar.isSearching() && mMultiSelectionAllowed && (selectedItems.size() != mPickerAdapter.getItemCount() || mPreviousSelection != null) @@ -280,11 +278,15 @@ new HashSet<ContactDetails>(mPickerAdapter.getAllContacts())); mActionButton.setImageResource(R.drawable.ic_undo); mActionButton.setContentDescription(mLabelUndo); + mListener.onContactsPickerUserAction( + ContactsPickerListener.ContactsPickerAction.SELECT_ALL, null); } else { mSelectionDelegate.setSelectedItems(mPreviousSelection); mActionButton.setImageResource(R.drawable.ic_select_all); mActionButton.setContentDescription(mLabelSelectAll); mPreviousSelection = null; + mListener.onContactsPickerUserAction( + ContactsPickerListener.ContactsPickerAction.UNDO_SELECT_ALL, null); } mSelectAllMode = !mSelectAllMode; } else {
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 40cdfea..069df25c 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2229,7 +2229,7 @@ Open Online </message> <message name="IDS_PAGE_INFO_PREVIEW_MESSAGE" desc="This text is displayed in the page info bubble when the currently viewed page has been modified by Google to be a lighter and faster version of the original page. The word 'Lite' should match the translation in TC ID 1019734090540434451"> - Lite page delivered by Google. + Lite page delivered by Google </message> <message name="IDS_PAGE_INFO_PREVIEW_LOAD_ORIGINAL" desc="This text, when clicked, loads the original page from its origin without any treatments. This text is shown in the page info bubble when the currently viewed page has been modified to be a lighter and faster version of the original page."> <ph name="BEGIN_LINK"><link></ph>Load original page<ph name="END_LINK"></link></ph> from <ph name="DOMAIN_NAME">%1$s<ex>google.com</ex></ph>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java index f6d15be..879f8211 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java
@@ -141,7 +141,8 @@ return dialog; } - private void clickView(final int position, final int expectedSelectionCount) throws Exception { + private void clickView(final int position, final int expectedSelectionCount, + final boolean expectSelection) throws Exception { RecyclerView recyclerView = getRecyclerView(); RecyclerViewTestUtils.scrollToView(recyclerView, position); @@ -152,7 +153,8 @@ // Validate the correct selection took place. Assert.assertEquals(expectedSelectionCount, mCurrentContactSelection.size()); - Assert.assertTrue(mSelectionDelegate.isItemSelected(mTestContacts.get(position))); + Assert.assertEquals( + expectSelection, mSelectionDelegate.isItemSelected(mTestContacts.get(position))); } private void clickDone() throws Exception { @@ -164,8 +166,7 @@ int callCount = onActionCallback.getCallCount(); TestTouchUtils.performClickOnMainSync(InstrumentationRegistry.getInstrumentation(), done); onActionCallback.waitForCallback(callCount, 1); - Assert.assertEquals( - ContactsPickerListener.ContactsPickerAction.CONTACTS_SELECTED, mLastActionRecorded); + Assert.assertEquals(ContactsPickerAction.CONTACTS_SELECTED, mLastActionRecorded); } public void clickCancel() throws Exception { @@ -176,8 +177,21 @@ int callCount = onActionCallback.getCallCount(); categoryView.onClick(cancel); onActionCallback.waitForCallback(callCount, 1); - Assert.assertEquals( - ContactsPickerListener.ContactsPickerAction.CANCEL, mLastActionRecorded); + Assert.assertEquals(ContactsPickerAction.CANCEL, mLastActionRecorded); + } + + private void clickActionButton(final int expectedSelectionCount, + final ContactsPickerAction expectedAction) throws Exception { + mLastActionRecorded = null; + + ContactsPickerToolbar toolbar = + (ContactsPickerToolbar) mDialog.findViewById(R.id.action_bar); + View action = toolbar.findViewById(R.id.action); + int callCount = onActionCallback.getCallCount(); + TestTouchUtils.performClickOnMainSync(InstrumentationRegistry.getInstrumentation(), action); + onActionCallback.waitForCallback(callCount, 1); + Assert.assertEquals(expectedSelectionCount, mSelectionDelegate.getSelectedItems().size()); + Assert.assertEquals(expectedAction, mLastActionRecorded); } private void dismissDialog() { @@ -209,12 +223,11 @@ Assert.assertTrue(mDialog.isShowing()); int expectedSelectionCount = 1; - clickView(0, expectedSelectionCount); + clickView(0, expectedSelectionCount, /* expectSelection = */ true); clickCancel(); Assert.assertNull(mLastSelectedContacts); - Assert.assertEquals( - ContactsPickerListener.ContactsPickerAction.CANCEL, mLastActionRecorded); + Assert.assertEquals(ContactsPickerAction.CANCEL, mLastActionRecorded); dismissDialog(); } @@ -225,10 +238,10 @@ createDialog(/* multiselect = */ false, Arrays.asList("image/*")); Assert.assertTrue(mDialog.isShowing()); - // Expected selection count is 1 because clicking on a new view unselects other. + // Expected selection count is 1 because clicking on a new view deselects other. int expectedSelectionCount = 1; - clickView(0, expectedSelectionCount); - clickView(1, expectedSelectionCount); + clickView(0, expectedSelectionCount, /* expectSelection = */ true); + clickView(1, expectedSelectionCount, /* expectSelection = */ true); clickDone(); StringWriter out = new StringWriter(); @@ -237,8 +250,7 @@ addContact(writer, mTestContacts.get(1).getDisplayName()); writer.endArray(); - Assert.assertEquals( - ContactsPickerListener.ContactsPickerAction.CONTACTS_SELECTED, mLastActionRecorded); + Assert.assertEquals(ContactsPickerAction.CONTACTS_SELECTED, mLastActionRecorded); Assert.assertEquals(out.toString(), mLastSelectedContacts); dismissDialog(); @@ -251,14 +263,13 @@ Assert.assertTrue(mDialog.isShowing()); // Multi-selection is enabled, so each click is counted. - int expectedSelectionCount = 1; - clickView(0, expectedSelectionCount++); - clickView(2, expectedSelectionCount++); - clickView(4, expectedSelectionCount++); + int expectedSelectionCount = 0; + clickView(0, ++expectedSelectionCount, /* expectSelection = */ true); + clickView(2, ++expectedSelectionCount, /* expectSelection = */ true); + clickView(4, ++expectedSelectionCount, /* expectSelection = */ true); clickDone(); - Assert.assertEquals( - ContactsPickerListener.ContactsPickerAction.CONTACTS_SELECTED, mLastActionRecorded); + Assert.assertEquals(ContactsPickerAction.CONTACTS_SELECTED, mLastActionRecorded); StringWriter out = new StringWriter(); final JsonWriter writer = new JsonWriter(out); @@ -271,4 +282,43 @@ dismissDialog(); } + + @Test + @LargeTest + public void testSelectAll() throws Throwable { + createDialog(/* multiselect = */ true, Arrays.asList("image/*")); + Assert.assertTrue(mDialog.isShowing()); + + ContactsPickerToolbar toolbar = + (ContactsPickerToolbar) mDialog.findViewById(R.id.action_bar); + View action = toolbar.findViewById(R.id.action); + Assert.assertEquals(View.VISIBLE, action.getVisibility()); + + clickActionButton(6, ContactsPickerAction.SELECT_ALL); + clickActionButton(0, ContactsPickerAction.UNDO_SELECT_ALL); + + // Manually select one item. + int expectedSelectionCount = 0; + clickView(0, ++expectedSelectionCount, /* expectSelection = */ true); + + clickActionButton(6, ContactsPickerAction.SELECT_ALL); + clickActionButton(1, ContactsPickerAction.UNDO_SELECT_ALL); + + // Select the rest of the items manually. + clickView(1, ++expectedSelectionCount, /* expectSelection = */ true); + clickView(2, ++expectedSelectionCount, /* expectSelection = */ true); + clickView(3, ++expectedSelectionCount, /* expectSelection = */ true); + clickView(4, ++expectedSelectionCount, /* expectSelection = */ true); + clickView(5, ++expectedSelectionCount, /* expectSelection = */ true); + + // Select all should no longer be visible (nothing left to select). + Assert.assertEquals(View.GONE, action.getVisibility()); + + // Deselect one item. The Select All button should re-appear. + clickView(5, --expectedSelectionCount, /* expectSelection = */ false); + Assert.assertEquals(View.VISIBLE, action.getVisibility()); + + clickActionButton(6, ContactsPickerAction.SELECT_ALL); + clickActionButton(5, ContactsPickerAction.UNDO_SELECT_ALL); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java index c52d311..2fe427b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java
@@ -28,6 +28,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; @@ -196,6 +197,7 @@ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/888996") @Feature({"FeedNewTabPage"}) public void testFeedDisabledByPolicy() throws Exception { final boolean pref = ThreadUtils.runOnUiThreadBlocking(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserControllerInputTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserControllerInputTest.java index e033b232..fdc5612a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserControllerInputTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserControllerInputTest.java
@@ -390,4 +390,26 @@ > navigationTimestamp; }); } + + /** + * Tests that pressing the app button on the Daydream controller exits omnibox text input mode. + */ + @Test + @MediumTest + public void testAppButtonExitsOmniboxTextInput() throws InterruptedException { + // We should always have the keyboard installed and up to date during automated testing, so + // this isn't strictly required. However, it may prevent weird issues when running locally + // if you don't have the keyboard installed for some reason. + NativeUiUtils.enableMockedKeyboard(); + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + // This acts as an assert that we're actually in omnibox text input mode. If the omnibox + // is not actually visible, we'll hit a DCHECK in the native code. + NativeUiUtils.clickElementAndWaitForUiQuiescence( + UserFriendlyElementName.OMNIBOX_TEXT_FIELD, new PointF()); + NativeUiUtils.revertToRealInput(); + // Wait for the URL bar to re-appear, which we take as a signal that we've exited omnibox + // text input mode. + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.URL, () -> { mController.pressReleaseAppButton(); }); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java index ba1f900..7e715e62 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java
@@ -9,6 +9,7 @@ import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_TIMEOUT_LONG_MS; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM_OR_STANDALONE; +import android.graphics.PointF; import android.os.SystemClock; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; @@ -25,9 +26,11 @@ import org.chromium.chrome.browser.payments.ui.PaymentRequestUI; import org.chromium.chrome.browser.payments.ui.PaymentRequestUI.PaymentRequestObserverForTest; import org.chromium.chrome.browser.vr.rules.ChromeTabbedActivityVrTestRule; +import org.chromium.chrome.browser.vr.util.NativeUiUtils; import org.chromium.chrome.browser.vr.util.VrBrowserTransitionUtils; import org.chromium.chrome.browser.vr.util.VrShellDelegateUtils; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.net.test.EmbeddedTestServer; import java.util.concurrent.TimeoutException; @@ -123,4 +126,164 @@ mVrBrowserTestFramework.endTest(); server.stopAndDestroyServer(); } + + /** + * Tests that the current URL is automatically populated when opening up the omnibox text + * entry mode. + */ + @Test + @MediumTest + public void testOmniboxContainsCurrentUrl() throws InterruptedException { + // This is a really roundabout way of checking the automatically populated text in the + // omnibox without having to add yet more native plumbing to read the current text. + // The idea is that by deleting the last four characters, we should be left with just + // "chrome://", so we can then input another chrome:// URL based off that. The only way + // the second navigation will complete successfully is if the omnibox had "chrome://gpu/" + // when we opened it. + NativeUiUtils.enableMockedKeyboard(); + mVrTestRule.loadUrl("chrome://gpu/"); + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + // Click near the righthand side of the text input field so the cursor is at the end instead + // of selecting the existing text. + NativeUiUtils.clickElementAndWaitForUiQuiescence( + UserFriendlyElementName.OMNIBOX_TEXT_FIELD, new PointF(0.4f, 0.0f)); + // Delete "gpu/". + for (int i = 0; i < 4; ++i) { + NativeUiUtils.inputBackspace(); + } + // Wait for suggestions to change so that our navigation succeeds. + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.SUGGESTION_BOX, + () -> { NativeUiUtils.inputString("version/"); }); + NativeUiUtils.inputEnter(); + ChromeTabUtils.waitForTabPageLoaded( + mVrTestRule.getActivity().getActivityTab(), "chrome://version/"); + } + + /** + * Tests that the the omnibox automatically scrolls the text when it is longer than the box + * can fit. + */ + @Test + @MediumTest + public void testOmniboxTextScrolls() throws InterruptedException { + // This is a roundabout way of checking that the text scrolls. By inputting a long string, + // clicking near the beginning and deleting a character, we can check that the text scrolled + // by checking whether a character at the beginning of the string was deleted or not - if + // the text scrolled, then a character later in the string should have been deleted. + NativeUiUtils.enableMockedKeyboard(); + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + String expectedString = "chrome://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + NativeUiUtils.inputString(expectedString + "a"); + // Click near the lefthand side of the input field to place the cursor near the beginning + // of the visible part of the string. + NativeUiUtils.clickElementAndWaitForUiQuiescence( + UserFriendlyElementName.OMNIBOX_TEXT_FIELD, new PointF(-0.45f, 0.0f)); + // We expect this to delete an "a" instead of anything in "chrome://". Do so and wait for + // the suggestions to appear. + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.SUGGESTION_BOX, () -> { NativeUiUtils.inputBackspace(); }); + NativeUiUtils.inputEnter(); + // Navigating automatically appends a "/". + ChromeTabUtils.waitForTabPageLoaded( + mVrTestRule.getActivity().getActivityTab(), expectedString + "/"); + } + + /** + * Tests that the omnibox automatically clears any text that gets input but not committed. + */ + @Test + @MediumTest + public void testOmniboxClearsUncommittedText() throws InterruptedException { + // Similar to testOmniboxContainsCurrentUrl, we check that the uncommitted text is not + // present the second time we open the omnibox by deleting a number of characters from + // the expected text and entering additional text. + NativeUiUtils.enableMockedKeyboard(); + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + // Input text and close the omnibox without committing. + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.SUGGESTION_BOX, + () -> { NativeUiUtils.inputString("chrome://version/"); }); + NativeUiUtils.clickElementAndWaitForUiQuiescence( + UserFriendlyElementName.OMNIBOX_CLOSE_BUTTON, new PointF()); + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + // Click near the righthand side of the text input field so the cursor is at the end instead + // of selecting the existing text. + NativeUiUtils.clickElementAndWaitForUiQuiescence( + UserFriendlyElementName.OMNIBOX_TEXT_FIELD, new PointF(0.4f, 0.0f)); + // Delete "about:blank". + for (int i = 0; i < 11; ++i) { + NativeUiUtils.inputBackspace(); + } + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.SUGGESTION_BOX, + () -> { NativeUiUtils.inputString("chrome://version/"); }); + NativeUiUtils.inputEnter(); + // This should only succeed if the original "chrome://version/" we input is not present - + // if it is, we'll end up navigating to "chromechrome://version/". + ChromeTabUtils.waitForTabPageLoaded( + mVrTestRule.getActivity().getActivityTab(), "chrome://version/"); + } + + /** + * Tests that omnibox autocompletion is functional. + */ + @Test + @MediumTest + public void testOmniboxAutocompletion() throws InterruptedException { + // At least with chrome:// URLs, autocompletion only kicks in when there's one valid option + // left. So, test that: + // 1. Autocompletion works if only one option is available. + // 2. Autocompletion updates successfully if additional characters are added. + // 3. Autocompletion doesn't work if multiple options are available. + // 4. Autocompletion cancels if a non-matching character is input. + NativeUiUtils.enableMockedKeyboard(); + // Test that autocompletion works with only one option left. + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + // This should autocomplete to "chrome://version". + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.SUGGESTION_BOX, + () -> { NativeUiUtils.inputString("chrome://v"); }); + NativeUiUtils.inputEnter(); + ChromeTabUtils.waitForTabPageLoaded( + mVrTestRule.getActivity().getActivityTab(), "chrome://version/"); + // Navigate away from chrome://version/ so waitForTabPageLoaded doesn't no-op the next time. + mVrTestRule.loadUrl("about:blank"); + + // Test that autocompletion updates successfully when entering more text. + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.SUGGESTION_BOX, + () -> { NativeUiUtils.inputString("chrome://v"); }); + NativeUiUtils.inputString("e"); + // Since suggestions are already visible, we need to wait for suggestions to update via + // a glorified sleep instead of waiting for suggestions to appear. + NativeUiUtils.waitNumFrames(NativeUiUtils.NUM_FRAMES_FOR_SUGGESTION_UPDATE); + NativeUiUtils.inputEnter(); + ChromeTabUtils.waitForTabPageLoaded( + mVrTestRule.getActivity().getActivityTab(), "chrome://version/"); + + // Test that autocompletion doesn't work with more than one option available. + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + // This could be either "chrome://net-export" or "chrome://net-internals", so it shouldn't + // autocomplete to anything. + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.SUGGESTION_BOX, + () -> { NativeUiUtils.inputString("chrome://net-"); }); + NativeUiUtils.inputEnter(); + ChromeTabUtils.waitForTabPageLoaded( + mVrTestRule.getActivity().getActivityTab(), "chrome://net-/"); + + // Test that autocompletion cancels if a non-matching character is input. + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + // This should autocomplete to "chrome://version". + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.SUGGESTION_BOX, + () -> { NativeUiUtils.inputString("chrome://v"); }); + NativeUiUtils.inputString("a"); + NativeUiUtils.waitNumFrames(NativeUiUtils.NUM_FRAMES_FOR_SUGGESTION_UPDATE); + NativeUiUtils.inputEnter(); + ChromeTabUtils.waitForTabPageLoaded( + mVrTestRule.getActivity().getActivityTab(), "chrome://va/"); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java index bafb4da..84867e1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java
@@ -664,6 +664,25 @@ @Test @MediumTest public void testUrlEntryTriggersNavigation() throws InterruptedException { + testUrlEntryTriggersNavigationImpl(); + } + + /** + * Tests that inputting a URL into the URL bar in Incognito Mode results in a successful + * navigation. + */ + @Test + @MediumTest + public void testUrlEntryTriggersNavigationIncognito() throws InterruptedException { + ThreadUtils.runOnUiThreadBlocking(() -> { + mTestRule.getActivity() + .getTabCreator(true /* incognito */) + .launchUrl("about:blank", TabLaunchType.FROM_LINK); + }); + testUrlEntryTriggersNavigationImpl(); + } + + private void testUrlEntryTriggersNavigationImpl() throws InterruptedException { NativeUiUtils.enableMockedKeyboard(); NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); // This is a roundabout solution for ensuring that the committing/pressing of enter actually @@ -680,4 +699,47 @@ ChromeTabUtils.waitForTabPageLoaded( mTestRule.getActivity().getActivityTab(), "chrome://version/"); } + + /** + * Tests that clicking on a suggestion results in a successful navigation. + */ + @Test + @MediumTest + public void testSuggestionClickTriggersNavigation() throws InterruptedException { + testSuggestionClickTriggersNavigationImpl(); + } + + /** + * Tests that clicking on a suggestion while in Incognito Mode results in a successful + * navigation. + */ + @Test + @MediumTest + public void testSuggestionClickTriggersNavigationIncognito() throws InterruptedException { + ThreadUtils.runOnUiThreadBlocking(() -> { + mTestRule.getActivity() + .getTabCreator(true /* incognito */) + .launchUrl("about:blank", TabLaunchType.FROM_LINK); + }); + testSuggestionClickTriggersNavigationImpl(); + } + + private void testSuggestionClickTriggersNavigationImpl() throws InterruptedException { + NativeUiUtils.enableMockedKeyboard(); + NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF()); + NativeUiUtils.performActionAndWaitForVisibilityChange( + UserFriendlyElementName.SUGGESTION_BOX, + () -> { NativeUiUtils.inputString("chrome://"); }); + // Blindly clicking in the center of the suggestion box should end up clicking the middle + // suggestion, which for "chrome://" should be a valid chrome:// URL. + NativeUiUtils.clickElement(UserFriendlyElementName.SUGGESTION_BOX, new PointF()); + ChromeTabUtils.waitForTabPageLoaded( + mTestRule.getActivity().getActivityTab(), (String) null); + // We can't just wait for navigation to finish and then check because waitForTabPageLoaded + // only supports either exact URL matching or no URL matching, and no URL matching results + // in the URL still being about:blank when we check. + CriteriaHelper.pollInstrumentationThread(() -> { + return mTestRule.getActivity().getActivityTab().getUrl().startsWith("chrome://"); + }); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/NativeUiUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/NativeUiUtils.java index b87d19a..4cb8782 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/NativeUiUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/NativeUiUtils.java
@@ -33,9 +33,14 @@ * omnibox or back button. */ public class NativeUiUtils { + // How many frames to wait after entering text in the omnibox before we can assume that + // suggestions are updated. This should only be used if the workaround of inputting text and + // waiting for the suggestion box to appear doesn't work, e.g. if you need to input text, wait + // for autocomplete, then input more text before committing. 20 is arbitrary, but stable. + public static final int NUM_FRAMES_FOR_SUGGESTION_UPDATE = 20; // Arbitrary but reasonable amount of time to expect the UI to stop updating after interacting // with an element. - private static final int DEFAULT_UI_QUIESCENCE_TIMEOUT_MS = 1000; + private static final int DEFAULT_UI_QUIESCENCE_TIMEOUT_MS = 2000; /** * Enables the use of both the mock head pose (locked forward) and Chrome-side mocked controller
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index d64969a..5b9351746 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1243,11 +1243,22 @@ {resource_coordinator:: kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscardParam, "true"}}; +const FeatureEntry::FeatureParam + kProactiveTabFreezeAndDiscard_DisableHeuristics[] = { + {resource_coordinator:: + kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscardParam, + "true"}, + {resource_coordinator:: + kProactiveTabFreezeAndDiscard_DisableHeuristicsParam, + "true"}}; const FeatureEntry::FeatureVariation kProactiveTabFreezeAndDiscardVariations[] = {{"Freeze only", kProactiveTabFreezeAndDiscard_FreezeOnly, base::size(kProactiveTabFreezeAndDiscard_FreezeOnly), nullptr}, {"Freeze and discard", kProactiveTabFreezeAndDiscard_FreezeAndDiscard, - base::size(kProactiveTabFreezeAndDiscard_FreezeAndDiscard), nullptr}}; + base::size(kProactiveTabFreezeAndDiscard_FreezeAndDiscard), nullptr}, + {"Freeze and discard, heuristics disabled", + kProactiveTabFreezeAndDiscard_DisableHeuristics, + base::size(kProactiveTabFreezeAndDiscard_DisableHeuristics), nullptr}}; #endif const FeatureEntry::FeatureParam kGamepadPollingRate100Hz[] = { @@ -1493,10 +1504,6 @@ flag_descriptions::kDisablePushStateThrottleName, flag_descriptions::kDisablePushStateThrottleDescription, kOsAll, SINGLE_VALUE_TYPE(switches::kDisablePushStateThrottle)}, - {"disable-ipc-flooding-protection", - flag_descriptions::kDisableIpcFloodingProtectionName, - flag_descriptions::kDisableIpcFloodingProtectionDescription, kOsAll, - SINGLE_VALUE_TYPE(switches::kDisableIpcFloodingProtection)}, {"disable-hyperlink-auditing", flag_descriptions::kHyperlinkAuditingName, flag_descriptions::kHyperlinkAuditingDescription, kOsAll, SINGLE_DISABLE_VALUE_TYPE(switches::kNoPings)},
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index 6ea3f5be..f2019825 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -12,6 +12,7 @@ #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/command_line.h" +#include "base/time/time.h" #include "chrome/browser/android/chrome_feature_list.h" #include "chrome/browser/autofill/personal_data_manager_factory.h" #include "chrome/browser/profiles/profile_manager.h" @@ -128,7 +129,9 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller, const base::android::JavaParamRef<jstring>& jaddress_guid) { - DCHECK(address_or_card_callback_); + if (!address_or_card_callback_) // possibly duplicate call + return; + std::string guid; base::android::ConvertJavaStringToUTF8(env, jaddress_guid, &guid); std::move(address_or_card_callback_).Run(guid); @@ -138,7 +141,9 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller, const base::android::JavaParamRef<jstring>& jcard_guid) { - DCHECK(address_or_card_callback_); + if (!address_or_card_callback_) // possibly duplicate call + return; + std::string guid; base::android::ConvertJavaStringToUTF8(env, jcard_guid, &guid); std::move(address_or_card_callback_).Run(guid); @@ -162,6 +167,34 @@ env, java_autofill_assistant_ui_controller_); } +void UiControllerAndroid::HideDetails() { + Java_AutofillAssistantUiController_onHideDetails( + AttachCurrentThread(), java_autofill_assistant_ui_controller_); +} + +void UiControllerAndroid::ShowDetails(const DetailsProto& details) { + base::Time time; + base::Time::Exploded exploded; + exploded.year = details.datetime().date().year(); + exploded.month = details.datetime().date().month(); + exploded.day_of_month = details.datetime().date().day(); + exploded.hour = details.datetime().time().hour(); + exploded.minute = details.datetime().time().minute(); + exploded.second = details.datetime().time().second(); + + long java_time = 0; + if (base::Time::FromUTCExploded(exploded, &time)) { + java_time = time.ToJavaTime(); + } + + JNIEnv* env = AttachCurrentThread(); + Java_AutofillAssistantUiController_onShowDetails( + env, java_autofill_assistant_ui_controller_, + base::android::ConvertUTF8ToJavaString(env, details.title()), + base::android::ConvertUTF8ToJavaString(env, details.url()), java_time, + base::android::ConvertUTF8ToJavaString(env, details.description())); +} + std::string UiControllerAndroid::GetApiKey() { std::string api_key; if (google_apis::IsGoogleChromeAPIKeyUsed()) {
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.h b/chrome/browser/android/autofill_assistant/ui_controller_android.h index 6121c62..f1b2d8a 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.h +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.h
@@ -36,6 +36,8 @@ base::OnceCallback<void(const std::string&)> callback) override; void ChooseCard( base::OnceCallback<void(const std::string&)> callback) override; + void HideDetails() override; + void ShowDetails(const DetailsProto& details) override; // Overrides Client: std::string GetApiKey() override;
diff --git a/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc b/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc index 07533401..93f6485 100644 --- a/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc +++ b/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc
@@ -7,9 +7,10 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/json/json_reader.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "content/public/test/test_browser_thread.h" #include "net/base/net_errors.h" @@ -28,7 +29,8 @@ DigitalAssetLinksHandlerTest() : num_invocations_(0), result_(RelationshipCheckResult::SUCCESS), - io_thread_(content::BrowserThread::IO, &message_loop_) {} + io_thread_(content::BrowserThread::IO, + base::ThreadTaskRunnerHandle::Get()) {} void OnRelationshipCheckComplete(RelationshipCheckResult result) { ++num_invocations_; @@ -89,7 +91,7 @@ RelationshipCheckResult result_; private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_; content::TestBrowserThread io_thread_; network::TestURLLoaderFactory test_url_loader_factory_;
diff --git a/chrome/browser/android/preferences/pref_service_bridge.cc b/chrome/browser/android/preferences/pref_service_bridge.cc index be61fb32..a46c5eb 100644 --- a/chrome/browser/android/preferences/pref_service_bridge.cc +++ b/chrome/browser/android/preferences/pref_service_bridge.cc
@@ -409,7 +409,8 @@ static jboolean JNI_PrefServiceBridge_IsScoutExtendedReportingActive( JNIEnv* env, const JavaParamRef<jobject>& obj) { - return safe_browsing::IsScout(*GetPrefService()); + // TODO(lpz/scout): Remove this method and refactor calling code. + return true; } static jboolean JNI_PrefServiceBridge_GetSafeBrowsingExtendedReportingEnabled(
diff --git a/chrome/browser/autofill/personal_data_manager_factory.cc b/chrome/browser/autofill/personal_data_manager_factory.cc index 8d87dbc..f555f43 100644 --- a/chrome/browser/autofill/personal_data_manager_factory.cc +++ b/chrome/browser/autofill/personal_data_manager_factory.cc
@@ -7,6 +7,7 @@ #include "base/memory/singleton.h" #include "chrome/browser/autofill/autofill_profile_validator_factory.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" @@ -50,9 +51,11 @@ profile, ServiceAccessType::EXPLICIT_ACCESS); auto account_storage = WebDataServiceFactory::GetAutofillWebDataForAccount( profile, ServiceAccessType::EXPLICIT_ACCESS); + auto* history_service = HistoryServiceFactory::GetForProfile( + profile, ServiceAccessType::EXPLICIT_ACCESS); service->Init(local_storage, account_storage, profile->GetPrefs(), IdentityManagerFactory::GetForProfile(profile), - AutofillProfileValidatorFactory::GetInstance(), + AutofillProfileValidatorFactory::GetInstance(), history_service, profile->IsOffTheRecord()); return service; }
diff --git a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc index bd2896c..8de926e 100644 --- a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc +++ b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc
@@ -86,12 +86,14 @@ } void SetUpOnMainThread() override { - settings_helper_.ReplaceProvider(kAccountsPrefDeviceLocalAccounts); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); owner_settings_service_ = settings_helper_.CreateOwnerSettingsService(browser()->profile()); } - void TearDownOnMainThread() override { settings_helper_.RestoreProvider(); } + void TearDownOnMainThread() override { + settings_helper_.RestoreRealDeviceSettingsProvider(); + } void SetApps(const std::vector<policy::ArcKioskAppBasicInfo>& apps, const std::string& auto_login_account) {
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc index dc655de5..4ede611 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
@@ -253,12 +253,14 @@ // spawned. embedded_test_server()->StartAcceptingConnections(); - settings_helper_.ReplaceProvider(kAccountsPrefDeviceLocalAccounts); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); owner_settings_service_ = settings_helper_.CreateOwnerSettingsService(browser()->profile()); } - void TearDownOnMainThread() override { settings_helper_.RestoreProvider(); } + void TearDownOnMainThread() override { + settings_helper_.RestoreRealDeviceSettingsProvider(); + } std::string GetAppIds() const { KioskAppManager::Apps apps;
diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher_unittest.cc b/chrome/browser/chromeos/app_mode/startup_app_launcher_unittest.cc index 37c1da8..3ffa0c53 100644 --- a/chrome/browser/chromeos/app_mode/startup_app_launcher_unittest.cc +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher_unittest.cc
@@ -504,8 +504,7 @@ accounts_settings_helper_ = std::make_unique<ScopedCrosSettingsTestHelper>( false /*create_service*/); - accounts_settings_helper_->ReplaceProvider( - kAccountsPrefDeviceLocalAccounts); + accounts_settings_helper_->ReplaceDeviceSettingsProviderWithStub(); auto account = std::make_unique<base::DictionaryValue>(); account->SetKey(kAccountsPrefDeviceLocalAccountsKeyId,
diff --git a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc index 40042e6c..32620754 100644 --- a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc +++ b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc
@@ -66,7 +66,7 @@ class AttestationPolicyObserverTest : public ::testing::Test { public: AttestationPolicyObserverTest() { - settings_helper_.ReplaceProvider(kDeviceAttestationEnabled); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); settings_helper_.SetBoolean(kDeviceAttestationEnabled, true); policy_client_.SetDMToken("fake_dm_token"); }
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc index f7819c3..a21ec178 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc +++ b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc
@@ -114,7 +114,7 @@ callback_ = base::Bind(&PlatformVerificationFlowTest::FakeChallengeCallback, base::Unretained(this)); - settings_helper_.ReplaceProvider(kAttestationForContentProtectionEnabled); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); settings_helper_.SetBoolean(kAttestationForContentProtectionEnabled, true); }
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 974fdbc..f87dd0ff 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -619,6 +619,12 @@ TestCase("showGridViewDrive"), TestCase("showGridViewDrive").EnableDriveFs())); +// TODO(crbug.com/891119): Flaky on Chrome OS. +#if defined(OS_CHROMEOS) +#define MAYBE_Providers DISABLED_Providers +#else +#define MAYBE_Providers Providers +#endif WRAPPED_INSTANTIATE_TEST_CASE_P( Providers, /* providers.js */ FilesAppBrowserTest,
diff --git a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc index bfa5eea..911a9a8 100644 --- a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc +++ b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
@@ -556,7 +556,7 @@ state_->PresetCryptohomeStatus(cryptohome::MOUNT_ERROR_NONE); SetOwnerState(false, false); ScopedCrosSettingsTestHelper settings_helper(false); - settings_helper.ReplaceProvider(kPolicyMissingMitigationMode); + settings_helper.ReplaceDeviceSettingsProviderWithStub(); settings_helper.SetBoolean(kPolicyMissingMitigationMode, true); // Initialize login state for this test to verify the login state is changed @@ -606,7 +606,7 @@ state_->PresetCryptohomeStatus(cryptohome::MOUNT_ERROR_NONE); SetOwnerState(false, false); ScopedCrosSettingsTestHelper settings_helper(false); - settings_helper.ReplaceProvider(kPolicyMissingMitigationMode); + settings_helper.ReplaceDeviceSettingsProviderWithStub(); settings_helper.SetBoolean(kPolicyMissingMitigationMode, true); // Initialize login state for this test to verify the login state is changed
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc index 5bc35d9..ca1cd4d 100644 --- a/chrome/browser/chromeos/login/kiosk_browsertest.cc +++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -525,7 +525,7 @@ // Needed to avoid showing Gaia screen instead of owner signin for // consumer network down test cases. StartupUtils::MarkDeviceRegistered(base::Closure()); - settings_helper_.ReplaceProvider(kAccountsPrefDeviceLocalAccounts); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); owner_settings_service_ = settings_helper_.CreateOwnerSettingsService( ProfileManager::GetPrimaryUserProfile()); @@ -534,7 +534,7 @@ } void TearDownOnMainThread() override { - settings_helper_.RestoreProvider(); + settings_helper_.RestoreRealDeviceSettingsProvider(); AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL); AppLaunchSigninScreen::SetUserManagerForTesting(NULL);
diff --git a/chrome/browser/chromeos/login/users/user_manager_unittest.cc b/chrome/browser/chromeos/login/users/user_manager_unittest.cc index 9afd52c..8a24c935 100644 --- a/chrome/browser/chromeos/login/users/user_manager_unittest.cc +++ b/chrome/browser/chromeos/login/users/user_manager_unittest.cc
@@ -64,7 +64,7 @@ command_line.AppendSwitch( chromeos::switches::kIgnoreUserProfileMappingForTests); - settings_helper_.ReplaceProvider(kDeviceOwner); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); // Populate the stub DeviceSettingsProvider with valid values. SetDeviceSettings(false, "", false);
diff --git a/chrome/browser/chromeos/policy/bluetooth_policy_handler_unittest.cc b/chrome/browser/chromeos/policy/bluetooth_policy_handler_unittest.cc index 5beedfe..5355be2 100644 --- a/chrome/browser/chromeos/policy/bluetooth_policy_handler_unittest.cc +++ b/chrome/browser/chromeos/policy/bluetooth_policy_handler_unittest.cc
@@ -34,7 +34,7 @@ // testing::Test void SetUp() override { testing::Test::SetUp(); - settings_helper_.ReplaceProvider(chromeos::kAllowBluetooth); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); }
diff --git a/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_utils_unittest.cc b/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_utils_unittest.cc index 3661376..e1ab4aa 100644 --- a/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_utils_unittest.cc +++ b/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_utils_unittest.cc
@@ -82,8 +82,8 @@ void TearDown() override { icu::TimeZone::adoptDefault(timezone_.release()); } void SetCrosSettings(const std::string& path, const Value& in_value) { + cros_settings_helper_.ReplaceDeviceSettingsProviderWithStub(); cros_settings_helper_.Set(path, in_value); - cros_settings_helper_.ReplaceProvider(path); } ListValue GetIntervalsAsList(const vector<WeeklyTimeInterval>& intervals) {
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc index e7ee855..418a85a8 100644 --- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -370,7 +370,7 @@ TestingDeviceStatusCollector::RegisterProfilePrefs( profile_pref_service_.registry()); - settings_helper_.ReplaceProvider(chromeos::kReportDeviceActivityTimes); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); owner_settings_service_ = settings_helper_.CreateOwnerSettingsService(nullptr); owner_settings_service_->set_ignore_profile_creation_notification(true); @@ -416,7 +416,9 @@ false); } - void TearDown() override { settings_helper_.RestoreProvider(); } + void TearDown() override { + settings_helper_.RestoreRealDeviceSettingsProvider(); + } protected: // States tracked to calculate a child's active time. @@ -2254,6 +2256,18 @@ base::test::ScopedFeatureList scoped_feature_list_; }; +void expectChildScreenTimeMilliseconds(int64_t duration, + TestingPrefServiceSimple* pref_service) { + pref_service->CommitPendingWrite( + base::OnceClosure(), + base::BindOnce( + [](int64_t duration, TestingPrefServiceSimple* pref_service) { + EXPECT_EQ(duration, pref_service->GetInteger( + prefs::kChildScreenTimeMilliseconds)); + }, + duration, pref_service)); +} + TEST_F(ConsumerDeviceStatusCollectorTimeLimitDisabledTest, ReportingBootMode) { fake_statistics_provider_.SetMachineStatistic( chromeos::system::kDevSwitchBootKey, @@ -2418,9 +2432,8 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -// Fails on all chromeos builders https://crbug.com/891573 TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, - DISABLED_ReportingActivityTimesSessionTransistions) { + ReportingActivityTimesSessionTransistions) { DeviceStateTransitions test_states[] = { DeviceStateTransitions::kEnterSessionActive, DeviceStateTransitions::kPeriodicCheckTriggered, @@ -2438,16 +2451,14 @@ ASSERT_EQ(1, device_status_.active_period_size()); EXPECT_EQ(5 * ActivePeriodMilliseconds(), GetActiveMilliseconds(device_status_)); - EXPECT_EQ( - 5 * ActivePeriodMilliseconds(), - profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds)); + expectChildScreenTimeMilliseconds(5 * ActivePeriodMilliseconds(), + &profile_pref_service_); EXPECT_EQ(user_account_id_.GetUserEmail(), device_status_.active_period(0).user_email()); } -// Fails on all chromeos builders https://crbug.com/891573 TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, - DISABLED_ReportingActivityTimesSleepTransistions) { + ReportingActivityTimesSleepTransistions) { DeviceStateTransitions test_states[] = { DeviceStateTransitions::kEnterSessionActive, DeviceStateTransitions::kPeriodicCheckTriggered, @@ -2464,16 +2475,14 @@ ASSERT_EQ(1, device_status_.active_period_size()); EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(device_status_)); - EXPECT_EQ( - 4 * ActivePeriodMilliseconds(), - profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds)); + expectChildScreenTimeMilliseconds(4 * ActivePeriodMilliseconds(), + &profile_pref_service_); EXPECT_EQ(user_account_id_.GetUserEmail(), device_status_.active_period(0).user_email()); } -// Fails on all chromeos builders https://crbug.com/891573 TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, - DISABLED_ReportingActivityTimesIdleTransitions) { + ReportingActivityTimesIdleTransitions) { DeviceStateTransitions test_states[] = { DeviceStateTransitions::kEnterSessionActive, DeviceStateTransitions::kPeriodicCheckTriggered, @@ -2492,16 +2501,13 @@ ASSERT_EQ(1, device_status_.active_period_size()); EXPECT_EQ(5 * ActivePeriodMilliseconds(), GetActiveMilliseconds(device_status_)); - EXPECT_EQ( - 5 * ActivePeriodMilliseconds(), - profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds)); + expectChildScreenTimeMilliseconds(5 * ActivePeriodMilliseconds(), + &profile_pref_service_); EXPECT_EQ(user_account_id_.GetUserEmail(), device_status_.active_period(0).user_email()); } -// Fails on all chromeos builders https://crbug.com/891573 -TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, - DISABLED_ActivityKeptInPref) { +TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, ActivityKeptInPref) { EXPECT_TRUE( profile_pref_service_.GetDictionary(prefs::kUserActivityTimes)->empty()); @@ -2534,14 +2540,12 @@ GetStatus(); EXPECT_EQ(12 * ActivePeriodMilliseconds(), GetActiveMilliseconds(device_status_)); - EXPECT_EQ( - 12 * ActivePeriodMilliseconds(), - profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds)); + expectChildScreenTimeMilliseconds(12 * ActivePeriodMilliseconds(), + &profile_pref_service_); } -// Fails on all chromeos builders https://crbug.com/891573 TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, - DISABLED_ActivityNotWrittenToLocalState) { + ActivityNotWrittenToLocalState) { EXPECT_TRUE(local_state_.GetDictionary(prefs::kDeviceActivityTimes)->empty()); DeviceStateTransitions test_states[] = { @@ -2562,10 +2566,8 @@ EXPECT_EQ(1, device_status_.active_period_size()); EXPECT_EQ(5 * ActivePeriodMilliseconds(), GetActiveMilliseconds(device_status_)); - EXPECT_EQ( - 5 * ActivePeriodMilliseconds(), - profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds)); - + expectChildScreenTimeMilliseconds(5 * ActivePeriodMilliseconds(), + &profile_pref_service_); // Nothing should be written to local state, because it is only used for // enterprise reporting. EXPECT_TRUE(local_state_.GetDictionary(prefs::kDeviceActivityTimes)->empty()); @@ -2602,9 +2604,8 @@ kMillisecondsPerDay); EXPECT_EQ(time_period1.end_timestamp() - time_period1.start_timestamp(), kMillisecondsPerDay); - EXPECT_EQ( - 0.5 * ActivePeriodMilliseconds(), - profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds)); + expectChildScreenTimeMilliseconds(0.5 * ActivePeriodMilliseconds(), + &profile_pref_service_); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/extension_cache_unittest.cc b/chrome/browser/chromeos/policy/extension_cache_unittest.cc index 4767803..1484491 100644 --- a/chrome/browser/chromeos/policy/extension_cache_unittest.cc +++ b/chrome/browser/chromeos/policy/extension_cache_unittest.cc
@@ -62,7 +62,7 @@ }; TEST_F(ExtensionCacheTest, SizePolicy) { - settings_helper_.ReplaceProvider(chromeos::kExtensionCacheSize); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); settings_helper_.SetInteger(chromeos::kExtensionCacheSize, kMaxCacheSize); // Create and initialize local cache.
diff --git a/chrome/browser/chromeos/policy/heartbeat_scheduler_unittest.cc b/chrome/browser/chromeos/policy/heartbeat_scheduler_unittest.cc index e82d1b0..b051034a 100644 --- a/chrome/browser/chromeos/policy/heartbeat_scheduler_unittest.cc +++ b/chrome/browser/chromeos/policy/heartbeat_scheduler_unittest.cc
@@ -131,7 +131,7 @@ task_runner_) {} void SetUp() override { - settings_helper_.ReplaceProvider(chromeos::kHeartbeatEnabled); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); } void TearDown() override { content::RunAllTasksUntilIdle(); }
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc index 849b912..c34c235 100644 --- a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc +++ b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
@@ -457,7 +457,7 @@ // Ignore network config updates. EXPECT_CALL(network_config_handler_, SetPolicy(_, _, _, _)).Times(AtLeast(1)); - settings_helper_.ReplaceProvider(chromeos::kSignedDataRoamingEnabled); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); settings_helper_.SetBoolean(chromeos::kSignedDataRoamingEnabled, false); EXPECT_FALSE(network_device_handler_.allow_roaming_);
diff --git a/chrome/browser/chromeos/policy/site_isolation_flag_handling_browsertest.cc b/chrome/browser/chromeos/policy/site_isolation_flag_handling_browsertest.cc index 32df7509..6e5f3d6 100644 --- a/chrome/browser/chromeos/policy/site_isolation_flag_handling_browsertest.cc +++ b/chrome/browser/chromeos/policy/site_isolation_flag_handling_browsertest.cc
@@ -289,7 +289,7 @@ policy::LoginPolicyTestBase::SetUpOnMainThread(); // Write ephemeral users status directly into CrosSettings. - settings_helper_.ReplaceProvider(kAccountsPrefEphemeralUsersEnabled); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); settings_helper_.SetBoolean(kAccountsPrefEphemeralUsersEnabled, GetParam().ephemeral_users); @@ -315,7 +315,9 @@ base::Unretained(this))); } - void TearDownOnMainThread() override { settings_helper_.RestoreProvider(); } + void TearDownOnMainThread() override { + settings_helper_.RestoreRealDeviceSettingsProvider(); + } ChromeUserManagerImpl* GetChromeUserManager() const { return static_cast<ChromeUserManagerImpl*>(
diff --git a/chrome/browser/chromeos/policy/status_uploader_unittest.cc b/chrome/browser/chromeos/policy/status_uploader_unittest.cc index fa9a019a..dedb025f 100644 --- a/chrome/browser/chromeos/policy/status_uploader_unittest.cc +++ b/chrome/browser/chromeos/policy/status_uploader_unittest.cc
@@ -87,7 +87,7 @@ chromeos::DBusThreadManager::Initialize(); client_.SetDMToken("dm_token"); collector_.reset(new MockDeviceStatusCollector(&prefs_)); - settings_helper_.ReplaceProvider(chromeos::kReportUploadFrequency); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); // Keep a pointer to the mock collector because collector_ gets cleared // when it is passed to the StatusUploader constructor.
diff --git a/chrome/browser/chromeos/policy/system_log_uploader_unittest.cc b/chrome/browser/chromeos/policy/system_log_uploader_unittest.cc index 06eafbf..3c23e44 100644 --- a/chrome/browser/chromeos/policy/system_log_uploader_unittest.cc +++ b/chrome/browser/chromeos/policy/system_log_uploader_unittest.cc
@@ -160,11 +160,11 @@ SystemLogUploaderTest() : task_runner_(new base::TestSimpleTaskRunner()) {} void SetUp() override { - settings_helper_.ReplaceProvider(chromeos::kSystemLogUploadEnabled); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); } void TearDown() override { - settings_helper_.RestoreProvider(); + settings_helper_.RestoreRealDeviceSettingsProvider(); content::RunAllTasksUntilIdle(); }
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc index e96a469..7676e10 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -21,7 +21,6 @@ #include "base/threading/thread_restrictions.h" #include "base/values.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" -#include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/policy/device_policy_decoder_chromeos.h" #include "chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser.h" #include "chrome/browser/chromeos/settings/cros_settings.h" @@ -256,7 +255,8 @@ base::Value(entry->deprecated_public_session_id())); entry_dict->SetKey( kAccountsPrefDeviceLocalAccountsKeyType, - base::Value(policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)); + base::Value( + em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION)); } account_list->Append(std::move(entry_dict)); }
diff --git a/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc index 7ff3ee5..c7b2621 100644 --- a/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc +++ b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc
@@ -29,7 +29,7 @@ } ScopedCrosSettingsTestHelper::~ScopedCrosSettingsTestHelper() { - RestoreProvider(); + RestoreRealDeviceSettingsProvider(); } std::unique_ptr<FakeOwnerSettingsService> @@ -38,13 +38,15 @@ profile, new ownership::MockOwnerKeyUtil(), stub_settings_provider_ptr_); } -void ScopedCrosSettingsTestHelper::ReplaceProvider(const std::string& path) { +void ScopedCrosSettingsTestHelper::ReplaceDeviceSettingsProviderWithStub() { CHECK(!real_settings_provider_); - // Swap out the DeviceSettingsProvider with our settings provider so we can - // set values for the specified path. + // Swap out the DeviceSettingsProvider with our settings provider. CrosSettings* const cros_settings = CrosSettings::Get(); + + // TODO(olsen): This could be simplified if DeviceSettings and CrosSettings + // were the same thing, which they nearly are, except for 3 timezone settings. CrosSettingsProvider* real_settings_provider = - cros_settings->GetProvider(path); + cros_settings->GetProvider(kDeviceOwner); // Can be any device setting. EXPECT_TRUE(real_settings_provider); real_settings_provider_ = cros_settings->RemoveSettingsProvider(real_settings_provider); @@ -52,7 +54,7 @@ cros_settings->AddSettingsProvider(std::move(stub_settings_provider_)); } -void ScopedCrosSettingsTestHelper::RestoreProvider() { +void ScopedCrosSettingsTestHelper::RestoreRealDeviceSettingsProvider() { if (real_settings_provider_) { // Restore the real DeviceSettingsProvider. CrosSettings* const cros_settings = CrosSettings::Get(); @@ -61,6 +63,11 @@ EXPECT_TRUE(stub_settings_provider_); cros_settings->AddSettingsProvider(std::move(real_settings_provider_)); } + real_settings_provider_.reset(); +} + +bool ScopedCrosSettingsTestHelper::IsDeviceSettingsProviderStubbed() { + return !!real_settings_provider_; } void ScopedCrosSettingsTestHelper::SetTrustedStatus( @@ -74,6 +81,7 @@ void ScopedCrosSettingsTestHelper::Set(const std::string& path, const base::Value& in_value) { + CHECK(IsDeviceSettingsProviderStubbed()); stub_settings_provider_ptr_->Set(path, in_value); }
diff --git a/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h index 8d2128f..22bd06cf 100644 --- a/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h +++ b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h
@@ -34,10 +34,11 @@ explicit ScopedCrosSettingsTestHelper(bool create_settings_service = true); ~ScopedCrosSettingsTestHelper(); - // Methods to replace and restore CrosSettingsProvider for the specified - // |path|. - void ReplaceProvider(const std::string& path); - void RestoreProvider(); + // This replaces the DeviceSettingsProvider with a simple stub that stores + // settings in memory unsigned; see StubCrosSettingsProvider for more info. + void ReplaceDeviceSettingsProviderWithStub(); + void RestoreRealDeviceSettingsProvider(); + bool IsDeviceSettingsProviderStubbed(); // Method to create an owner settings service that uses // |stub_settings_provider_| as settings write path. @@ -56,13 +57,14 @@ void SetDouble(const std::string& path, double in_value); void SetString(const std::string& path, const std::string& in_value); - // This may be called before |ReplaceProvider| to copy values currently stored - // in the old provider. If the method is called after |ReplaceProvider|, then - // the value is retrieved from |real_settings_provider_| for any |path|. + // This may be called before or after |ReplaceDeviceSettingsProviderWithStub| + // is called. It reads the value for |path| from the original, real, + // DeviceSettingsProvider, and copies it to the stub DeviceSettingsProvider. void CopyStoredValue(const std::string& path); - // Write the setting from |path| to local state so that it can be retrieved - // later on browser test startup by the device settings service. + // Write the setting from |path| in the stub DeviceSettingsProvider to local + // state so that it can be retrieved later on browser test startup by the + // device settings service. void StoreCachedDeviceSetting(const std::string& path); // Get the scoped install attributes to change them as needed for the
diff --git a/chrome/browser/chromeos/settings/shutdown_policy_handler_unittest.cc b/chrome/browser/chromeos/settings/shutdown_policy_handler_unittest.cc index f85c27d..24474d2 100644 --- a/chrome/browser/chromeos/settings/shutdown_policy_handler_unittest.cc +++ b/chrome/browser/chromeos/settings/shutdown_policy_handler_unittest.cc
@@ -25,7 +25,7 @@ void SetUp() override { testing::Test::SetUp(); DBusThreadManager::Initialize(); - settings_helper_.ReplaceProvider(kRebootOnShutdown); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); } void TearDown() override { DBusThreadManager::Shutdown(); }
diff --git a/chrome/browser/chromeos/tpm_firmware_update_unittest.cc b/chrome/browser/chromeos/tpm_firmware_update_unittest.cc index 3a0cd0e2..07852004 100644 --- a/chrome/browser/chromeos/tpm_firmware_update_unittest.cc +++ b/chrome/browser/chromeos/tpm_firmware_update_unittest.cc
@@ -222,7 +222,7 @@ public: void SetUp() override { TPMFirmwareUpdateModesTest::SetUp(); - cros_settings_test_helper_.ReplaceProvider(kTPMFirmwareUpdateSettings); + cros_settings_test_helper_.ReplaceDeviceSettingsProviderWithStub(); cros_settings_test_helper_.InstallAttributes()->SetCloudManaged( "example.com", "fake-device-id"); }
diff --git a/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc b/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc index 9c60f3a..9665a94 100644 --- a/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc +++ b/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/task/post_task.h" +#include "chrome/browser/ssl/ssl_error_assistant.h" #include "chrome/browser/ssl/ssl_error_handler.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -46,6 +47,16 @@ DVLOG(1) << "Failed parsing proto " << pb_path.value(); return; } + + // Retrieve the default proto from the resource bundle and keep the most + // recent version. This is required since the component updater may still have + // an older version. + std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> default_proto = + SSLErrorAssistant::GetErrorAssistantProtoFromResourceBundle(); + if (default_proto && default_proto->version_id() > proto->version_id()) { + proto = std::move(default_proto); + } + base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::UI}) ->PostTask(FROM_HERE, base::BindOnce(&SSLErrorHandler::SetErrorAssistantProto,
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc index f6acb71..97b4ffd67 100644 --- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc +++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc
@@ -33,15 +33,14 @@ void SetUpOnMainThread() override { PlatformAppBrowserTest::SetUpOnMainThread(); - settings_helper_.ReplaceProvider( - chromeos::kAccountsPrefDeviceLocalAccounts); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); owner_settings_service_ = settings_helper_.CreateOwnerSettingsService(browser()->profile()); } void TearDownOnMainThread() override { PlatformAppBrowserTest::TearDownOnMainThread(); - settings_helper_.RestoreProvider(); + settings_helper_.RestoreRealDeviceSettingsProvider(); user_manager_enabler_.reset(); fake_user_manager_ = nullptr; }
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc index 17e44aa..afc81fc 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -221,8 +221,7 @@ if (!new_meta_info) { changes.additional_properties[it->first] = ""; } else { - BookmarkNode::MetaInfoMap::const_iterator new_meta_field = - new_meta_info->find(it->first); + auto new_meta_field = new_meta_info->find(it->first); if (new_meta_field == new_meta_info->end()) { changes.additional_properties[it->first] = ""; } else if (it->second != new_meta_field->second) { @@ -233,11 +232,8 @@ // Identify added fields: if (new_meta_info) { - for (BookmarkNode::MetaInfoMap::const_iterator it = new_meta_info->begin(); - it != new_meta_info->end(); - ++it) { - BookmarkNode::MetaInfoMap::const_iterator prev_meta_field = - prev_meta_info_.find(it->first); + for (auto it = new_meta_info->cbegin(); it != new_meta_info->cend(); ++it) { + auto prev_meta_field = prev_meta_info_.find(it->first); if (prev_meta_field == prev_meta_info_.end()) changes.additional_properties[it->first] = it->second; }
diff --git a/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc b/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc index 2b5a259..f92d4a4 100644 --- a/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc +++ b/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc
@@ -189,8 +189,7 @@ VLOG(1) << "Current audio tone frequency: " << frequency; const int kTargetWindowHz = 20; - for (std::vector<int>::iterator it = expected_tones_.begin(); - it != expected_tones_.end(); ++it) { + for (auto it = expected_tones_.begin(); it != expected_tones_.end(); ++it) { if (abs(static_cast<int>(frequency) - *it) < kTargetWindowHz) { LOG(INFO) << "Heard tone at frequency " << *it << " Hz."; expected_tones_.erase(it); @@ -234,7 +233,7 @@ << current_color.u << ", " << current_color.v << ')'; const int kTargetWindow = 10; - for (std::vector<YUVColor>::iterator it = expected_yuv_colors_.begin(); + for (auto it = expected_yuv_colors_.begin(); it != expected_yuv_colors_.end(); ++it) { if (abs(current_color.y - it->y) < kTargetWindow && abs(current_color.u - it->u) < kTargetWindow &&
diff --git a/chrome/browser/extensions/api/commands/command_service.cc b/chrome/browser/extensions/api/commands/command_service.cc index d8f0b19..8e055684 100644 --- a/chrome/browser/extensions/api/commands/command_service.cc +++ b/chrome/browser/extensions/api/commands/command_service.cc
@@ -181,8 +181,7 @@ if (!commands) return false; - for (CommandMap::const_iterator iter = commands->begin(); - iter != commands->end(); ++iter) { + for (auto iter = commands->cbegin(); iter != commands->cend(); ++iter) { // Look up to see if the user has overridden how the command should work. Command saved_command = FindCommandByName(extension_id, iter->second.command_name()); @@ -510,8 +509,7 @@ if (!commands) return; - for (CommandMap::const_iterator iter = commands->begin(); - iter != commands->end(); ++iter) { + for (auto iter = commands->cbegin(); iter != commands->cend(); ++iter) { const Command command = iter->second; if (CanAutoAssign(command, extension)) { AddKeybindingPref(command.accelerator(), @@ -602,8 +600,7 @@ const CommandMap* commands = CommandsInfo::GetNamedCommands(extension); if (commands) { - for (CommandMap::const_iterator iter = commands->begin(); - iter != commands->end(); ++iter) { + for (auto iter = commands->cbegin(); iter != commands->cend(); ++iter) { const Command command = iter->second; std::unique_ptr<base::DictionaryValue> command_keys( new base::DictionaryValue); @@ -731,7 +728,7 @@ const CommandMap* named_commands = CommandsInfo::GetNamedCommands(extension); if (named_commands) { - CommandMap::const_iterator loc = named_commands->find(command_name); + auto loc = named_commands->find(command_name); if (loc != named_commands->end()) new_command = loc->second; }
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_api.cc b/chrome/browser/extensions/api/content_settings/content_settings_api.cc index f0688bfb..f245875 100644 --- a/chrome/browser/extensions/api/content_settings/content_settings_api.cc +++ b/chrome/browser/extensions/api/content_settings/content_settings_api.cc
@@ -332,8 +332,7 @@ PluginFinder* finder = PluginFinder::GetInstance(); std::set<std::string> group_identifiers; std::unique_ptr<base::ListValue> list(new base::ListValue()); - for (std::vector<content::WebPluginInfo>::const_iterator it = plugins.begin(); - it != plugins.end(); ++it) { + for (auto it = plugins.cbegin(); it != plugins.cend(); ++it) { std::unique_ptr<PluginMetadata> plugin_metadata( finder->GetPluginMetadata(*it)); const std::string& group_identifier = plugin_metadata->identifier();
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc index a7c4849..b610acb5 100644 --- a/chrome/browser/extensions/api/debugger/debugger_api.cc +++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -478,7 +478,7 @@ const std::string& extension_id = extension()->id(); DevToolsAgentHost* agent_host = agent_host_.get(); AttachedClientHosts& hosts = g_attached_client_hosts.Get(); - AttachedClientHosts::iterator it = std::find_if( + auto it = std::find_if( hosts.begin(), hosts.end(), [&agent_host, &extension_id](ExtensionDevToolsClientHost* client_host) { return client_host->agent_host() == agent_host &&
diff --git a/chrome/browser/extensions/api/debugger/extension_dev_tools_infobar.cc b/chrome/browser/extensions/api/debugger/extension_dev_tools_infobar.cc index fdc19ab8..2098ec451 100644 --- a/chrome/browser/extensions/api/debugger/extension_dev_tools_infobar.cc +++ b/chrome/browser/extensions/api/debugger/extension_dev_tools_infobar.cc
@@ -101,8 +101,7 @@ const std::string& extension_name, ExtensionDevToolsClientHost* client_host, const base::Closure& dismissed_callback) { - ExtensionInfoBars::iterator it = - g_extension_info_bars.Get().find(extension_id); + auto it = g_extension_info_bars.Get().find(extension_id); ExtensionDevToolsInfoBar* infobar = nullptr; if (it != g_extension_info_bars.Get().end()) infobar = it->second;
diff --git a/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc b/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc index 87b0fca..400b45f 100644 --- a/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc +++ b/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc
@@ -311,7 +311,7 @@ std::vector<const void*> predicate_groups_to_stop_tracking; for (const std::string& id : rule_identifiers) { // Skip unknown rules. - RulesMap::iterator content_rules_entry = + auto content_rules_entry = content_rules_.find(std::make_pair(extension_id, id)); if (content_rules_entry == content_rules_.end()) continue; @@ -340,7 +340,7 @@ evaluator->StopTrackingPredicates(predicate_groups_to_stop_tracking); // Remove the rules. - for (RulesMap::iterator it : rules_to_erase) + for (auto it : rules_to_erase) content_rules_.erase(it); return std::string();
diff --git a/chrome/browser/extensions/api/declarative_content/content_action.cc b/chrome/browser/extensions/api/declarative_content/content_action.cc index 2e06299..28c8e52 100644 --- a/chrome/browser/extensions/api/declarative_content/content_action.cc +++ b/chrome/browser/extensions/api/declarative_content/content_action.cc
@@ -164,9 +164,7 @@ // Helper for getting JS collections into C++. static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings, std::vector<std::string>* append_to) { - for (base::ListValue::const_iterator it = append_strings.begin(); - it != append_strings.end(); - ++it) { + for (auto it = append_strings.begin(); it != append_strings.end(); ++it) { std::string value; if (it->GetAsString(&value)) { append_to->push_back(value); @@ -343,17 +341,15 @@ script_.set_run_location(UserScript::BROWSER_DRIVEN); script_.set_match_all_frames(script_data.all_frames); script_.set_match_about_blank(script_data.match_about_blank); - for (std::vector<std::string>::const_iterator it = - script_data.css_file_names.begin(); - it != script_data.css_file_names.end(); ++it) { + for (auto it = script_data.css_file_names.cbegin(); + it != script_data.css_file_names.cend(); ++it) { GURL url = extension->GetResourceURL(*it); ExtensionResource resource = extension->GetResource(*it); script_.css_scripts().push_back(std::make_unique<UserScript::File>( resource.extension_root(), resource.relative_path(), url)); } - for (std::vector<std::string>::const_iterator it = - script_data.js_file_names.begin(); - it != script_data.js_file_names.end(); ++it) { + for (auto it = script_data.js_file_names.cbegin(); + it != script_data.js_file_names.cend(); ++it) { GURL url = extension->GetResourceURL(*it); ExtensionResource resource = extension->GetResource(*it); script_.js_scripts().push_back(std::make_unique<UserScript::File>( @@ -436,8 +432,7 @@ } ContentActionFactory& factory = g_content_action_factory.Get(); - std::map<std::string, ContentActionFactory::FactoryMethod>::iterator - factory_method_iter = factory.factory_methods.find(instance_type); + auto factory_method_iter = factory.factory_methods.find(instance_type); if (factory_method_iter != factory.factory_methods.end()) return (*factory_method_iter->second)( browser_context, extension, action_dict, error);
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc index f12242e9..406f36bc 100644 --- a/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc +++ b/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc
@@ -200,8 +200,7 @@ continue; for (const DeclarativeContentCssPredicate* predicate : loc->second) { for (const std::string& selector : predicate->css_selectors()) { - std::map<std::string, int>::iterator loc = - watched_css_selector_predicate_count_.find(selector); + auto loc = watched_css_selector_predicate_count_.find(selector); DCHECK(loc != watched_css_selector_predicate_count_.end()); if (--loc->second == 0) { watched_css_selector_predicate_count_.erase(loc);
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc index fd60fff..289ccf9 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
@@ -52,9 +52,7 @@ CHECK(parsed_value->GetAsList(&parsed_list)); WebRequestActionSet::Values actions; - for (base::ListValue::const_iterator it = parsed_list->begin(); - it != parsed_list->end(); - ++it) { + for (auto it = parsed_list->begin(); it != parsed_list->end(); ++it) { const base::DictionaryValue* dict; CHECK(it->GetAsDictionary(&dict)); actions.push_back(dict->CreateDeepCopy()); @@ -590,10 +588,8 @@ std::unique_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kActions)); ASSERT_EQ(arraysize(kExpectedNames), action_set->actions().size()); size_t index = 0; - for (WebRequestActionSet::Actions::const_iterator it = - action_set->actions().begin(); - it != action_set->actions().end(); - ++it) { + for (auto it = action_set->actions().cbegin(); + it != action_set->actions().cend(); ++it) { EXPECT_EQ(kExpectedNames[index], (*it)->GetName()); ++index; }
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc index 8c01dd7..4ce1f72f 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc
@@ -223,9 +223,7 @@ rule->id.reset(new std::string(rule_id)); rule->priority.reset(new int(1)); rule->actions.push_back(action_dict.CreateDeepCopy()); - for (std::vector<const std::string*>::const_iterator it = - attributes.begin(); - it != attributes.end(); ++it) + for (auto it = attributes.cbegin(); it != attributes.cend(); ++it) rule->conditions.push_back(CreateCondition(**it)); return rule; } @@ -293,8 +291,7 @@ EXPECT_EQ(2u, matches.size()); std::set<WebRequestRule::GlobalRuleId> matches_ids; - for (std::set<const WebRequestRule*>::const_iterator it = matches.begin(); - it != matches.end(); ++it) + for (auto it = matches.cbegin(); it != matches.cend(); ++it) matches_ids.insert((*it)->id()); EXPECT_TRUE( base::ContainsKey(matches_ids, std::make_pair(kExtensionId, kRuleId1))); @@ -437,7 +434,7 @@ ASSERT_EQ(2u, deltas.size()); deltas.sort(&helpers::InDecreasingExtensionInstallationTimeOrder); - std::list<LinkedPtrEventResponseDelta>::iterator i = deltas.begin(); + auto i = deltas.begin(); LinkedPtrEventResponseDelta winner = *i++; LinkedPtrEventResponseDelta loser = *i;
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc index 29040b2..559b9c5c 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
@@ -242,7 +242,7 @@ void DesktopCaptureRequestsRegistry::CancelRequest(int process_id, int request_id) { - RequestsMap::iterator it = requests_.find(RequestId(process_id, request_id)); + auto it = requests_.find(RequestId(process_id, request_id)); if (it != requests_.end()) it->second->Cancel(); }
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc index bb3604b..73f82fe 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api.cc
@@ -498,8 +498,8 @@ if (sorter_types.Get().empty()) InitSortTypeMap(sorter_types.Pointer()); - for (std::vector<std::string>::const_iterator iter = order_by_strs.begin(); - iter != order_by_strs.end(); ++iter) { + for (auto iter = order_by_strs.cbegin(); iter != order_by_strs.cend(); + ++iter) { std::string term_str = *iter; if (term_str.empty()) continue; @@ -709,8 +709,7 @@ void DeterminerRemoved(const std::string& extension_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - for (DeterminerInfoVector::iterator iter = determiners_.begin(); - iter != determiners_.end();) { + for (auto iter = determiners_.begin(); iter != determiners_.end();) { if (iter->extension_id == extension_id) { iter = determiners_.erase(iter); } else { @@ -835,8 +834,7 @@ // This is safe to call even while not waiting for determiners to call back; // in that case, the callbacks will be null so they won't be Run. void CheckAllDeterminersCalled() { - for (DeterminerInfoVector::iterator iter = determiners_.begin(); - iter != determiners_.end(); ++iter) { + for (auto iter = determiners_.begin(); iter != determiners_.end(); ++iter) { if (!iter->reported) return; } @@ -1563,8 +1561,7 @@ BrowserList* browsers = BrowserList::GetInstance(); if (browsers) { - for (BrowserList::const_iterator iter = browsers->begin(); - iter != browsers->end(); ++iter) { + for (auto iter = browsers->begin(); iter != browsers->end(); ++iter) { const Browser* browser = *iter; DownloadCoreService* current_service = DownloadCoreServiceFactory::GetForBrowserContext(browser->profile()); @@ -1671,8 +1668,7 @@ void ExtensionDownloadsEventRouter::SetShelfEnabled(const Extension* extension, bool enabled) { - std::set<const Extension*>::iterator iter = - shelf_disabling_extensions_.find(extension); + auto iter = shelf_disabling_extensions_.find(extension); if (iter == shelf_disabling_extensions_.end()) { if (!enabled) shelf_disabling_extensions_.insert(extension); @@ -2052,8 +2048,7 @@ const Extension* extension, UnloadedExtensionReason reason) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - std::set<const Extension*>::iterator iter = - shelf_disabling_extensions_.find(extension); + auto iter = shelf_disabling_extensions_.find(extension); if (iter != shelf_disabling_extensions_.end()) shelf_disabling_extensions_.erase(iter); }
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index fa1ce8b4..24b6417 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -1163,9 +1163,7 @@ ASSERT_FALSE(base::PathExists(fake_path)); } - for (DownloadManager::DownloadVector::iterator iter = all_downloads.begin(); - iter != all_downloads.end(); - ++iter) { + for (auto iter = all_downloads.begin(); iter != all_downloads.end(); ++iter) { std::string result_string; // Use a MockIconExtractorImpl to test if the correct path is being passed // into the DownloadFileIconExtractor. @@ -4196,8 +4194,7 @@ EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); DownloadManager::DownloadVector items; manager->GetAllDownloads(&items); - for (DownloadManager::DownloadVector::iterator iter = items.begin(); - iter != items.end(); ++iter) { + for (auto iter = items.begin(); iter != items.end(); ++iter) { if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) { // There should be only one IN_PROGRESS item. EXPECT_EQ(NULL, item);
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc index 5813659a7..4c3d57a3 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc
@@ -148,7 +148,7 @@ stub_install_attributes_.SetCloudManaged("google.com", "device_id"); - settings_helper_.ReplaceProvider(chromeos::kDeviceAttestationEnabled); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, true); }
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc index 2f3082f..66448402 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc
@@ -169,7 +169,7 @@ stub_install_attributes_.SetCloudManaged("google.com", "device_id"); - settings_helper_.ReplaceProvider(chromeos::kDeviceAttestationEnabled); + settings_helper_.ReplaceDeviceSettingsProviderWithStub(); settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, true); }
diff --git a/chrome/browser/extensions/api/file_system/file_system_apitest.cc b/chrome/browser/extensions/api/file_system/file_system_apitest.cc index f9d07854..1be4cd8b 100644 --- a/chrome/browser/extensions/api/file_system/file_system_apitest.cc +++ b/chrome/browser/extensions/api/file_system/file_system_apitest.cc
@@ -118,9 +118,8 @@ "test_temp", temp_dir_.GetPath()); std::vector<base::FilePath> result; - for (std::vector<std::string>::const_iterator it = - destination_names.begin(); - it != destination_names.end(); ++it) { + for (auto it = destination_names.cbegin(); it != destination_names.cend(); + ++it) { base::FilePath destination = temp_dir_.GetPath().AppendASCII(*it); if (copy_gold) { base::FilePath source = test_root_folder_.AppendASCII("gold.txt");
diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chrome/browser/extensions/api/font_settings/font_settings_api.cc index e43333db..483d0a9 100644 --- a/chrome/browser/extensions/api/font_settings/font_settings_api.cc +++ b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
@@ -281,8 +281,7 @@ bool FontSettingsGetFontListFunction::CopyFontsToResult( base::ListValue* fonts) { std::unique_ptr<base::ListValue> result(new base::ListValue()); - for (base::ListValue::iterator it = fonts->begin(); - it != fonts->end(); ++it) { + for (auto it = fonts->begin(); it != fonts->end(); ++it) { base::ListValue* font_list_value; if (!it->GetAsList(&font_list_value)) { NOTREACHED();
diff --git a/chrome/browser/extensions/api/gcm/gcm_api.cc b/chrome/browser/extensions/api/gcm/gcm_api.cc index b2c1e5c..d003884 100644 --- a/chrome/browser/extensions/api/gcm/gcm_api.cc +++ b/chrome/browser/extensions/api/gcm/gcm_api.cc
@@ -203,8 +203,7 @@ bool GcmSendFunction::ValidateMessageData(const gcm::MessageData& data) const { size_t total_size = 0u; - for (std::map<std::string, std::string>::const_iterator iter = data.begin(); - iter != data.end(); ++iter) { + for (auto iter = data.cbegin(); iter != data.cend(); ++iter) { total_size += iter->first.size() + iter->second.size(); if (!IsMessageKeyValid(iter->first) ||
diff --git a/chrome/browser/extensions/api/identity/extension_token_key_unittest.cc b/chrome/browser/extensions/api/identity/extension_token_key_unittest.cc index 80b3858..aaedbd3b 100644 --- a/chrome/browser/extensions/api/identity/extension_token_key_unittest.cc +++ b/chrome/browser/extensions/api/identity/extension_token_key_unittest.cc
@@ -63,7 +63,7 @@ // comparison should establish an ordering std::sort(keys.begin(), keys.end()); for (ExtensionTokenKeyIterator it1 = keys.begin(); it1 != keys.end(); ++it1) { - ExtensionTokenKeyIterator it2 = it1; + auto it2 = it1; for (++it2; it2 != keys.end(); ++it2) { EXPECT_LT(*it1, *it2); EXPECT_FALSE(it2 < it1);
diff --git a/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc b/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc index 3c640ff8..cba30e91 100644 --- a/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc +++ b/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc
@@ -189,9 +189,7 @@ std::string error; std::string expiration; - for (base::StringPairs::iterator it = pairs.begin(); - it != pairs.end(); - ++it) { + for (auto it = pairs.begin(); it != pairs.end(); ++it) { if (it->first == kOAuth2RedirectAccessTokenKey) access_token = it->second; else if (it->first == kOAuth2RedirectErrorKey)
diff --git a/chrome/browser/extensions/api/identity/identity_api.cc b/chrome/browser/extensions/api/identity/identity_api.cc index 8d8e19d..0a600743 100644 --- a/chrome/browser/extensions/api/identity/identity_api.cc +++ b/chrome/browser/extensions/api/identity/identity_api.cc
@@ -107,7 +107,7 @@ void IdentityAPI::SetCachedToken(const ExtensionTokenKey& key, const IdentityTokenCacheValue& token_data) { - CachedTokens::iterator it = token_cache_.find(key); + auto it = token_cache_.find(key); if (it != token_cache_.end() && it->second.status() <= token_data.status()) token_cache_.erase(it);
diff --git a/chrome/browser/extensions/api/image_writer_private/operation_manager.cc b/chrome/browser/extensions/api/image_writer_private/operation_manager.cc index 037e29ae3..dffe7832 100644 --- a/chrome/browser/extensions/api/image_writer_private/operation_manager.cc +++ b/chrome/browser/extensions/api/image_writer_private/operation_manager.cc
@@ -59,9 +59,7 @@ } void OperationManager::Shutdown() { - for (OperationMap::iterator iter = operations_.begin(); - iter != operations_.end(); - iter++) { + for (auto iter = operations_.begin(); iter != operations_.end(); iter++) { scoped_refptr<Operation> operation = iter->second; operation->PostTask(base::BindOnce(&Operation::Abort, operation)); } @@ -77,7 +75,7 @@ // Chrome OS can only support a single operation at a time. if (operations_.size() > 0) { #else - OperationMap::iterator existing_operation = operations_.find(extension_id); + auto existing_operation = operations_.find(extension_id); if (existing_operation != operations_.end()) { #endif @@ -110,7 +108,7 @@ // Chrome OS can only support a single operation at a time. if (operations_.size() > 0) { #else - OperationMap::iterator existing_operation = operations_.find(extension_id); + auto existing_operation = operations_.find(extension_id); if (existing_operation != operations_.end()) { #endif @@ -144,7 +142,7 @@ const ExtensionId& extension_id, const std::string& device_path, Operation::StartWriteCallback callback) { - OperationMap::iterator existing_operation = operations_.find(extension_id); + auto existing_operation = operations_.find(extension_id); if (existing_operation != operations_.end()) { std::move(callback).Run(false, error::kOperationAlreadyInProgress); @@ -226,7 +224,7 @@ } Operation* OperationManager::GetOperation(const ExtensionId& extension_id) { - OperationMap::iterator existing_operation = operations_.find(extension_id); + auto existing_operation = operations_.find(extension_id); if (existing_operation == operations_.end()) return NULL; @@ -234,7 +232,7 @@ } void OperationManager::DeleteOperation(const ExtensionId& extension_id) { - OperationMap::iterator existing_operation = operations_.find(extension_id); + auto existing_operation = operations_.find(extension_id); if (existing_operation != operations_.end()) { operations_.erase(existing_operation); }
diff --git a/chrome/browser/extensions/api/mdns/mdns_api.cc b/chrome/browser/extensions/api/mdns/mdns_api.cc index e27d9f1..e20b7ae 100644 --- a/chrome/browser/extensions/api/mdns/mdns_api.cc +++ b/chrome/browser/extensions/api/mdns/mdns_api.cc
@@ -113,8 +113,8 @@ // mDNS unregistration is performed for difference(previous, cur). // The mDNS device list is refreshed if the listener count has grown for // a service type in union(cur, previous). - ServiceTypeCounts::iterator i_cur = current_service_counts.begin(); - ServiceTypeCounts::iterator i_prev = prev_service_counts_.begin(); + auto i_cur = current_service_counts.begin(); + auto i_prev = prev_service_counts_.begin(); while (i_cur != current_service_counts.end() || i_prev != prev_service_counts_.end()) { if (i_prev == prev_service_counts_.end() ||
diff --git a/chrome/browser/extensions/api/messaging/incognito_connectability.cc b/chrome/browser/extensions/api/messaging/incognito_connectability.cc index 325d811..dc425a3 100644 --- a/chrome/browser/extensions/api/messaging/incognito_connectability.cc +++ b/chrome/browser/extensions/api/messaging/incognito_connectability.cc
@@ -192,7 +192,7 @@ const GURL& origin, const ExtensionToOriginsMap& map) { DCHECK_EQ(origin, origin.GetOrigin()); - ExtensionToOriginsMap::const_iterator it = map.find(extension->id()); + auto it = map.find(extension->id()); return it != map.end() && it->second.count(origin) > 0; }
diff --git a/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc index 07d05cf7..7ddb9b9 100644 --- a/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc +++ b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc
@@ -109,7 +109,7 @@ return false; } allowed_origins_.ClearPatterns(); - for (base::ListValue::const_iterator it = allowed_origins_list->begin(); + for (auto it = allowed_origins_list->begin(); it != allowed_origins_list->end(); ++it) { std::string pattern_string; if (!it->GetAsString(&pattern_string)) {
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc index 66cfea4..c25a1ba 100644 --- a/chrome/browser/extensions/api/notifications/notifications_api.cc +++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -691,8 +691,8 @@ std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue()); - for (std::set<std::string>::iterator iter = notification_ids.begin(); - iter != notification_ids.end(); iter++) { + for (auto iter = notification_ids.begin(); iter != notification_ids.end(); + iter++) { result->SetKey(StripScopeFromIdentifier(extension_->id(), *iter), base::Value(true)); }
diff --git a/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc b/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc index 0df71bec..a4b84cd8 100644 --- a/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc +++ b/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc
@@ -72,8 +72,8 @@ std::vector<std::string>* permissions_list = permissions.permissions.get(); if (permissions_list) { PermissionsInfo* info = PermissionsInfo::GetInstance(); - for (std::vector<std::string>::iterator it = permissions_list->begin(); - it != permissions_list->end(); ++it) { + for (auto it = permissions_list->begin(); it != permissions_list->end(); + ++it) { // This is a compromise: we currently can't switch to a blend of // objects/strings all the way through the API. Until then, put this // processing here. @@ -127,8 +127,8 @@ URLPatternSet origins; if (permissions.origins.get()) { - for (std::vector<std::string>::iterator it = permissions.origins->begin(); - it != permissions.origins->end(); ++it) { + for (auto it = permissions.origins->begin(); + it != permissions.origins->end(); ++it) { int allowed_schemes = Extension::kValidHostPermissionSchemes; if (!allow_file_access) allowed_schemes &= ~URLPattern::SCHEME_FILE;
diff --git a/chrome/browser/extensions/api/preference/preference_api.cc b/chrome/browser/extensions/api/preference/preference_api.cc index 44cc6d7..15748c8 100644 --- a/chrome/browser/extensions/api/preference/preference_api.cc +++ b/chrome/browser/extensions/api/preference/preference_api.cc
@@ -246,7 +246,7 @@ std::string* browser_pref, APIPermission::ID* read_permission, APIPermission::ID* write_permission) { - PrefMap::iterator it = mapping_.find(extension_pref); + auto it = mapping_.find(extension_pref); if (it != mapping_.end()) { *browser_pref = it->second.pref_name; *read_permission = it->second.read_permission; @@ -259,7 +259,7 @@ bool FindEventForBrowserPref(const std::string& browser_pref, std::string* event_name, APIPermission::ID* permission) { - PrefMap::iterator it = event_mapping_.find(browser_pref); + auto it = event_mapping_.find(browser_pref); if (it != event_mapping_.end()) { *event_name = it->second.pref_name; *permission = it->second.read_permission;
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc index a523a80c..fc81b12 100644 --- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc +++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -73,8 +73,7 @@ window->set_window_id(window_id); window->set_selected_tab_index(0); window->set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED); - for (std::vector<int>::const_iterator iter = tab_list.begin(); - iter != tab_list.end(); ++iter) { + for (auto iter = tab_list.cbegin(); iter != tab_list.cend(); ++iter) { window->add_tab(*iter); } }
diff --git a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc index 75a6bba..9ab25558 100644 --- a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc +++ b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc
@@ -142,9 +142,8 @@ void SignedInDevicesManager::RemoveChangeObserverForExtension( const std::string& extension_id) { - for (std::vector<std::unique_ptr<SignedInDevicesChangeObserver>>::iterator - it = change_observers_.begin(); - it != change_observers_.end(); ++it) { + for (auto it = change_observers_.begin(); it != change_observers_.end(); + ++it) { if ((*it)->extension_id() == extension_id) { change_observers_.erase(it); return;
diff --git a/chrome/browser/extensions/api/storage/managed_value_store_cache.cc b/chrome/browser/extensions/api/storage/managed_value_store_cache.cc index 917b87f..420ffe2 100644 --- a/chrome/browser/extensions/api/storage/managed_value_store_cache.cc +++ b/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
@@ -302,8 +302,7 @@ return; const policy::PolicyMap empty_map; - for (policy::ComponentMap::const_iterator it = map->begin(); - it != map->end(); ++it) { + for (auto it = map->cbegin(); it != map->cend(); ++it) { const policy::PolicyNamespace ns(policy_domain_, it->first); // If there is no policy for |ns| then this will clear the previous store, // if there is one.
diff --git a/chrome/browser/extensions/api/storage/policy_value_store.cc b/chrome/browser/extensions/api/storage/policy_value_store.cc index 484182e..a431343 100644 --- a/chrome/browser/extensions/api/storage/policy_value_store.cc +++ b/chrome/browser/extensions/api/storage/policy_value_store.cc
@@ -40,8 +40,7 @@ // Convert |policy| to a dictionary value. Only include mandatory policies // for now. base::DictionaryValue current_policy; - for (policy::PolicyMap::const_iterator it = policy.begin(); - it != policy.end(); ++it) { + for (auto it = policy.begin(); it != policy.end(); ++it) { if (it->second.level == policy::POLICY_LEVEL_MANDATORY) { current_policy.SetWithoutPathExpansion( it->first, it->second.value->CreateDeepCopy());
diff --git a/chrome/browser/extensions/api/storage/settings_sync_processor.cc b/chrome/browser/extensions/api/storage/settings_sync_processor.cc index 9e880bd..e9566c9 100644 --- a/chrome/browser/extensions/api/storage/settings_sync_processor.cc +++ b/chrome/browser/extensions/api/storage/settings_sync_processor.cc
@@ -49,8 +49,7 @@ std::set<std::string> added_keys; std::set<std::string> deleted_keys; - for (ValueStoreChangeList::const_iterator i = changes.begin(); - i != changes.end(); ++i) { + for (auto i = changes.cbegin(); i != changes.cend(); ++i) { const std::string& key = i->key(); const base::Value* value = i->new_value(); if (value) { @@ -85,8 +84,7 @@ return error; synced_keys_.insert(added_keys.begin(), added_keys.end()); - for (std::set<std::string>::iterator i = deleted_keys.begin(); - i != deleted_keys.end(); ++i) { + for (auto i = deleted_keys.begin(); i != deleted_keys.end(); ++i) { synced_keys_.erase(*i); } @@ -97,8 +95,7 @@ DCHECK(IsOnBackendSequence()); CHECK(initialized_) << "Init not called"; - for (ValueStoreChangeList::const_iterator i = changes.begin(); - i != changes.end(); ++i) { + for (auto i = changes.cbegin(); i != changes.cend(); ++i) { if (i->new_value()) synced_keys_.insert(i->key()); else
diff --git a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc index 437fa0b1..7dcda11 100644 --- a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc +++ b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
@@ -115,8 +115,7 @@ "MockSyncChangeProcessor: configured to fail", change_list[0].sync_data().GetDataType()); } - for (syncer::SyncChangeList::const_iterator it = change_list.begin(); - it != change_list.end(); ++it) { + for (auto it = change_list.cbegin(); it != change_list.cend(); ++it) { changes_.push_back(std::make_unique<SettingSyncData>(*it)); } return syncer::SyncError(); @@ -231,8 +230,7 @@ syncer::SyncDataList as_list = GetSyncableService(model_type)->GetAllSyncData(model_type); SettingSyncDataMultimap as_map; - for (syncer::SyncDataList::iterator it = as_list.begin(); - it != as_list.end(); ++it) { + for (auto it = as_list.begin(); it != as_list.end(); ++it) { std::unique_ptr<SettingSyncData> sync_data(new SettingSyncData(*it)); std::unique_ptr<SettingSyncDataList>& list_for_extension = as_map[sync_data->extension_id()];
diff --git a/chrome/browser/extensions/api/storage/sync_storage_backend.cc b/chrome/browser/extensions/api/storage/sync_storage_backend.cc index ad8b2f5..477b091e 100644 --- a/chrome/browser/extensions/api/storage/sync_storage_backend.cc +++ b/chrome/browser/extensions/api/storage/sync_storage_backend.cc
@@ -75,7 +75,7 @@ std::unique_ptr<base::DictionaryValue> sync_data) const { DCHECK(IsOnBackendSequence()); - StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); + auto maybe_storage = storage_objs_.find(extension_id); if (maybe_storage != storage_objs_.end()) { return maybe_storage->second.get(); } @@ -115,7 +115,7 @@ // exists) since the storage area may have been unloaded, but we still want // to clear the data from disk. // However, this triggers http://crbug.com/111072. - StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); + auto maybe_storage = storage_objs_.find(extension_id); if (maybe_storage == storage_objs_.end()) return; maybe_storage->second->Clear(); @@ -149,8 +149,7 @@ std::set<std::string> known_extension_ids( GetKnownExtensionIDs(ToFactoryModelType(type))); - for (std::set<std::string>::const_iterator it = known_extension_ids.begin(); - it != known_extension_ids.end(); + for (auto it = known_extension_ids.cbegin(); it != known_extension_ids.cend(); ++it) { ValueStore::ReadResult maybe_settings = GetOrCreateStorageWithSyncData(*it, EmptyDictionaryValue())->Get();
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.cc b/chrome/browser/extensions/api/streams_private/streams_private_api.cc index 53c7404..1cb0524 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_api.cc +++ b/chrome/browser/extensions/api/streams_private/streams_private_api.cc
@@ -166,14 +166,14 @@ void StreamsPrivateAPI::AbortStream(const std::string& extension_id, const GURL& stream_url, const base::Closure& callback) { - StreamMap::iterator extension_it = streams_.find(extension_id); + auto extension_it = streams_.find(extension_id); if (extension_it == streams_.end()) { callback.Run(); return; } StreamMap::mapped_type* url_map = &extension_it->second; - StreamMap::mapped_type::iterator url_it = url_map->find(stream_url); + auto url_it = url_map->find(stream_url); if (url_it == url_map->end()) { callback.Run(); return;
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc index 089c9f2..541b41d 100644 --- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc +++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
@@ -292,8 +292,8 @@ // autogenerated Results::Create function thinks the enum values should be // returned as int values. std::unique_ptr<base::ListValue> status_array(new base::ListValue()); - for (URLToStatusMap::iterator it = file_sync_statuses_.begin(); - it != file_sync_statuses_.end(); ++it) { + for (auto it = file_sync_statuses_.begin(); it != file_sync_statuses_.end(); + ++it) { std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); storage::FileSystemURL url = it->first;
diff --git a/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc b/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc index eacadc7..baa15574 100644 --- a/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc +++ b/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
@@ -163,21 +163,20 @@ bool SystemIndicatorManager::SendClickEventToExtensionForTest( const std::string& extension_id) { - extensions::SystemIndicatorManager::SystemIndicatorMap::iterator it = - system_indicators_.find(extension_id); + auto it = system_indicators_.find(extension_id); - if (it == system_indicators_.end()) - return false; + if (it == system_indicators_.end()) + return false; - it->second->OnStatusIconClicked(); - return true; + it->second->OnStatusIconClicked(); + return true; } void SystemIndicatorManager::CreateOrUpdateIndicator( const Extension* extension, ExtensionAction* extension_action) { DCHECK(thread_checker_.CalledOnValidThread()); - SystemIndicatorMap::iterator it = system_indicators_.find(extension->id()); + auto it = system_indicators_.find(extension->id()); if (it != system_indicators_.end()) { it->second->OnIconUpdated(); return;
diff --git a/chrome/browser/extensions/api/tab_capture/offscreen_tabs_owner.cc b/chrome/browser/extensions/api/tab_capture/offscreen_tabs_owner.cc index 202e849c..e12a300 100644 --- a/chrome/browser/extensions/api/tab_capture/offscreen_tabs_owner.cc +++ b/chrome/browser/extensions/api/tab_capture/offscreen_tabs_owner.cc
@@ -101,9 +101,7 @@ } void OffscreenTabsOwner::DestroyTab(OffscreenTab* tab) { - for (std::vector<std::unique_ptr<OffscreenTab>>::iterator iter = - tabs_.begin(); - iter != tabs_.end(); ++iter) { + for (auto iter = tabs_.begin(); iter != tabs_.end(); ++iter) { if (iter->get() == tab) { tabs_.erase(iter); break;
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc index 1101115..c7c82d22 100644 --- a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc +++ b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
@@ -184,9 +184,7 @@ const Extension* extension, UnloadedExtensionReason reason) { // Cleanup all the requested media streams for this extension. - for (std::vector<std::unique_ptr<LiveRequest>>::iterator it = - requests_.begin(); - it != requests_.end();) { + for (auto it = requests_.begin(); it != requests_.end();) { if ((*it)->extension_id() == extension->id()) { it = requests_.erase(it); } else { @@ -345,9 +343,7 @@ } void TabCaptureRegistry::KillRequest(LiveRequest* request) { - for (std::vector<std::unique_ptr<LiveRequest>>::iterator it = - requests_.begin(); - it != requests_.end(); ++it) { + for (auto it = requests_.begin(); it != requests_.end(); ++it) { if (it->get() == request) { requests_.erase(it); return;
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index f75bb027..eea41e7 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -486,8 +486,7 @@ url_strings.swap(*create_data->url->as_strings); // Second, resolve, validate and convert them to GURLs. - for (std::vector<std::string>::iterator i = url_strings.begin(); - i != url_strings.end(); ++i) { + for (auto i = url_strings.begin(); i != url_strings.end(); ++i) { GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL(*i, extension()); if (!url.is_valid()) return RespondNow(Error(tabs_constants::kInvalidUrlError, *i));
diff --git a/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc b/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc index 182858b9..83335ff 100644 --- a/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc +++ b/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc
@@ -58,8 +58,7 @@ bool FrameNavigationState::CanSendEvents( content::RenderFrameHost* frame_host) const { - FrameHostToStateMap::const_iterator it = - frame_host_state_map_.find(frame_host); + auto it = frame_host_state_map_.find(frame_host); if (it == frame_host_state_map_.end() || it->second.error_occurred) { return false; } @@ -93,7 +92,7 @@ void FrameNavigationState::UpdateFrame(content::RenderFrameHost* frame_host, const GURL& url) { - FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); + auto it = frame_host_state_map_.find(frame_host); if (it == frame_host_state_map_.end()) { NOTREACHED(); return; @@ -107,8 +106,7 @@ } GURL FrameNavigationState::GetUrl(content::RenderFrameHost* frame_host) const { - FrameHostToStateMap::const_iterator it = - frame_host_state_map_.find(frame_host); + auto it = frame_host_state_map_.find(frame_host); if (it == frame_host_state_map_.end()) return GURL(); @@ -117,7 +115,7 @@ void FrameNavigationState::SetErrorOccurredInFrame( content::RenderFrameHost* frame_host) { - FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); + auto it = frame_host_state_map_.find(frame_host); if (it == frame_host_state_map_.end()) { NOTREACHED(); return; @@ -127,15 +125,14 @@ bool FrameNavigationState::GetErrorOccurredInFrame( content::RenderFrameHost* frame_host) const { - FrameHostToStateMap::const_iterator it = - frame_host_state_map_.find(frame_host); + auto it = frame_host_state_map_.find(frame_host); DCHECK(it != frame_host_state_map_.end()); return it == frame_host_state_map_.end() || it->second.error_occurred; } void FrameNavigationState::SetDocumentLoadCompleted( content::RenderFrameHost* frame_host) { - FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); + auto it = frame_host_state_map_.find(frame_host); if (it == frame_host_state_map_.end()) { NOTREACHED(); return; @@ -145,15 +142,14 @@ bool FrameNavigationState::GetDocumentLoadCompleted( content::RenderFrameHost* frame_host) const { - FrameHostToStateMap::const_iterator it = - frame_host_state_map_.find(frame_host); + auto it = frame_host_state_map_.find(frame_host); DCHECK(it != frame_host_state_map_.end()); return it == frame_host_state_map_.end() || !it->second.is_loading; } void FrameNavigationState::SetParsingFinished( content::RenderFrameHost* frame_host) { - FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); + auto it = frame_host_state_map_.find(frame_host); if (it == frame_host_state_map_.end()) { NOTREACHED(); return; @@ -163,8 +159,7 @@ bool FrameNavigationState::GetParsingFinished( content::RenderFrameHost* frame_host) const { - FrameHostToStateMap::const_iterator it = - frame_host_state_map_.find(frame_host); + auto it = frame_host_state_map_.find(frame_host); DCHECK(it != frame_host_state_map_.end()); return it == frame_host_state_map_.end() || !it->second.is_parsing; }
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc index c546379..7c61061 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -173,8 +173,7 @@ } void WebNavigationEventRouter::TabAdded(content::WebContents* tab) { - std::map<content::WebContents*, PendingWebContents>::iterator iter = - pending_web_contents_.find(tab); + auto iter = pending_web_contents_.find(tab); if (iter == pending_web_contents_.end()) return; @@ -199,8 +198,8 @@ void WebNavigationEventRouter::TabDestroyed(content::WebContents* tab) { pending_web_contents_.erase(tab); - for (std::map<content::WebContents*, PendingWebContents>::iterator i = - pending_web_contents_.begin(); i != pending_web_contents_.end(); ) { + for (auto i = pending_web_contents_.begin(); + i != pending_web_contents_.end();) { if (i->second.source_web_contents == tab) pending_web_contents_.erase(i++); else @@ -222,7 +221,7 @@ // static WebNavigationTabObserver* WebNavigationTabObserver::Get( content::WebContents* web_contents) { - TabObserverMap::iterator i = g_tab_observer.Get().find(web_contents); + auto i = g_tab_observer.Get().find(web_contents); return i == g_tab_observer.Get().end() ? NULL : i->second; } @@ -535,8 +534,7 @@ observer->frame_navigation_state(); std::vector<GetAllFrames::Results::DetailsType> result_list; - for (FrameNavigationState::const_iterator it = navigation_state.begin(); - it != navigation_state.end(); ++it) { + for (auto it = navigation_state.begin(); it != navigation_state.end(); ++it) { GURL frame_url = navigation_state.GetUrl(*it); if (!navigation_state.IsValidUrl(frame_url)) continue;
diff --git a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc index 5e25f25..a524f58 100644 --- a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
@@ -763,7 +763,7 @@ false); IPC::Message* message = NULL; - TestIPCSender::SentMessages::const_iterator i = ipc_sender_.sent_begin(); + auto i = ipc_sender_.sent_begin(); for (size_t test = 0; test < arraysize(kExpected); ++test) { SCOPED_TRACE(testing::Message("iteration number ") << test); EXPECT_NE(i, ipc_sender_.sent_end()); @@ -853,7 +853,7 @@ ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(id4, false); - TestIPCSender::SentMessages::const_iterator i = ipc_sender_.sent_begin(); + auto i = ipc_sender_.sent_begin(); for (size_t test = 0; test < arraysize(kExpected); ++test, ++i) { SCOPED_TRACE(testing::Message("iteration number ") << test); @@ -976,7 +976,7 @@ ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(id1, false); - TestIPCSender::SentMessages::const_iterator i = ipc_sender_.sent_begin(); + auto i = ipc_sender_.sent_begin(); for (size_t test = 0; test < arraysize(kMethods); ++test, ++i) { SCOPED_TRACE(testing::Message("iteration number ") << test); EXPECT_NE(i, ipc_sender_.sent_end());
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.h b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.h index 7e85f87..a9ce89f9 100644 --- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.h +++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/common/extensions/api/webrtc_audio_private.h" #include "content/public/browser/render_process_host.h"
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc index 38a7b32..6f90d46 100644 --- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc +++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -102,8 +102,7 @@ std::unique_ptr<WebstoreInstaller::Approval> PendingApprovals::PopApproval( Profile* profile, const std::string& id) { - for (ApprovalList::iterator iter = approvals_.begin(); - iter != approvals_.end(); ++iter) { + for (auto iter = approvals_.begin(); iter != approvals_.end(); ++iter) { if (iter->get()->extension_id == id && profile->IsSameProfile(iter->get()->profile)) { std::unique_ptr<WebstoreInstaller::Approval> approval = std::move(*iter);
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index e77c118..07f2ecf 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -308,13 +308,6 @@ "With this flag on, desktop share picker window will not let the user " "choose whether to share audio."; -const char kDisableIpcFloodingProtectionName[] = - "Disable IPC flooding protection"; -const char kDisableIpcFloodingProtectionDescription[] = - "Some javascript code can flood the inter process communication system. " - "This protection limits the rate (calls/seconds) at which theses function " - "can be used. This flag disables the protection."; - const char kDisablePushStateThrottleName[] = "Disable pushState throttling"; const char kDisablePushStateThrottleDescription[] = "Disables throttling of history.pushState and history.replaceState method "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 83b9668b..cb840554 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -219,9 +219,6 @@ extern const char kDisableAudioForDesktopShareName[]; extern const char kDisableAudioForDesktopShareDescription[]; -extern const char kDisableIpcFloodingProtectionName[]; -extern const char kDisableIpcFloodingProtectionDescription[]; - extern const char kDisablePushStateThrottleName[]; extern const char kDisablePushStateThrottleDescription[];
diff --git a/chrome/browser/media/media_engagement_session.cc b/chrome/browser/media/media_engagement_session.cc index 93b16e74..548b839 100644 --- a/chrome/browser/media/media_engagement_session.cc +++ b/chrome/browser/media/media_engagement_session.cc
@@ -166,6 +166,8 @@ MediaEngagementScore score = service_->CreateEngagementScore(origin_.GetURL()); ukm::builders::Media_Engagement_SessionFinished(ukm_source_id_) + .SetPlaybacks_AudioContextTotal(score.audio_context_playbacks()) + .SetPlaybacks_MediaElementTotal(score.media_element_playbacks()) .SetPlaybacks_Total(score.media_playbacks()) .SetVisits_Total(score.visits()) .SetEngagement_Score(round(score.actual_score() * 100))
diff --git a/chrome/browser/media/media_engagement_session_unittest.cc b/chrome/browser/media/media_engagement_session_unittest.cc index 61008b8..334933d 100644 --- a/chrome/browser/media/media_engagement_session_unittest.cc +++ b/chrome/browser/media/media_engagement_session_unittest.cc
@@ -707,6 +707,10 @@ auto* ukm_entry = ukm_entries[0]; test_ukm_recorder().ExpectEntrySourceHasUrl(ukm_entry, origin().GetURL()); + EXPECT_EQ(0, *test_ukm_recorder().GetEntryMetric( + ukm_entry, Entry::kPlaybacks_AudioContextTotalName)); + EXPECT_EQ(1, *test_ukm_recorder().GetEntryMetric( + ukm_entry, Entry::kPlaybacks_MediaElementTotalName)); EXPECT_EQ(1, *test_ukm_recorder().GetEntryMetric( ukm_entry, Entry::kPlaybacks_TotalName)); EXPECT_EQ(1, *test_ukm_recorder().GetEntryMetric(ukm_entry, @@ -733,8 +737,7 @@ ukm_entry, Entry::kEngagement_IsHigh_ChangedName)); } - SetSignificantMediaElementPlaybackRecordedForSession(session.get(), false); - session->RecordSignificantMediaElementPlayback(); + session->RecordSignificantAudioContextPlayback(); CommitPendingDataForSession(session.get()); RecordUkmMetricsForSession(session.get()); @@ -745,6 +748,10 @@ auto* ukm_entry = ukm_entries[1]; test_ukm_recorder().ExpectEntrySourceHasUrl(ukm_entry, origin().GetURL()); + EXPECT_EQ(1, *test_ukm_recorder().GetEntryMetric( + ukm_entry, Entry::kPlaybacks_AudioContextTotalName)); + EXPECT_EQ(1, *test_ukm_recorder().GetEntryMetric( + ukm_entry, Entry::kPlaybacks_MediaElementTotalName)); EXPECT_EQ(2, *test_ukm_recorder().GetEntryMetric( ukm_entry, Entry::kPlaybacks_TotalName)); EXPECT_EQ(1, *test_ukm_recorder().GetEntryMetric(ukm_entry,
diff --git a/chrome/browser/metrics/field_trial_synchronizer.cc b/chrome/browser/metrics/field_trial_synchronizer.cc index 385fc76c..cd17b03 100644 --- a/chrome/browser/metrics/field_trial_synchronizer.cc +++ b/chrome/browser/metrics/field_trial_synchronizer.cc
@@ -50,6 +50,12 @@ void FieldTrialSynchronizer::OnFieldTrialGroupFinalized( const std::string& field_trial_name, const std::string& group_name) { + // The FieldTrialSynchronizer may have been created before any BrowserThread + // is created, so we don't need to synchronize with child processes in which + // case there are no child processes to notify yet. + if (!content::BrowserThread::IsThreadInitialized(BrowserThread::UI)) + return; + base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&FieldTrialSynchronizer::NotifyAllRenderers, this,
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc index ff73cb7..cad7f59 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc
@@ -215,7 +215,8 @@ std::unique_ptr<data_reduction_proxy::DataReductionProxyService> service = std::make_unique<data_reduction_proxy::DataReductionProxyService>( - this, profile_prefs, request_context_getter, std::move(store), + this, profile_prefs, request_context_getter, url_loader_factory, + std::move(store), std::make_unique< data_reduction_proxy::DataReductionProxyPingbackClientImpl>( url_loader_factory, ui_task_runner),
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_unittest.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_unittest.cc index 0f0b754..23dd45b 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_unittest.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_unittest.cc
@@ -16,6 +16,7 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" #include "components/proxy_config/proxy_config_pref_names.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_;
diff --git a/chrome/browser/net/trial_comparison_cert_verifier.cc b/chrome/browser/net/trial_comparison_cert_verifier.cc index 2855b3d..352d1c9 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier.cc
@@ -54,10 +54,10 @@ const Profile* profile = reinterpret_cast<const Profile*>(profile_id); const PrefService& prefs = *profile->GetPrefs(); - // Only allow on non-incognito profiles which have SBER2 (Scout) opt-in set. + // Only allow on non-incognito profiles which have SBER opt-in set. // See design doc for more details: // https://docs.google.com/document/d/1AM1CD42bC6LHWjKg-Hkid_RLr2DH6OMzstH9-pGSi-g - return !profile->IsOffTheRecord() && safe_browsing::IsScout(prefs) && + return !profile->IsOffTheRecord() && safe_browsing::IsExtendedReportingEnabled(prefs); }
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index b825908e..d5476f6 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -1772,8 +1772,9 @@ #endif // defined(OS_MACOSX) -#if defined(OS_WIN) && defined(ADDRESS_SANITIZER) -// https://crbug.com/856169 +#if (defined(OS_WIN) && defined(ADDRESS_SANITIZER)) || \ + (defined(OS_CHROME) && defined(MEMORY_SANITIZER)) +// https://crbug.com/856169, https://crbug.com/892484 #define MAYBE_MouseLeave DISABLED_MouseLeave #else #define MAYBE_MouseLeave MouseLeave
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc index ca492f58..e45c9db 100644 --- a/chrome/browser/push_messaging/push_messaging_browsertest.cc +++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -182,8 +182,8 @@ // Calls should be wrapped in the ASSERT_NO_FATAL_FAILURE() macro. void RestartPushService() { Profile* profile = GetBrowser()->profile(); - PushMessagingServiceFactory::GetInstance()->SetTestingFactory(profile, - nullptr); + PushMessagingServiceFactory::GetInstance()->SetTestingFactory( + profile, BrowserContextKeyedServiceFactory::TestingFactory()); ASSERT_EQ(nullptr, PushMessagingServiceFactory::GetForProfile(profile)); PushMessagingServiceFactory::GetInstance()->RestoreFactoryForTests(profile); PushMessagingServiceImpl::InitializeForProfile(profile);
diff --git a/chrome/browser/push_messaging/push_messaging_service_factory.cc b/chrome/browser/push_messaging/push_messaging_service_factory.cc index 416961d6..342483e 100644 --- a/chrome/browser/push_messaging/push_messaging_service_factory.cc +++ b/chrome/browser/push_messaging/push_messaging_service_factory.cc
@@ -6,6 +6,8 @@ #include <memory> +#include "base/bind.h" +#include "base/memory/ptr_util.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" #include "chrome/browser/gcm/gcm_profile_service_factory.h" @@ -56,10 +58,11 @@ void PushMessagingServiceFactory::RestoreFactoryForTests( content::BrowserContext* context) { - SetTestingFactory(context, [](content::BrowserContext* context) { - return std::unique_ptr<KeyedService>( - GetInstance()->BuildServiceInstanceFor(context)); - }); + SetTestingFactory(context, + base::BindRepeating([](content::BrowserContext* context) { + return base::WrapUnique( + GetInstance()->BuildServiceInstanceFor(context)); + })); } KeyedService* PushMessagingServiceFactory::BuildServiceInstanceFor(
diff --git a/chrome/browser/push_messaging/push_messaging_service_unittest.cc b/chrome/browser/push_messaging/push_messaging_service_unittest.cc index 12cb1b6..cd79a4d 100644 --- a/chrome/browser/push_messaging/push_messaging_service_unittest.cc +++ b/chrome/browser/push_messaging/push_messaging_service_unittest.cc
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/bind.h" #include "base/command_line.h" #include "base/macros.h" #include "base/run_loop.h" @@ -97,7 +98,7 @@ // Override the GCM Profile service so that we can send fake messages. gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactory( - &profile_, &BuildFakeGCMProfileService); + &profile_, base::BindRepeating(&BuildFakeGCMProfileService)); } ~PushMessagingServiceTest() override {}
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc index f9e90bf8..6a58aad 100644 --- a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc +++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
@@ -513,30 +513,19 @@ return false; } - if (!GetTabSource()->tab_lifecycles_enterprise_policy()) { - decision_details->AddReason( - DecisionFailureReason::LIFECYCLES_ENTERPRISE_POLICY_OPT_OUT); - } + bool check_heuristics = !GetStaticProactiveTabFreezeAndDiscardParams() + .disable_heuristics_protections; - auto intervention_policy = - GetTabSource()->intervention_policy_database()->GetFreezingPolicy( - url::Origin::Create(web_contents()->GetLastCommittedURL())); - - switch (intervention_policy) { - case OriginInterventions::OPT_IN: - decision_details->AddReason(DecisionSuccessReason::GLOBAL_WHITELIST); - break; - case OriginInterventions::OPT_OUT: - decision_details->AddReason(DecisionFailureReason::GLOBAL_BLACKLIST); - break; - case OriginInterventions::DEFAULT: - break; - } + if (check_heuristics) + CanFreezeHeuristicsChecks(decision_details); if (web_contents()->GetVisibility() == content::Visibility::VISIBLE) decision_details->AddReason(DecisionFailureReason::LIVE_STATE_VISIBLE); - CheckIfTabIsUsedInBackground(decision_details, InterventionType::kProactive); + if (check_heuristics) { + CheckIfTabIsUsedInBackground(decision_details, + InterventionType::kProactive); + } if (decision_details->reasons().empty()) { decision_details->AddReason( @@ -598,31 +587,11 @@ } #endif - // We deliberately run through all of the logic without early termination. - // This ensures that the decision details lists all possible reasons that the - // transition can be denied. + bool check_heuristics = !GetStaticProactiveTabFreezeAndDiscardParams() + .disable_heuristics_protections; - if (!GetTabSource()->tab_lifecycles_enterprise_policy()) { - decision_details->AddReason( - DecisionFailureReason::LIFECYCLES_ENTERPRISE_POLICY_OPT_OUT); - } - - if (reason == LifecycleUnitDiscardReason::PROACTIVE) { - auto intervention_policy = - GetTabSource()->intervention_policy_database()->GetDiscardingPolicy( - url::Origin::Create(web_contents()->GetLastCommittedURL())); - - switch (intervention_policy) { - case OriginInterventions::OPT_IN: - decision_details->AddReason(DecisionSuccessReason::GLOBAL_WHITELIST); - break; - case OriginInterventions::OPT_OUT: - decision_details->AddReason(DecisionFailureReason::GLOBAL_BLACKLIST); - break; - case OriginInterventions::DEFAULT: - break; - } - } + if (check_heuristics) + CanDiscardHeuristicsChecks(decision_details, reason); #if defined(OS_CHROMEOS) if (web_contents()->GetVisibility() == content::Visibility::VISIBLE) @@ -650,10 +619,12 @@ DecisionFailureReason::LIVE_STATE_EXTENSION_DISALLOWED); } - CheckIfTabIsUsedInBackground(decision_details, - reason == LifecycleUnitDiscardReason::PROACTIVE - ? InterventionType::kProactive - : InterventionType::kExternalOrUrgent); + if (check_heuristics) { + CheckIfTabIsUsedInBackground(decision_details, + reason == LifecycleUnitDiscardReason::PROACTIVE + ? InterventionType::kProactive + : InterventionType::kExternalOrUrgent); + } if (decision_details->reasons().empty()) { decision_details->AddReason( @@ -980,4 +951,56 @@ } } +void TabLifecycleUnitSource::TabLifecycleUnit::CanFreezeHeuristicsChecks( + DecisionDetails* decision_details) const { + if (!GetTabSource()->tab_lifecycles_enterprise_policy()) { + decision_details->AddReason( + DecisionFailureReason::LIFECYCLES_ENTERPRISE_POLICY_OPT_OUT); + } + + auto intervention_policy = + GetTabSource()->intervention_policy_database()->GetFreezingPolicy( + url::Origin::Create(web_contents()->GetLastCommittedURL())); + + switch (intervention_policy) { + case OriginInterventions::OPT_IN: + decision_details->AddReason(DecisionSuccessReason::GLOBAL_WHITELIST); + break; + case OriginInterventions::OPT_OUT: + decision_details->AddReason(DecisionFailureReason::GLOBAL_BLACKLIST); + break; + case OriginInterventions::DEFAULT: + break; + } +} + +void TabLifecycleUnitSource::TabLifecycleUnit::CanDiscardHeuristicsChecks( + DecisionDetails* decision_details, + LifecycleUnitDiscardReason reason) const { + // We deliberately run through all of the logic without early termination. + // This ensures that the decision details lists all possible reasons that + // the transition can be denied. + if (!GetTabSource()->tab_lifecycles_enterprise_policy()) { + decision_details->AddReason( + DecisionFailureReason::LIFECYCLES_ENTERPRISE_POLICY_OPT_OUT); + } + + if (reason == LifecycleUnitDiscardReason::PROACTIVE) { + auto intervention_policy = + GetTabSource()->intervention_policy_database()->GetDiscardingPolicy( + url::Origin::Create(web_contents()->GetLastCommittedURL())); + + switch (intervention_policy) { + case OriginInterventions::OPT_IN: + decision_details->AddReason(DecisionSuccessReason::GLOBAL_WHITELIST); + break; + case OriginInterventions::OPT_OUT: + decision_details->AddReason(DecisionFailureReason::GLOBAL_BLACKLIST); + break; + case OriginInterventions::DEFAULT: + break; + } + } +} + } // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.h b/chrome/browser/resource_coordinator/tab_lifecycle_unit.h index c13f1a4..8a45e30 100644 --- a/chrome/browser/resource_coordinator/tab_lifecycle_unit.h +++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.h
@@ -172,6 +172,18 @@ void CheckIfTabIsUsedInBackground(DecisionDetails* decision_details, InterventionType intervention_type) const; + // Runs the freezing heuristics checks on this tab and store the decision + // details in |decision_details|. This doesn't check for potential background + // feature usage. + void CanFreezeHeuristicsChecks(DecisionDetails* decision_details) const; + + // Runs the discarding heuristics checks on this tab and store the decision + // details in |decision_details|. If |intervention_type| indicates that + // this is a proactive intervention then more heuristics will be + // applied. This doesn't check for potential background feature usage. + void CanDiscardHeuristicsChecks(DecisionDetails* decision_details, + LifecycleUnitDiscardReason reason) const; + // List of observers to notify when the discarded state or the auto- // discardable state of this tab changes. base::ObserverList<TabLifecycleObserver>::Unchecked* observers_;
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc index 3dabe14..135eedb 100644 --- a/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
@@ -832,4 +832,51 @@ EXPECT_NE(LifecycleUnitState::FROZEN, tab_lifecycle_unit.GetState()); } +TEST_F(TabLifecycleUnitTest, DisableHeuristicsFlag) { + TabLifecycleUnit tab_lifecycle_unit(GetSource(), &observers_, + usage_clock_.get(), web_contents_, + tab_strip_model_.get()); + TabLoadTracker::Get()->TransitionStateForTesting(web_contents_, + LoadingState::LOADED); + + DecisionDetails decision_details; + EXPECT_TRUE(tab_lifecycle_unit.CanFreeze(&decision_details)); + EXPECT_TRUE(decision_details.IsPositive()); + decision_details.Clear(); + + EXPECT_TRUE(tab_lifecycle_unit.CanDiscard( + LifecycleUnitDiscardReason::PROACTIVE, &decision_details)); + EXPECT_TRUE(decision_details.IsPositive()); + decision_details.Clear(); + + // Use one of the heuristics on the tab to prevent it from being discarded. + InterventionPolicyDatabase* policy_db = + TabLifecycleUnitSource::GetInstance()->intervention_policy_database(); + policy_db->AddOriginPoliciesForTesting( + url::Origin::Create(web_contents_->GetLastCommittedURL()), + {OriginInterventions::OPT_OUT, OriginInterventions::OPT_OUT}); + + EXPECT_FALSE(tab_lifecycle_unit.CanFreeze(&decision_details)); + EXPECT_FALSE(decision_details.IsPositive()); + decision_details.Clear(); + + EXPECT_FALSE(tab_lifecycle_unit.CanDiscard( + LifecycleUnitDiscardReason::PROACTIVE, &decision_details)); + EXPECT_FALSE(decision_details.IsPositive()); + decision_details.Clear(); + + // Disable the heuristics and check that the tab can now be safely discarded. + GetMutableStaticProactiveTabFreezeAndDiscardParamsForTesting() + ->disable_heuristics_protections = true; + + EXPECT_TRUE(tab_lifecycle_unit.CanFreeze(&decision_details)); + EXPECT_TRUE(decision_details.IsPositive()); + decision_details.Clear(); + + EXPECT_TRUE(tab_lifecycle_unit.CanDiscard( + LifecycleUnitDiscardReason::PROACTIVE, &decision_details)); + EXPECT_TRUE(decision_details.IsPositive()); + decision_details.Clear(); +} + } // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_manager_features.cc b/chrome/browser/resource_coordinator/tab_manager_features.cc index e44e75a..2126f42 100644 --- a/chrome/browser/resource_coordinator/tab_manager_features.cc +++ b/chrome/browser/resource_coordinator/tab_manager_features.cc
@@ -83,6 +83,8 @@ "ProactiveTabFreezeAndDiscard"; const char kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscardParam[] = "ShouldProactivelyDiscard"; +const char kProactiveTabFreezeAndDiscard_DisableHeuristicsParam[] = + "DisableHeuristicsProtections"; // Instantiate the feature parameters for proactive tab discarding. constexpr base::FeatureParam<bool> @@ -109,6 +111,8 @@ ProactiveTabFreezeAndDiscardParams::kUnfreezeTimeout; constexpr base::FeatureParam<int> ProactiveTabFreezeAndDiscardParams::kRefreezeTimeout; +constexpr base::FeatureParam<bool> + ProactiveTabFreezeAndDiscardParams::kDisableHeuristicsProtections; // Instantiate the feature parameters for the site characteristics database. constexpr base::FeatureParam<int> @@ -199,6 +203,9 @@ params.refreeze_timeout = base::TimeDelta::FromSeconds( ProactiveTabFreezeAndDiscardParams::kRefreezeTimeout.Get()); + params.disable_heuristics_protections = + ProactiveTabFreezeAndDiscardParams::kDisableHeuristicsProtections.Get(); + return params; }
diff --git a/chrome/browser/resource_coordinator/tab_manager_features.h b/chrome/browser/resource_coordinator/tab_manager_features.h index 590db23..9de4063 100644 --- a/chrome/browser/resource_coordinator/tab_manager_features.h +++ b/chrome/browser/resource_coordinator/tab_manager_features.h
@@ -32,6 +32,10 @@ // ProactiveTabFreezeAndDiscard feature. extern const char kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscardParam[]; +// The name of the |DisableHeuristicsProtections| parameter of the +// ProactiveTabFreezeAndDiscard feature. +extern const char kProactiveTabFreezeAndDiscard_DisableHeuristicsParam[]; + // Parameters used by the proactive tab discarding feature. // // Proactive discarding has 5 key parameters: @@ -125,6 +129,10 @@ &features::kProactiveTabFreezeAndDiscard, "RefreezeTimeout", base::TimeDelta::FromMinutes(10).InSeconds()}; + static constexpr base::FeatureParam<bool> kDisableHeuristicsProtections{ + &features::kProactiveTabFreezeAndDiscard, + kProactiveTabFreezeAndDiscard_DisableHeuristicsParam, false}; + // Whether tabs should be proactively discarded. When the // |kProactiveTabFreezeAndDiscard| feature is enabled and this is false, only // proactive tab freezing happens. @@ -162,6 +170,9 @@ base::TimeDelta unfreeze_timeout; // Amount of time that a tab stays unfrozen before being frozen again. base::TimeDelta refreeze_timeout; + // Disable all the heuristics protections when doing a freezing or discarding + // intervention. + bool disable_heuristics_protections; }; // Parameters used by the site characteristics database.
diff --git a/chrome/browser/resource_coordinator/tab_manager_features_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_features_unittest.cc index aa7af5c..7590377 100644 --- a/chrome/browser/resource_coordinator/tab_manager_features_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_features_unittest.cc
@@ -60,7 +60,8 @@ base::TimeDelta high_occluded_timeout, base::TimeDelta freeze_timeout, base::TimeDelta unfreeze_timeout, - base::TimeDelta refreeze_timeout) { + base::TimeDelta refreeze_timeout, + bool disable_heuristics_protections) { ProactiveTabFreezeAndDiscardParams params = GetProactiveTabFreezeAndDiscardParams(memory_in_gb); @@ -85,6 +86,9 @@ EXPECT_EQ(freeze_timeout, params.freeze_timeout); EXPECT_EQ(unfreeze_timeout, params.unfreeze_timeout); EXPECT_EQ(refreeze_timeout, params.refreeze_timeout); + + EXPECT_EQ(disable_heuristics_protections, + params.disable_heuristics_protections); } void ExpectSiteCharacteristicsDatabaseParams( @@ -163,8 +167,9 @@ base::TimeDelta::FromSeconds( ProactiveTabFreezeAndDiscardParams::kUnfreezeTimeout.default_value), base::TimeDelta::FromSeconds( - ProactiveTabFreezeAndDiscardParams::kRefreezeTimeout - .default_value)); + ProactiveTabFreezeAndDiscardParams::kRefreezeTimeout.default_value), + ProactiveTabFreezeAndDiscardParams::kDisableHeuristicsProtections + .default_value); } void ExpectDefaultSiteCharacteristicsDatabaseParams() { @@ -245,6 +250,9 @@ SetParam(ProactiveTabFreezeAndDiscardParams::kFreezeTimeout.name, "b"); SetParam(ProactiveTabFreezeAndDiscardParams::kUnfreezeTimeout.name, "i"); SetParam(ProactiveTabFreezeAndDiscardParams::kRefreezeTimeout.name, "m"); + SetParam( + ProactiveTabFreezeAndDiscardParams::kDisableHeuristicsProtections.name, + "bleh"); EnableProactiveTabFreezeAndDiscard(); ExpectDefaultProactiveTabFreezeAndDiscardParams(); } @@ -270,6 +278,9 @@ SetParam(ProactiveTabFreezeAndDiscardParams::kFreezeTimeout.name, "10"); SetParam(ProactiveTabFreezeAndDiscardParams::kUnfreezeTimeout.name, "20"); SetParam(ProactiveTabFreezeAndDiscardParams::kRefreezeTimeout.name, "30"); + SetParam( + ProactiveTabFreezeAndDiscardParams::kDisableHeuristicsProtections.name, + "true"); EnableProactiveTabFreezeAndDiscard(); // Should snap |moderate_loaded_tab_count| to |low_loaded_tab_count|, when the @@ -280,7 +291,7 @@ true, true, true, 7, 7, 42, memory_in_gb_low, base::TimeDelta::FromSeconds(60), base::TimeDelta::FromSeconds(120), base::TimeDelta::FromSeconds(247), base::TimeDelta::FromSeconds(10), - base::TimeDelta::FromSeconds(20), base::TimeDelta::FromSeconds(30)); + base::TimeDelta::FromSeconds(20), base::TimeDelta::FromSeconds(30), true); // Should snap |moderate_loaded_tab_count| to |high_loaded_tab_count|, when // the amount of physical memory is so high that (|memory_in_gb| * @@ -290,7 +301,7 @@ true, true, true, 7, 42, 42, memory_in_gb_high, base::TimeDelta::FromSeconds(60), base::TimeDelta::FromSeconds(120), base::TimeDelta::FromSeconds(247), base::TimeDelta::FromSeconds(10), - base::TimeDelta::FromSeconds(20), base::TimeDelta::FromSeconds(30)); + base::TimeDelta::FromSeconds(20), base::TimeDelta::FromSeconds(30), true); // Tests normal case where |memory_in gb| * |moderate_tab_count_per_gb_ram| is // in the interval [low_loaded_tab_count, high_loaded_tab_count]. @@ -299,7 +310,7 @@ true, true, true, 7, 16, 42, memory_in_gb_normal, base::TimeDelta::FromSeconds(60), base::TimeDelta::FromSeconds(120), base::TimeDelta::FromSeconds(247), base::TimeDelta::FromSeconds(10), - base::TimeDelta::FromSeconds(20), base::TimeDelta::FromSeconds(30)); + base::TimeDelta::FromSeconds(20), base::TimeDelta::FromSeconds(30), true); } TEST_F(TabManagerFeaturesTest,
diff --git a/chrome/browser/resources/omnibox/omnibox.js b/chrome/browser/resources/omnibox/omnibox.js index b6e4e6f..8b651d5a 100644 --- a/chrome/browser/resources/omnibox/omnibox.js +++ b/chrome/browser/resources/omnibox/omnibox.js
@@ -435,6 +435,7 @@ * call handleNewAutocompleteResult as results come in. */ makeRequest() { + clearOutput(); this.progressiveAutocompleteResults = []; // Then, call chrome with a five-element list: // - first element: the value in the text box
diff --git a/chrome/browser/resources/print_preview/new/app.js b/chrome/browser/resources/print_preview/new/app.js index fbcf518..0b6c223 100644 --- a/chrome/browser/resources/print_preview/new/app.js +++ b/chrome/browser/resources/print_preview/new/app.js
@@ -252,8 +252,8 @@ return; } - // On Mac, Cmd-. should close the print dialog. - if (cr.isMac && e.code == 'Minus' && e.metaKey) { + // On Mac, Cmd+Period should close the print dialog. + if (cr.isMac && e.code == 'Period' && e.metaKey) { this.close_(); e.preventDefault(); return;
diff --git a/chrome/browser/resources/print_preview/new/header.html b/chrome/browser/resources/print_preview/new/header.html index 09c61e8..4902440 100644 --- a/chrome/browser/resources/print_preview/new/header.html +++ b/chrome/browser/resources/print_preview/new/header.html
@@ -69,7 +69,7 @@ </if> <paper-button class="action-button" on-click="onPrintClick_" disabled$="[[!printButtonEnabled_]]"> - [[getPrintButton_(destination.id)]] + [[printButtonLabel_]] </paper-button> <if expr="is_win"> <paper-button class="cancel-button" on-click="onCancelClick_">
diff --git a/chrome/browser/resources/print_preview/new/header.js b/chrome/browser/resources/print_preview/new/header.js index f8aa32d..f521e2e 100644 --- a/chrome/browser/resources/print_preview/new/header.js +++ b/chrome/browser/resources/print_preview/new/header.js
@@ -24,12 +24,20 @@ /** @type {!print_preview_new.State} */ state: Number, - /** @private {boolean} */ + /** @private */ printButtonEnabled_: { type: Boolean, value: false, }, + /** @private */ + printButtonLabel_: { + type: String, + value: function() { + return loadTimeData.getString('printButton'); + }, + }, + /** @private {?string} */ summary_: { type: String, @@ -47,9 +55,11 @@ errorMessage: String, }, - observers: - ['update_(settings.copies.value, settings.duplex.value, ' + - 'settings.pages.value, state, destination.id)'], + observers: [ + 'update_(settings.copies.value, settings.duplex.value, ' + + 'settings.pages.value, state, destination.id)', + 'updatePrintButtonLabel_(destination.id)' + ], /** @private {!print_preview_new.State} */ lastState_: print_preview_new.State.NOT_READY, @@ -76,12 +86,9 @@ print_preview.Destination.GooglePromotedId.DOCS); }, - /** - * @return {string} - * @private - */ - getPrintButton_: function() { - return loadTimeData.getString( + /** @private */ + updatePrintButtonLabel_: function() { + this.printButtonLabel_ = loadTimeData.getString( this.isPdfOrDrive_() ? 'saveButton' : 'printButton'); },
diff --git a/chrome/browser/resources/print_preview/new/pages_settings.html b/chrome/browser/resources/print_preview/new/pages_settings.html index e41aeab9..668c09de 100644 --- a/chrome/browser/resources/print_preview/new/pages_settings.html +++ b/chrome/browser/resources/print_preview/new/pages_settings.html
@@ -55,6 +55,7 @@ disabled$="[[controlsDisabled_]]" name="[[pagesValueEnum_.CUSTOM]]" on-blur="onCustomRadioBlur_" + on-click="onCustomRadioClick_" aria-label="$i18n{optionCustomPages}"> <cr-input id="pageSettingsCustomInput" type="text" data-timeout-delay="500" on-keydown="onKeydown_"
diff --git a/chrome/browser/resources/print_preview/new/pages_settings.js b/chrome/browser/resources/print_preview/new/pages_settings.js index 07c2d9b..a300b01 100644 --- a/chrome/browser/resources/print_preview/new/pages_settings.js +++ b/chrome/browser/resources/print_preview/new/pages_settings.js
@@ -289,7 +289,7 @@ return; if (this.errorState_ === PagesInputErrorState.EMPTY) { - this.setSettingValid('pages', false); + this.setSettingValid('pages', true); this.$.pageSettingsCustomInput.invalid = false; return; } @@ -382,6 +382,12 @@ }, /** @private */ + onCustomRadioClick_: function() { + /** @type {!CrInputElement} */ (this.$.pageSettingsCustomInput) + .inputElement.focus(); + }, + + /** @private */ onControlsDisabledChanged_: function() { if (!this.controlsDisabled_) { if (this.optionSelected_ === PagesValue.CUSTOM)
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc index 1379f8e7..ed878a1 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -80,8 +80,8 @@ is_extended_reporting_opt_in_allowed, web_contents->GetBrowserContext()->IsOffTheRecord(), is_unified_consent_given, IsExtendedReportingEnabled(*prefs), - IsScout(*prefs), IsExtendedReportingPolicyManaged(*prefs), - is_proceed_anyway_disabled, + true, // is_scout_reporting_enabled, + IsExtendedReportingPolicyManaged(*prefs), is_proceed_anyway_disabled, true, // should_open_links_in_new_tab true, // always_show_back_to_safety kHelpCenterLink);
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 08c4f32..8a2b99c2 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -339,8 +339,8 @@ is_extended_reporting_opt_in_allowed, web_contents->GetBrowserContext()->IsOffTheRecord(), is_unified_consent_given, IsExtendedReportingEnabled(*prefs), - IsScout(*prefs), IsExtendedReportingPolicyManaged(*prefs), - is_proceed_anyway_disabled, + true, // is_scout_reporting_enabled + IsExtendedReportingPolicyManaged(*prefs), is_proceed_anyway_disabled, true, // should_open_links_in_new_tab false, // check_can_go_back_to_safety "cpn_safe_browsing" /* help_center_article_link */);
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc index 3653524..01089dd 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
@@ -127,8 +127,8 @@ is_extended_reporting_opt_in_allowed, web_contents->GetBrowserContext()->IsOffTheRecord(), is_unified_consent_given, IsExtendedReportingEnabled(*prefs), - IsScout(*prefs), IsExtendedReportingPolicyManaged(*prefs), - is_proceed_anyway_disabled, + true, // is_scout_reporting_enabled + IsExtendedReportingPolicyManaged(*prefs), is_proceed_anyway_disabled, true, // should_open_links_in_new_tab true, // always_show_back_to_safety "cpn_safe_browsing" /* help_center_article_link */); @@ -215,8 +215,8 @@ is_extended_reporting_opt_in_allowed, web_contents->GetBrowserContext()->IsOffTheRecord(), is_unified_consent_given, IsExtendedReportingEnabled(*prefs), - IsScout(*prefs), IsExtendedReportingPolicyManaged(*prefs), - is_proceed_anyway_disabled, + true, // is_scout_reporting_enabled + IsExtendedReportingPolicyManaged(*prefs), is_proceed_anyway_disabled, true, // should_open_links_in_new_tab true, // always_show_back_to_safety "cpn_safe_browsing" /* help_center_article_link */);
diff --git a/chrome/browser/ssl/captive_portal_helper_android.cc b/chrome/browser/ssl/captive_portal_helper_android.cc index 6ec1d41..8e69864 100644 --- a/chrome/browser/ssl/captive_portal_helper_android.cc +++ b/chrome/browser/ssl/captive_portal_helper_android.cc
@@ -14,6 +14,7 @@ #include "base/android/jni_string.h" #include "base/logging.h" #include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/ssl/ssl_error_assistant.h" #include "chrome/browser/ssl/ssl_error_handler.h" #include "content/public/browser/browser_thread.h" #include "jni/CaptivePortalHelper_jni.h" @@ -26,6 +27,13 @@ JNIEnv* env, const base::android::JavaParamRef<jclass>& jcaller, const base::android::JavaParamRef<jstring>& jhash) { + auto default_proto = + SSLErrorAssistant::GetErrorAssistantProtoFromResourceBundle(); + base::PostTaskWithTraits( + FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(SSLErrorHandler::SetErrorAssistantProto, + std::move(default_proto))); + const std::string hash = ConvertJavaStringToUTF8(env, jhash); auto config_proto = std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>();
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index 8963731..3a36371 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -190,7 +190,7 @@ const base::FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data"); -const uint32_t kLargeVersionId = 0xFFFFFFu; +const int kLargeVersionId = 0xFFFFFF; const char kHstsTestHostName[] = "hsts-example.test"; @@ -6641,6 +6641,7 @@ // the certificate issued by our server won't match. auto config_proto = std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>(); + config_proto->set_version_id(kLargeVersionId); chrome_browser_ssl::MITMSoftware* mitm_software = config_proto->add_mitm_software(); mitm_software->set_name(kTestMITMSoftwareName); @@ -6649,7 +6650,8 @@ mitm_software->set_issuer_organization_regex( "pattern-that-does-not-match-anything"); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); // Navigate to an unsafe page on the server. Mock out the URL host name to // equal the one set for HSTS. @@ -6687,6 +6689,7 @@ // the certificate issued by our server won't match. auto config_proto = std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>(); + config_proto->set_version_id(kLargeVersionId); chrome_browser_ssl::MITMSoftware* mitm_software = config_proto->add_mitm_software(); mitm_software->set_name(kTestMITMSoftwareName); @@ -6695,7 +6698,8 @@ mitm_software->set_issuer_organization_regex( https_server()->GetCertificate().get()->issuer().organization_names[0]); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); // Navigate to an unsafe page on the server. Mock out the URL host name to // equal the one set for HSTS. @@ -6731,6 +6735,7 @@ // the certificate issued by our server won't match. auto config_proto = std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>(); + config_proto->set_version_id(kLargeVersionId); chrome_browser_ssl::MITMSoftware* mitm_software = config_proto->add_mitm_software(); mitm_software->set_name("Non-Matching MITM Software"); @@ -6739,7 +6744,8 @@ mitm_software->set_issuer_organization_regex( "pattern-that-does-not-match-anything"); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); // Navigate to an unsafe page on the server. Mock out the URL host name to // equal the one set for HSTS. @@ -6876,6 +6882,10 @@ // update will be ignored and a non-MITM interstitial will be shown. IN_PROC_BROWSER_TEST_P(SSLUIMITMSoftwareEnabledTest, IgnoreDynamicUpdateWithSmallVersionId) { + auto config_proto = + SSLErrorAssistant::GetErrorAssistantProtoFromResourceBundle(); + SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); + SetUpCertVerifier(net::CERT_STATUS_AUTHORITY_INVALID); SSLErrorHandler::SetEnterpriseManagedForTesting(false); ASSERT_TRUE(SSLErrorHandler::IsEnterpriseManagedFlagSetForTesting()); @@ -7381,12 +7391,13 @@ { std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto = CreateSSLErrorAssistantConfig(); + config_proto->set_version_id(kLargeVersionId); AddMismatchDynamicInterstitial(config_proto.get()); AddMatchingDynamicInterstitial(config_proto.get()); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > - 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); WaitForInterstitial(tab); @@ -7409,6 +7420,7 @@ { std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto = CreateSSLErrorAssistantConfig(); + config_proto->set_version_id(kLargeVersionId); AddMismatchDynamicInterstitial(config_proto.get()); // Add a matching dynamic interstitial with the UNKNOWN_CERT_ERROR status. @@ -7418,8 +7430,8 @@ chrome_browser_ssl::DynamicInterstitial::UNKNOWN_CERT_ERROR); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > - 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); WaitForInterstitial(tab); @@ -7443,6 +7455,7 @@ { std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto = CreateSSLErrorAssistantConfig(); + config_proto->set_version_id(kLargeVersionId); AddMismatchDynamicInterstitial(config_proto.get()); // Add a matching dynamic interstitial with an empty issuer common name @@ -7452,8 +7465,8 @@ match->set_issuer_common_name_regex(std::string()); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > - 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); WaitForInterstitial(tab); @@ -7477,6 +7490,7 @@ { std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto = CreateSSLErrorAssistantConfig(); + config_proto->set_version_id(kLargeVersionId); AddMismatchDynamicInterstitial(config_proto.get()); // Add a matching dynamic interstitial with an empty issuer organization @@ -7486,8 +7500,8 @@ match->set_issuer_organization_regex(std::string()); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > - 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); WaitForInterstitial(tab); @@ -7510,6 +7524,7 @@ { std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto = CreateSSLErrorAssistantConfig(); + config_proto->set_version_id(kLargeVersionId); AddMismatchDynamicInterstitial(config_proto.get()); // Add a dynamic interstitial with matching fields, except for the @@ -7521,8 +7536,8 @@ match->add_sha256_hash("sha256/flowerpiercer"); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > - 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); WaitForInterstitial(tab); @@ -7544,6 +7559,7 @@ { std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto = CreateSSLErrorAssistantConfig(); + config_proto->set_version_id(kLargeVersionId); AddMismatchDynamicInterstitial(config_proto.get()); // Add a dynamic interstitial with matching fields, except for the @@ -7554,8 +7570,8 @@ chrome_browser_ssl::DynamicInterstitial::ERR_CERT_DATE_INVALID); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > - 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); WaitForInterstitial(tab); @@ -7577,6 +7593,7 @@ { std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto = CreateSSLErrorAssistantConfig(); + config_proto->set_version_id(kLargeVersionId); AddMismatchDynamicInterstitial(config_proto.get()); // Add a dynamic interstitial with matching fields, except for the @@ -7586,8 +7603,8 @@ match->set_issuer_common_name_regex("beeeater"); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > - 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); WaitForInterstitial(tab); @@ -7610,6 +7627,7 @@ { std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto = CreateSSLErrorAssistantConfig(); + config_proto->set_version_id(kLargeVersionId); AddMismatchDynamicInterstitial(config_proto.get()); // Add a dynamic interstitial with matching fields, except for the @@ -7619,8 +7637,8 @@ match->set_issuer_organization_regex("honeycreeper"); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > - 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); WaitForInterstitial(tab); @@ -7642,6 +7660,7 @@ { std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto = CreateSSLErrorAssistantConfig(); + config_proto->set_version_id(kLargeVersionId); AddMismatchDynamicInterstitial(config_proto.get()); // Add a matching dynamic interstitial, except for the @@ -7652,8 +7671,8 @@ chrome_browser_ssl::DynamicInterstitial::UNKNOWN_CERT_ERROR); SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto)); - ASSERT_TRUE(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting() > - 0); + ASSERT_EQ(SSLErrorHandler::GetErrorAssistantProtoVersionIdForTesting(), + kLargeVersionId); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); WaitForInterstitial(tab);
diff --git a/chrome/browser/ssl/ssl_error_assistant.cc b/chrome/browser/ssl/ssl_error_assistant.cc index 6b37592..9133c4c 100644 --- a/chrome/browser/ssl/ssl_error_assistant.cc +++ b/chrome/browser/ssl/ssl_error_assistant.cc
@@ -123,19 +123,6 @@ return dynamic_interstitial_list; } -// Reads the SSL error assistant configuration from the resource bundle. -std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> -ReadErrorAssistantProtoFromResourceBundle() { - auto proto = std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>(); - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(proto); - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - base::StringPiece data = - bundle.GetRawDataResource(IDR_SSL_ERROR_ASSISTANT_PB); - google::protobuf::io::ArrayInputStream stream(data.data(), data.size()); - return proto->ParseFromZeroCopyStream(&stream) ? std::move(proto) : nullptr; -} - bool RegexMatchesAny(const std::vector<std::string>& organization_names, const std::string& pattern) { const re2::RE2 regex(pattern); @@ -203,9 +190,10 @@ bool SSLErrorAssistant::IsKnownCaptivePortalCertificate( const net::SSLInfo& ssl_info) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + EnsureInitialized(); + CHECK(error_assistant_proto_); + if (!captive_portal_spki_hashes_) { - error_assistant_proto_ = ReadErrorAssistantProtoFromResourceBundle(); - CHECK(error_assistant_proto_); captive_portal_spki_hashes_ = LoadCaptivePortalCertHashes(*error_assistant_proto_); } @@ -219,10 +207,10 @@ // Load the dynamic interstitial data from SSL error assistant proto if it's // not already loaded. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!dynamic_interstitial_list_) { - if (!error_assistant_proto_) - error_assistant_proto_ = ReadErrorAssistantProtoFromResourceBundle(); + EnsureInitialized(); + CHECK(error_assistant_proto_); + if (!dynamic_interstitial_list_) { DCHECK(error_assistant_proto_); dynamic_interstitial_list_ = LoadDynamicInterstitialList(*error_assistant_proto_); @@ -270,11 +258,12 @@ return std::string(); } + EnsureInitialized(); + CHECK(error_assistant_proto_); + // Load MITM software data from the SSL error assistant proto. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (!mitm_software_list_) { - if (!error_assistant_proto_) - error_assistant_proto_ = ReadErrorAssistantProtoFromResourceBundle(); DCHECK(error_assistant_proto_); mitm_software_list_ = LoadMITMSoftwareList(*error_assistant_proto_); } @@ -322,21 +311,23 @@ return std::string(); } +// static +std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> +SSLErrorAssistant::GetErrorAssistantProtoFromResourceBundle() { + // Reads the SSL error assistant configuration from the resource bundle. + auto proto = std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>(); + DCHECK(proto); + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + base::StringPiece data = + bundle.GetRawDataResource(IDR_SSL_ERROR_ASSISTANT_PB); + google::protobuf::io::ArrayInputStream stream(data.data(), data.size()); + return proto->ParseFromZeroCopyStream(&stream) ? std::move(proto) : nullptr; +} + void SSLErrorAssistant::SetErrorAssistantProto( std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> proto) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); CHECK(proto); - if (!error_assistant_proto_) { - // If the user hasn't seen an SSL error and a component update is available, - // the local resource bundle won't have been read and error_assistant_proto_ - // will be null. It's possible that the local resource bundle has a higher - // version_id than the component updater component, so load the local - // resource bundle once to compare versions. - // TODO(meacer): Ideally, ReadErrorAssistantProtoFromResourceBundle should - // only be called once and not on the UI thread. Move the call to the - // component updater component. - error_assistant_proto_ = ReadErrorAssistantProtoFromResourceBundle(); - } // Ignore versions that are not new. INT_MAX is used by tests, so always allow // it. @@ -356,6 +347,11 @@ LoadDynamicInterstitialList(*error_assistant_proto_); } +void SSLErrorAssistant::EnsureInitialized() { + if (!error_assistant_proto_) + error_assistant_proto_ = GetErrorAssistantProtoFromResourceBundle(); +} + void SSLErrorAssistant::ResetForTesting() { error_assistant_proto_.reset(); mitm_software_list_.reset();
diff --git a/chrome/browser/ssl/ssl_error_assistant.h b/chrome/browser/ssl/ssl_error_assistant.h index a52d364..91c8354 100644 --- a/chrome/browser/ssl/ssl_error_assistant.h +++ b/chrome/browser/ssl/ssl_error_assistant.h
@@ -88,11 +88,18 @@ void SetErrorAssistantProto( std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> proto); + // Returns the SSL error assistant config stored in the resource bundle. This + // function is thread-safe and can safely be called multiple times. + static std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> + GetErrorAssistantProtoFromResourceBundle(); + // Testing methods: void ResetForTesting(); int GetErrorAssistantProtoVersionIdForTesting() const; private: + void EnsureInitialized(); + // SPKI hashes belonging to certs treated as captive portals. Null until the // first time ShouldDisplayCaptiveProtalInterstitial() or // SetErrorAssistantProto() is called.
diff --git a/chrome/browser/ssl/ssl_error_handler.cc b/chrome/browser/ssl/ssl_error_handler.cc index 8a66c87..fcd848d 100644 --- a/chrome/browser/ssl/ssl_error_handler.cc +++ b/chrome/browser/ssl/ssl_error_handler.cc
@@ -233,6 +233,7 @@ void SetErrorAssistantProto( std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> error_assistant_proto); + void SetEnterpriseManagedForTesting(bool enterprise_managed); bool IsEnterpriseManagedFlagSetForTesting() const; int GetErrorAssistantProtoVersionIdForTesting() const; @@ -726,6 +727,7 @@ return timer_.IsRunning(); } +// static void SSLErrorHandler::SetErrorAssistantProto( std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto) { g_config.Pointer()->SetErrorAssistantProto(std::move(config_proto));
diff --git a/chrome/browser/ssl/ssl_error_handler_unittest.cc b/chrome/browser/ssl/ssl_error_handler_unittest.cc index 59fc94b..a9c1ce5 100644 --- a/chrome/browser/ssl/ssl_error_handler_unittest.cc +++ b/chrome/browser/ssl/ssl_error_handler_unittest.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/captive_portal/captive_portal_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/common_name_mismatch_handler.h" +#include "chrome/browser/ssl/ssl_error_assistant.h" #include "chrome/browser/ssl/ssl_error_assistant.pb.h" #include "chrome/common/buildflags.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" @@ -368,6 +369,9 @@ void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); SSLErrorHandler::ResetConfigForTesting(); + SSLErrorHandler::SetErrorAssistantProto( + SSLErrorAssistant::GetErrorAssistantProtoFromResourceBundle()); + SSLErrorHandler::SetInterstitialDelayForTesting(base::TimeDelta()); ResetErrorHandlerFromFile(kOkayCertName, net::CERT_STATUS_COMMON_NAME_INVALID);
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc b/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc index 046ad14..9b47e55 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc
@@ -92,13 +92,6 @@ DoUpdateBoundsAndRedrawPopup(); GetWidget()->Show(); -#if defined(OS_MACOSX) - mac_bubble_closer_ = std::make_unique<ui::BubbleCloser>( - GetWidget()->GetNativeWindow(), - base::BindRepeating(&AutofillPopupBaseView::HideController, - base::Unretained(this))); -#endif - // Showing the widget can change native focus (which would result in an // immediate hiding of the popup). Only start observing after shown. if (initialize_widget)
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_base_view.h b/chrome/browser/ui/views/autofill/autofill_popup_base_view.h index 377f40c..846573c2 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_base_view.h +++ b/chrome/browser/ui/views/autofill/autofill_popup_base_view.h
@@ -15,10 +15,6 @@ #include "ui/views/widget/widget_delegate.h" #include "ui/views/widget/widget_observer.h" -#if defined(OS_MACOSX) -#include "ui/base/cocoa/bubble_closer.h" -#endif - namespace gfx { class Point; } @@ -128,13 +124,6 @@ // The time when the popup was shown. base::Time show_time_; -#if defined(OS_MACOSX) - // Special handler to close the popup on the Mac Cocoa browser. - // |parent_widget_| is null on that browser so we can't observe it for - // window changes. - std::unique_ptr<ui::BubbleCloser> mac_bubble_closer_; -#endif - base::WeakPtrFactory<AutofillPopupBaseView> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(AutofillPopupBaseView);
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc index 51520c6..5dc7740 100644 --- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
@@ -34,6 +34,7 @@ #include "services/service_manager/public/cpp/connector.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/events/test/event_generator.h" #include "ui/gfx/geometry/rect.h" @@ -836,6 +837,56 @@ DISALLOW_COPY_AND_ASSIGN(PageStateUpdateWaiter); }; +// Verifies that we ignore the shown ratios sent from widgets other than that of +// the main frame (such as widgets of the drop-down menus in web pages). +// https://crbug.com/891471. +IN_PROC_BROWSER_TEST_F(TopControlsSlideControllerTest, TestDropDowns) { + browser_view()->frame()->Maximize(); + ToggleTabletMode(); + ASSERT_TRUE(GetTabletModeEnabled()); + EXPECT_TRUE(top_controls_slide_controller()->IsEnabled()); + EXPECT_FLOAT_EQ(top_controls_slide_controller()->GetShownRatio(), 1.f); + + OpenUrlAtIndex(embedded_test_server()->GetURL("/top_controls_scroll.html"), + 0); + + // On mash, use nullptr root windows to route events over mojo to ash. + aura::Window* browser_window = browser()->window()->GetNativeWindow(); + ui::test::EventGenerator event_generator( + features::IsUsingWindowService() ? nullptr + : browser_window->GetRootWindow()); + + // Send a mouse click event that should open the popup drop-down menu of the + // <select> html element on the page. + // Note that if a non-main-frame widget is created, its LayerTreeHostImpl's + // `top_controls_shown_ratio_` (which is initialized to 0.f) will be sent to + // the browser when a new compositor frame gets generated. If this shown ratio + // value is not ignored, top-chrome will immediately hide, which will result + // in a BrowserView's Layout() and the immediate closure of the drop-down + // menu. + // We verify below that this doesn't happen, the menu remains open, and it's + // possible to select another option in the drop-down menu. + content::WebContents* contents = + browser()->tab_strip_model()->GetActiveWebContents(); + PageStateUpdateWaiter page_state_update_waiter(contents); + event_generator.MoveMouseTo(54, 173); + event_generator.ClickLeftButton(); + page_state_update_waiter.Wait(); + + // Verify that the element has been focused. + EXPECT_EQ(true, content::EvalJs(contents, "selectFocused;")); + + // Now send a mouse click event that should select the forth option in the + // drop-down menu. + event_generator.MoveMouseTo(54, 300); + event_generator.ClickLeftButton(); + + // Verify that the selected option has changed and the forth option is + // selected. + EXPECT_EQ(true, content::EvalJs(contents, "selectChanged;")); + EXPECT_EQ("4", content::EvalJs(contents, "getSelectedValue();")); +} + IN_PROC_BROWSER_TEST_F(TopControlsSlideControllerTest, TestScrollingMaximizedPageBeforeGoingToTabletMode) { // If the page exists in a maximized browser window before going to tablet
diff --git a/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc b/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc index 5d5acfd..a3562e8 100644 --- a/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc +++ b/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
@@ -102,11 +102,14 @@ return; } + // TODO(crbug.com/891905): Centralize powerwash restriction checks. policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); - bool allow_powerwash = !connector->IsEnterpriseManaged() && + bool allow_powerwash = + !connector->IsEnterpriseManaged() && !user_manager::UserManager::Get()->IsLoggedInAsGuest() && - !user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser(); + !user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser() && + !user_manager::UserManager::Get()->IsLoggedInAsChildUser(); if (!allow_powerwash) return;
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc index ea77a494..6de08a7 100644 --- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -82,12 +82,15 @@ ResetSettingsHandler* ResetSettingsHandler::Create( content::WebUIDataSource* html_source, Profile* profile) { #if defined(OS_CHROMEOS) + // TODO(crbug.com/891905): Centralize powerwash restriction checks. bool allow_powerwash = false; policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); - allow_powerwash = !connector->IsEnterpriseManaged() && + allow_powerwash = + !connector->IsEnterpriseManaged() && !user_manager::UserManager::Get()->IsLoggedInAsGuest() && - !user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser(); + !user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser() && + !user_manager::UserManager::Get()->IsLoggedInAsChildUser(); html_source->AddBoolean("allowPowerwash", allow_powerwash); #endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/usb/usb_chooser_controller_unittest.cc b/chrome/browser/usb/usb_chooser_controller_unittest.cc index 0e46bad..7932cd9a 100644 --- a/chrome/browser/usb/usb_chooser_controller_unittest.cc +++ b/chrome/browser/usb/usb_chooser_controller_unittest.cc
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/usb/usb_chooser_controller.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc index 58cd1d3..331f733 100644 --- a/chrome/browser/vr/ui.cc +++ b/chrome/browser/vr/ui.cc
@@ -73,6 +73,10 @@ return kExitPrompt; case UserFriendlyElementName::kSuggestionBox: return kOmniboxSuggestions; + case UserFriendlyElementName::kOmniboxTextField: + return kOmniboxTextField; + case UserFriendlyElementName::kOmniboxCloseButton: + return kOmniboxCloseButton; default: NOTREACHED(); return kNone;
diff --git a/chrome/browser/vr/ui_test_input.h b/chrome/browser/vr/ui_test_input.h index e38706e9..c6ef1ce7 100644 --- a/chrome/browser/vr/ui_test_input.h +++ b/chrome/browser/vr/ui_test_input.h
@@ -27,6 +27,9 @@ // menu kExitPrompt, // DOFF prompt/request to exit VR kSuggestionBox, // Box containing the omnibox suggestions + kOmniboxTextField, // The Omnibox's text input field that shows up when the + // URL bar is clicked. + kOmniboxCloseButton, // The button the exits the omnibox's text input mode. }; // These are the types of actions that Java can request callbacks for once
diff --git a/chrome/browser/win/jumplist.cc b/chrome/browser/win/jumplist.cc index 63aeb0f..1093c88 100644 --- a/chrome/browser/win/jumplist.cc +++ b/chrome/browser/win/jumplist.cc
@@ -862,8 +862,8 @@ int icons_created = 0; // Reuse icons for urls that already present in the current JumpList. - for (ShellLinkItemList::const_iterator iter = item_list.begin(); - iter != item_list.end() && max_items > 0; ++iter, --max_items) { + for (auto iter = item_list.begin(); iter != item_list.end() && max_items > 0; + ++iter, --max_items) { ShellLinkItem* item = iter->get(); auto cache_iter = icon_cur.find(item->url()); if (cache_iter != icon_cur.end()) {
diff --git a/chrome/test/data/top_controls_scroll/top_controls_scroll.html b/chrome/test/data/top_controls_scroll/top_controls_scroll.html index 282b883..94e4c1d 100644 --- a/chrome/test/data/top_controls_scroll/top_controls_scroll.html +++ b/chrome/test/data/top_controls_scroll/top_controls_scroll.html
@@ -10,9 +10,19 @@ background: linear-gradient(cyan, cyan 50%, blue 50%, blue); background-size: 100% 200px; } + select { + width: 100%; + height: 100px; + } </style> </head> <body> + <select id="select"> + <option value="1">1</option> + <option value="2">2</option> + <option value="3">3</option> + <option value="4">4</option> + </select> <h1>Browser Top Controls Scrolls Test Page</h1> <p> This page is used to test the browser top controls scroll behavior with page @@ -20,5 +30,28 @@ </p> <input id="editable-element" type="text"> <div></div> + + <script> + let selectFocused = false; + let selectChanged = false; + let selectElement = document.getElementById('select'); + + selectElement.onfocus = function() { + selectFocused = true; + }; + + selectElement.onblur = function() { + selectFocused = false; + }; + + selectElement.onchange = function() { + selectChanged = true; + }; + + function getSelectedValue() { + return selectElement.options[selectElement.selectedIndex].value; + } + </script> + </body> </html>
diff --git a/chrome/test/data/webui/print_preview/pages_settings_test.js b/chrome/test/data/webui/print_preview/pages_settings_test.js index 2435e011..25f5d88 100644 --- a/chrome/test/data/webui/print_preview/pages_settings_test.js +++ b/chrome/test/data/webui/print_preview/pages_settings_test.js
@@ -10,6 +10,7 @@ NupChangesPages: 'nup changes pages', ClearInput: 'clear input', TabOrder: 'tab order', + ClickingCustomFocusesInput: 'clicking custom focuses input', }; const suiteName = 'PagesSettingsTest'; @@ -277,7 +278,7 @@ .then(function() { assertEquals( pagesSection.pagesValueEnum_.CUSTOM, radioGroup.selected); - validateState([1, 2, 3], '', true); + validateState([1, 2, 3], '', false); const whenBlurred = test_util.eventToPromise('blur', input); input.blur(); return whenBlurred; @@ -383,6 +384,30 @@ validateTabOrder(true); }); }); + + test(assert(TestNames.ClickingCustomFocusesInput), function() { + const input = pagesSection.$.pageSettingsCustomInput.inputElement; + const radioGroup = pagesSection.$$('paper-radio-group'); + assertEquals(pagesSection.pagesValueEnum_.ALL, radioGroup.selected); + + // Click the custom input and set a valid value. + return setupInput('1-2', 3) + .then(function() { + // Blur the custom input. + const whenCustomInputBlurred = + test_util.eventToPromise('blur', input); + input.blur(); + Polymer.dom.flush(); + return whenCustomInputBlurred; + }) + .then(function() { + const whenCustomInputFocused = + test_util.eventToPromise('focus', input); + // Clicking the custom radio button should re-focus the input. + pagesSection.$.customRadioButton.click(); + return whenCustomInputFocused; + }); + }); }); return {
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index eddf5eb..8d252bd 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -1606,12 +1606,9 @@ ]), }; -// Failing on multiple builders. crbug.com/891955. -TEST_F( - 'CrSettingsLanguagesPageTest', 'DISABLED_AddLanguagesDialog', function() { - mocha.grep(assert(languages_page_tests.TestNames.AddLanguagesDialog)) - .run(); - }); +TEST_F('CrSettingsLanguagesPageTest', 'AddLanguagesDialog', function() { + mocha.grep(assert(languages_page_tests.TestNames.AddLanguagesDialog)).run(); +}); TEST_F('CrSettingsLanguagesPageTest', 'LanguageMenu', function() { mocha.grep(assert(languages_page_tests.TestNames.LanguageMenu)).run();
diff --git a/chrome/test/data/webui/settings/languages_page_tests.js b/chrome/test/data/webui/settings/languages_page_tests.js index 1e12758..ba007cb 100644 --- a/chrome/test/data/webui/settings/languages_page_tests.js +++ b/chrome/test/data/webui/settings/languages_page_tests.js
@@ -101,11 +101,13 @@ setup(function(done) { const addLanguagesButton = languagesCollapse.querySelector('#addLanguages'); + const whenDialogOpen = + test_util.eventToPromise('cr-dialog-open', languagesPage); addLanguagesButton.click(); // The page stamps the dialog, registers listeners, and populates the // iron-list asynchronously at microtask timing, so wait for a new task. - setTimeout(function() { + whenDialogOpen.then(() => { dialog = languagesPage.$$('settings-add-languages-dialog'); assertTrue(!!dialog); @@ -117,6 +119,7 @@ actionButton = assert(dialog.$$('.action-button')); cancelButton = assert(dialog.$$('.cancel-button')); + Polymer.dom.flush(); // The fixed-height dialog's iron-list should stamp far fewer than // 50 items.
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc index 6bc5adb5..2b99719 100644 --- a/chromeos/audio/cras_audio_handler.cc +++ b/chromeos/audio/cras_audio_handler.cc
@@ -17,7 +17,7 @@ #include "base/bind_helpers.h" #include "base/logging.h" #include "base/sys_info.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "chromeos/audio/audio_devices_pref_handler_stub.h" #include "chromeos/dbus/dbus_thread_manager.h"
diff --git a/chromeos/audio/cras_audio_handler_unittest.cc b/chromeos/audio/cras_audio_handler_unittest.cc index 29df317..3183c163 100644 --- a/chromeos/audio/cras_audio_handler_unittest.cc +++ b/chromeos/audio/cras_audio_handler_unittest.cc
@@ -14,7 +14,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/run_loop.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h"
diff --git a/components/app_modal/javascript_app_modal_dialog.cc b/components/app_modal/javascript_app_modal_dialog.cc index 04aefb5..20f1e3b8 100644 --- a/components/app_modal/javascript_app_modal_dialog.cc +++ b/components/app_modal/javascript_app_modal_dialog.cc
@@ -177,7 +177,7 @@ // The close callback above may delete web_contents_, thus removing the extra // data from the map owned by ::JavaScriptDialogManager. Make sure // to only use the data if still present. http://crbug.com/236476 - ExtraDataMap::iterator extra_data = extra_data_map_->find(web_contents_); + auto extra_data = extra_data_map_->find(web_contents_); if (extra_data != extra_data_map_->end()) { extra_data->second.has_already_shown_a_dialog_ = true; extra_data->second.suppress_javascript_messages_ = suppress_js_messages;
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 80a3413b2..732c9cc0 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -739,8 +739,7 @@ WebInputElement mutable_element = element; // We need a non-const. mutable_element.SetAutofillState(WebAutofillState::kNotFilled); - WebInputToPasswordInfoMap::iterator iter = - web_input_to_password_info_.find(element); + auto iter = web_input_to_password_info_.find(element); if (iter != web_input_to_password_info_.end()) { iter->second.password_was_edited_last = false; } @@ -763,7 +762,7 @@ ProvisionallySavePassword(element.Form(), element, RESTRICTION_NONE); if (element.IsPasswordFieldForAutofill()) { - PasswordToLoginMap::iterator iter = password_to_username_.find(element); + auto iter = password_to_username_.find(element); if (iter != password_to_username_.end()) { web_input_to_password_info_[iter->second].password_was_edited_last = true; // Note that the suggested value of |mutable_element| was reset when its @@ -937,8 +936,7 @@ *password_element = element; - WebInputToPasswordInfoMap::iterator iter = - web_input_to_password_info_.find(element); + auto iter = web_input_to_password_info_.find(element); if (iter == web_input_to_password_info_.end()) { PasswordToLoginMap::const_iterator password_iter = password_to_username_.find(element); @@ -962,8 +960,7 @@ // Otherwise |username_element| has been set above. } - WebInputToPasswordInfoMap::iterator iter = - web_input_to_password_info_.find(*username_element); + auto iter = web_input_to_password_info_.find(*username_element); if (iter == web_input_to_password_info_.end()) return false; @@ -1075,8 +1072,7 @@ // manager. See https://crbug.com/756587. WebLocalFrame* frame = render_frame()->GetWebFrame(); blink::WebURL url = frame->GetDocument().Url(); - if (url.ProtocolIs(url::kAboutScheme) || url.ProtocolIs(url::kBlobScheme) || - url.ProtocolIs(url::kFileSystemScheme)) + if (!url.ProtocolIs(url::kHttpScheme) && !url.ProtocolIs(url::kHttpsScheme)) return false; return frame->GetSecurityOrigin().CanAccessPasswordManager(); }
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index b8b64b4a..2376f29 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -263,6 +263,7 @@ "//base", "//base:i18n", "//components/data_use_measurement/core", + "//components/history/core/browser", "//components/infobars/core", "//components/keyed_service/core", "//components/leveldb_proto:leveldb_proto",
diff --git a/components/autofill/core/browser/DEPS b/components/autofill/core/browser/DEPS index 0399a2e..fb72964 100644 --- a/components/autofill/core/browser/DEPS +++ b/components/autofill/core/browser/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+components/data_use_measurement/core", "+components/grit/components_scaled_resources.h", + "+components/history/core/browser", "+components/infobars/core", "+components/keyed_service/core", "+components/leveldb_proto",
diff --git a/components/autofill/core/browser/address_rewriter.cc b/components/autofill/core/browser/address_rewriter.cc index 4cd255c..80d4d3a 100644 --- a/components/autofill/core/browser/address_rewriter.cc +++ b/components/autofill/core/browser/address_rewriter.cc
@@ -57,7 +57,7 @@ base::AutoLock auto_lock(lock_); // If we find a cached set of rules, return a pointer to the data. - CompiledRuleCache::iterator cache_iter = data_.find(region); + auto cache_iter = data_.find(region); if (cache_iter != data_.end()) return &cache_iter->second;
diff --git a/components/autofill/core/browser/autofill_data_util.cc b/components/autofill/core/browser/autofill_data_util.cc index 9bb74de..af02067 100644 --- a/components/autofill/core/browser/autofill_data_util.cc +++ b/components/autofill/core/browser/autofill_data_util.cc
@@ -112,7 +112,7 @@ // Removes common name prefixes from |name_tokens|. void StripPrefixes(std::vector<base::StringPiece16>* name_tokens) { - std::vector<base::StringPiece16>::iterator iter = name_tokens->begin(); + auto iter = name_tokens->begin(); while (iter != name_tokens->end()) { if (!ContainsString(name_prefixes, arraysize(name_prefixes), *iter)) break;
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc index 245ab7a..f6d37a513 100644 --- a/components/autofill/core/browser/autofill_download_manager.cc +++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -32,6 +32,7 @@ #include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/core/common/submission_source.h" #include "components/data_use_measurement/core/data_use_user_data.h" +#include "components/history/core/browser/history_service.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/variations/net/variations_http_headers.h" @@ -340,8 +341,8 @@ // Check for and returns true if |upload_event| is allowed to trigger an upload // for |form|. If true, updates |prefs| to track that |upload_event| has been // recorded for |form|. -bool IsUploadAllowed(const FormStructure& form, PrefService* prefs) { - if (!prefs || +bool IsUploadAllowed(const FormStructure& form, PrefService* pref_service) { + if (!pref_service || !base::FeatureList::IsEnabled(features::kAutofillUploadThrottling)) { return true; } @@ -350,17 +351,17 @@ static constexpr base::TimeDelta kResetPeriod = base::TimeDelta::FromDays(28); base::Time now = AutofillClock::Now(); base::Time last_reset = - prefs->GetTime(prefs::kAutofillUploadEventsLastResetTimestamp); + pref_service->GetTime(prefs::kAutofillUploadEventsLastResetTimestamp); if ((now - last_reset) > kResetPeriod) { - prefs->ClearPref(prefs::kAutofillUploadEvents); - prefs->SetTime(prefs::kAutofillUploadEventsLastResetTimestamp, now); + AutofillDownloadManager::ClearUploadHistory(pref_service); } // Get the key for the upload bucket and extract the current bitfield value. static constexpr size_t kNumUploadBuckets = 1021; std::string key = base::StringPrintf( "%03X", static_cast<int>(form.form_signature() % kNumUploadBuckets)); - auto* upload_events = prefs->GetDictionary(prefs::kAutofillUploadEvents); + auto* upload_events = + pref_service->GetDictionary(prefs::kAutofillUploadEvents); auto* found = upload_events->FindKeyOfType(key, base::Value::Type::INTEGER); int value = found ? found->GetInt() : 0; @@ -374,7 +375,7 @@ // pref to set the appropriate bit. bool allow_upload = ((value & mask) == 0); if (allow_upload) { - DictionaryPrefUpdate update(prefs, prefs::kAutofillUploadEvents); + DictionaryPrefUpdate update(pref_service, prefs::kAutofillUploadEvents); update->SetKey(std::move(key), base::Value(value | mask)); } @@ -480,6 +481,14 @@ return StartRequest(std::move(request_data)); } +void AutofillDownloadManager::ClearUploadHistory(PrefService* pref_service) { + if (pref_service) { + pref_service->ClearPref(prefs::kAutofillUploadEvents); + pref_service->SetTime(prefs::kAutofillUploadEventsLastResetTimestamp, + AutofillClock::Now()); + } +} + std::tuple<GURL, std::string> AutofillDownloadManager::GetRequestURLAndMethod( const FormRequestData& request_data) const { std::string method("POST");
diff --git a/components/autofill/core/browser/autofill_download_manager.h b/components/autofill/core/browser/autofill_download_manager.h index b51e3cc..77f36dc 100644 --- a/components/autofill/core/browser/autofill_download_manager.h +++ b/components/autofill/core/browser/autofill_download_manager.h
@@ -94,6 +94,11 @@ // Returns true if the autofill server communication is enabled. bool IsEnabled() const { return autofill_server_url_.is_valid(); } + // Reset the upload history. This reduced space history prevents the autofill + // download manager from uploading a multiple votes for a given form/event + // pair. + static void ClearUploadHistory(PrefService* pref_service); + private: friend class AutofillDownloadManagerTest; FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, QueryAndUploadTest);
diff --git a/components/autofill/core/browser/autofill_download_manager_unittest.cc b/components/autofill/core/browser/autofill_download_manager_unittest.cc index a7d2e25b..45a4430 100644 --- a/components/autofill/core/browser/autofill_download_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -1165,7 +1165,7 @@ } } -TEST_P(AutofillUploadTest, Reset) { +TEST_P(AutofillUploadTest, PeriodicReset) { ASSERT_NE(DISABLED, GetParam()); FormData form; @@ -1223,6 +1223,52 @@ 1, 2); } +TEST_P(AutofillUploadTest, ResetOnClearUploadHisotry) { + ASSERT_NE(DISABLED, GetParam()); + + FormData form; + FormFieldData field; + + field.label = ASCIIToUTF16("First Name:"); + field.name = ASCIIToUTF16("firstname"); + field.form_control_type = "text"; + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Last Name:"); + field.name = ASCIIToUTF16("lastname"); + field.form_control_type = "text"; + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Email:"); + field.name = ASCIIToUTF16("email"); + field.form_control_type = "text"; + form.fields.push_back(field); + + AutofillDownloadManager download_manager(driver_.get(), this); + SubmissionSource submission_source = SubmissionSource::FORM_SUBMISSION; + + FormStructure form_structure(form); + form_structure.set_submission_source(submission_source); + + base::HistogramTester histogram_tester; + + TestAutofillClock test_clock; + test_clock.SetNow(base::Time::Now()); + + // The first attempt should succeed. + EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true)); + + // Clear the upload throttling history. + AutofillDownloadManager::ClearUploadHistory(pref_service_.get()); + EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true)); + + // Two uploads were sent. + histogram_tester.ExpectBucketCount("Autofill.UploadEvent", 1, 2); + histogram_tester.ExpectBucketCount( + AutofillMetrics::SubmissionSourceToUploadEventMetric(submission_source), + 1, 2); +} + // Note that we omit DEFAULT_URL from the test params. We don't actually want // the tests to hit the production server. We also excluded DISABLED, since // these tests exercise "enabled" functionality.
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc index f78e4cf..246ac0ef 100644 --- a/components/autofill/core/browser/autofill_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -290,9 +290,13 @@ void SetUp() override { autofill_client_.SetPrefs(test::PrefServiceForTesting()); - personal_data_.Init(autofill_client_.GetDatabase(), nullptr, - autofill_client_.GetPrefs(), nullptr, - /*client_profile_validator=*/nullptr, false); + personal_data_.Init(/*profile_database=*/autofill_client_.GetDatabase(), + /*account_database=*/nullptr, + /*pref_service=*/autofill_client_.GetPrefs(), + /*identity_manager=*/nullptr, + /*client_profile_validator=*/nullptr, + /*history_service=*/nullptr, + /*is_off_the_record=*/false); personal_data_.SetPrefService(autofill_client_.GetPrefs()); autofill_driver_ = std::make_unique<testing::NiceMock<MockAutofillDriver>>(); @@ -2669,8 +2673,7 @@ FormData form; test::CreateTestAddressFormData(&form); // Mark the address fields as autofilled. - for (std::vector<FormFieldData>::iterator iter = form.fields.begin(); - iter != form.fields.end(); ++iter) { + for (auto iter = form.fields.begin(); iter != form.fields.end(); ++iter) { iter->is_autofilled = true; } @@ -2707,8 +2710,7 @@ // Now set the credit card fields to also be auto-filled, and try again to // fill the credit card data - for (std::vector<FormFieldData>::iterator iter = form.fields.begin(); - iter != form.fields.end(); ++iter) { + for (auto iter = form.fields.begin(); iter != form.fields.end(); ++iter) { iter->is_autofilled = true; } @@ -3773,8 +3775,7 @@ test::CreateTestAddressFormData(&form); // Remove the phone field -- we'll add it back later. - std::vector<FormFieldData>::iterator pos = - form.fields.begin() + kPhoneFieldOffset; + auto pos = form.fields.begin() + kPhoneFieldOffset; FormFieldData field = *pos; pos = form.fields.erase(pos);
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc index 1c948787..674909e 100644 --- a/components/autofill/core/browser/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -2799,6 +2799,7 @@ autofill_client_.GetPrefs(), /*identity_manager=*/nullptr, /*client_profile_validator=*/nullptr, + /*history_service=*/nullptr, /*is_off_the_record=*/false); histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", true, 1); } @@ -2812,6 +2813,7 @@ autofill_client_.GetPrefs(), /*identity_manager=*/nullptr, /*client_profile_validator=*/nullptr, + /*history_service=*/nullptr, /*is_off_the_record=*/false); histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", false, 1); }
diff --git a/components/autofill/core/browser/autofill_profile.cc b/components/autofill/core/browser/autofill_profile.cc index 94f9342..09a47d8 100644 --- a/components/autofill/core/browser/autofill_profile.cc +++ b/components/autofill/core/browser/autofill_profile.cc
@@ -1008,8 +1008,7 @@ std::vector<ServerFieldType> label_fields; bool found_differentiating_field = false; - for (std::vector<ServerFieldType>::const_iterator field = fields.begin(); - field != fields.end(); ++field) { + for (auto field = fields.begin(); field != fields.end(); ++field) { // Skip over empty fields. base::string16 field_text = profile->GetInfo(AutofillType(*field), app_locale);
diff --git a/components/autofill/core/browser/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/credit_card_save_manager_unittest.cc index 7e39b75..1f55f97 100644 --- a/components/autofill/core/browser/credit_card_save_manager_unittest.cc +++ b/components/autofill/core/browser/credit_card_save_manager_unittest.cc
@@ -104,9 +104,13 @@ public: void SetUp() override { autofill_client_.SetPrefs(test::PrefServiceForTesting()); - personal_data_.Init(autofill_client_.GetDatabase(), nullptr, - autofill_client_.GetPrefs(), nullptr, - /*client_profile_validator=*/nullptr, false); + personal_data_.Init(/*profile_database=*/autofill_client_.GetDatabase(), + /*account_database=*/nullptr, + /*pref_service=*/autofill_client_.GetPrefs(), + /*identity_manager=*/nullptr, + /*client_profile_validator=*/nullptr, + /*history_service=*/nullptr, + /*is_off_the_record=*/false); personal_data_.SetSyncServiceForTest(&sync_service_); autofill_driver_.reset(new TestAutofillDriver()); request_context_ = new net::TestURLRequestContextGetter(
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc index cedc101651..f6de5a3 100644 --- a/components/autofill/core/browser/form_data_importer_unittest.cc +++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -115,12 +115,15 @@ FormDataImporterTestBase() : autofill_table_(nullptr) {} void ResetPersonalDataManager(UserMode user_mode) { - bool is_incognito = (user_mode == USER_MODE_INCOGNITO); personal_data_manager_.reset(new PersonalDataManager("en")); personal_data_manager_->Init( scoped_refptr<AutofillWebDataService>(autofill_database_service_), - nullptr, prefs_.get(), nullptr, /*client_profile_validator=*/nullptr, - is_incognito); + /*account_database=*/nullptr, + /*pref_service=*/prefs_.get(), + /*identity_manager=*/nullptr, + /*client_profile_validator=*/nullptr, + /*history_service=*/nullptr, + /*is_off_the_record=*/(user_mode == USER_MODE_INCOGNITO)); personal_data_manager_->AddObserver(&personal_data_observer_); personal_data_manager_->OnSyncServiceInitialized(nullptr);
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 8f8ad97..84e5a8f 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -26,6 +26,7 @@ #include "components/autofill/core/browser/address_i18n.h" #include "components/autofill/core/browser/autofill-inl.h" #include "components/autofill/core/browser/autofill_country.h" +#include "components/autofill/core/browser/autofill_download_manager.h" #include "components/autofill/core/browser/autofill_experiments.h" #include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/autofill_metrics.h" @@ -43,6 +44,7 @@ #include "components/autofill/core/common/autofill_prefs.h" #include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/core/common/autofill_util.h" +#include "components/history/core/browser/history_service.h" #include "components/prefs/pref_service.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_service_utils.h" @@ -474,6 +476,7 @@ PrefService* pref_service, identity::IdentityManager* identity_manager, AutofillProfileValidator* client_profile_validator, + history::HistoryService* history_service, bool is_off_the_record) { CountryNames::SetLocaleString(app_locale_); database_helper_->Init(profile_database, account_database); @@ -487,6 +490,11 @@ base::BindRepeating(&PersonalDataManager::ResetProfileValidity, base::Unretained(this))); + // Listen for URL deletions from browsing history. + history_service_ = history_service; + if (history_service_) + history_service_->AddObserver(this); + identity_manager_ = identity_manager; is_off_the_record_ = is_off_the_record; @@ -523,8 +531,11 @@ void PersonalDataManager::Shutdown() { if (sync_service_) sync_service_->RemoveObserver(this); - sync_service_ = nullptr; + + if (history_service_) + history_service_->RemoveObserver(this); + history_service_ = nullptr; } void PersonalDataManager::OnSyncServiceInitialized( @@ -572,6 +583,14 @@ } } +void PersonalDataManager::OnURLsDeleted( + history::HistoryService* /* history_service */, + const history::DeletionInfo& deletion_info) { + if (!deletion_info.is_from_expiration() && deletion_info.IsAllHistory()) { + AutofillDownloadManager::ClearUploadHistory(pref_service_); + } +} + void PersonalDataManager::OnWebDataServiceRequestDone( WebDataServiceBase::Handle h, std::unique_ptr<WDTypedResult> result) { @@ -855,8 +874,7 @@ AutofillProfile* PersonalDataManager::GetProfileFromProfilesByGUID( const std::string& guid, const std::vector<AutofillProfile*>& profiles) { - std::vector<AutofillProfile*>::const_iterator iter = - FindElementByGUID<AutofillProfile>(profiles, guid); + auto iter = FindElementByGUID<AutofillProfile>(profiles, guid); return iter != profiles.end() ? *iter : nullptr; } @@ -1140,8 +1158,7 @@ CreditCard* PersonalDataManager::GetCreditCardByGUID(const std::string& guid) { const std::vector<CreditCard*>& credit_cards = GetCreditCards(); - std::vector<CreditCard*>::const_iterator iter = - FindElementByGUID<CreditCard>(credit_cards, guid); + auto iter = FindElementByGUID<CreditCard>(credit_cards, guid); return iter != credit_cards.end() ? *iter : nullptr; } @@ -2086,8 +2103,7 @@ // Take the most common country code. if (!votes.empty()) { - std::map<std::string, int>::iterator iter = - std::max_element(votes.begin(), votes.end(), CompareVotes); + auto iter = std::max_element(votes.begin(), votes.end(), CompareVotes); return iter->first; }
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h index e49b7a52..0071a2c 100644 --- a/components/autofill/core/browser/personal_data_manager.h +++ b/components/autofill/core/browser/personal_data_manager.h
@@ -28,6 +28,7 @@ #include "components/autofill/core/browser/suggestion.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h" +#include "components/history/core/browser/history_service_observer.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_member.h" @@ -69,6 +70,7 @@ class PersonalDataManager : public KeyedService, public WebDataServiceConsumer, public AutofillWebDataServiceObserverOnUISequence, + public history::HistoryServiceObserver, public syncer::SyncServiceObserver, public AccountInfoGetter { public: @@ -89,6 +91,7 @@ PrefService* pref_service, identity::IdentityManager* identity_manager, AutofillProfileValidator* client_profile_validator, + history::HistoryService* history_service, bool is_off_the_record); // KeyedService: @@ -98,6 +101,10 @@ // not be started, but it's preferences can be queried. virtual void OnSyncServiceInitialized(syncer::SyncService* sync_service); + // history::HistoryServiceObserver + void OnURLsDeleted(history::HistoryService* history_service, + const history::DeletionInfo& deletion_info) override; + // WebDataServiceConsumer: void OnWebDataServiceRequestDone( WebDataServiceBase::Handle h, @@ -720,6 +727,11 @@ // The PrefService that this instance uses. Must outlive this instance. PrefService* pref_service_ = nullptr; + // The HistoryService to observed by the personal data manager. Must + // outlive this instance. This unowned pointer is retained so the PDM can + // remove itself from the history service's observer list on shutdown. + history::HistoryService* history_service_ = nullptr; + // Pref registrar for managing the change observers. PrefChangeRegistrar pref_registrar_;
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 8dce199b..4342e71 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -179,7 +179,9 @@ ? scoped_refptr<AutofillWebDataService>(account_database_service_) : nullptr, prefs_.get(), identity_test_env_.identity_manager(), - TestAutofillProfileValidator::GetInstance(), is_incognito); + TestAutofillProfileValidator::GetInstance(), + /*history_service=*/nullptr, is_incognito); + personal_data_->AddObserver(&personal_data_observer_); sync_service_.SetIsAuthenticatedAccountPrimary(!use_account_server_storage); personal_data_->OnSyncServiceInitialized(&sync_service_);
diff --git a/components/autofill/core/browser/test_autofill_manager.cc b/components/autofill/core/browser/test_autofill_manager.cc index c8ac474..cadd9a6 100644 --- a/components/autofill/core/browser/test_autofill_manager.cc +++ b/components/autofill/core/browser/test_autofill_manager.cc
@@ -108,8 +108,7 @@ submitted_form->field(i)->possible_types(); EXPECT_EQ(expected_submitted_field_types_[i].size(), possible_types.size()); - for (ServerFieldTypeSet::const_iterator it = - expected_submitted_field_types_[i].begin(); + for (auto it = expected_submitted_field_types_[i].begin(); it != expected_submitted_field_types_[i].end(); ++it) { EXPECT_TRUE(possible_types.count(*it)) << "Expected type: " << AutofillType(*it).ToString();
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc index 34c3d98..d51108a 100644 --- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -103,8 +103,7 @@ const AutofillEntrySet& expected) { ASSERT_EQ(expected.size(), actual.size()); size_t count = 0; - for (AutofillEntrySet::const_iterator it = actual.begin(); - it != actual.end(); ++it) { + for (auto it = actual.begin(); it != actual.end(); ++it) { count += expected.count(*it); } EXPECT_EQ(actual.size(), count);
diff --git a/components/autofill/ios/browser/resources/autofill_controller.js b/components/autofill/ios/browser/resources/autofill_controller.js index 4798433..ec5477b 100644 --- a/components/autofill/ios/browser/resources/autofill_controller.js +++ b/components/autofill/ios/browser/resources/autofill_controller.js
@@ -269,8 +269,7 @@ __gCrWeb.form.getFormControlElements(form) : getUnownedAutofillableFormFieldElements_(document.all, /*fieldsets=*/[]); - for (var i = 0, delay = 0; i < controlElements.length; - ++i, delay += __gCrWeb.autofill.delayBetweenFieldFillingMs) { + for (var i = 0, delay = 0; i < controlElements.length; ++i) { var element = controlElements[i]; if (!__gCrWeb.fill.isAutofillableElement(element)) continue; @@ -313,6 +312,7 @@ }); }, _delay); })(element, fieldData.value, fieldData.section, delay); + delay += __gCrWeb.autofill.delayBetweenFieldFillingMs; } if (form) { @@ -361,8 +361,7 @@ } } - for (var i = 0, delay = 0; i < controlElements.length; - ++i, delay += __gCrWeb.autofill.delayBetweenFieldFillingMs) { + for (var i = 0, delay = 0; i < controlElements.length; ++i) { var element = controlElements[i]; if (!element.isAutofilled || element.disabled) continue; @@ -393,6 +392,7 @@ }); }, _delay); })(element, value, delay); + delay += __gCrWeb.autofill.delayBetweenFieldFillingMs; } } };
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index 22282e40a..06d055b3 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -30,6 +30,8 @@ "actions/reset_action.h", "actions/select_option_action.cc", "actions/select_option_action.h", + "actions/show_details_action.cc", + "actions/show_details_action.h", "actions/stop_action.cc", "actions/stop_action.h", "actions/tell_action.cc",
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index 6de2b49a..3089741 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -23,6 +23,7 @@ namespace autofill_assistant { class ClientMemory; +class DetailsProto; // Action delegate called when processing actions. class ActionDelegate { @@ -119,6 +120,12 @@ // Get associated web contents. virtual content::WebContents* GetWebContents() = 0; + // Hide contextual information. + virtual void HideDetails() = 0; + + // Show contextual information. + virtual void ShowDetails(const DetailsProto& details) = 0; + protected: ActionDelegate() = default; };
diff --git a/components/autofill_assistant/browser/actions/autofill_action.cc b/components/autofill_assistant/browser/actions/autofill_action.cc index 1e9e25c..4c8837d 100644 --- a/components/autofill_assistant/browser/actions/autofill_action.cc +++ b/components/autofill_assistant/browser/actions/autofill_action.cc
@@ -188,7 +188,6 @@ } if (guid.empty()) { - // User selected 'Fill manually'. delegate->StopCurrentScript(fill_form_message_); EndAction(/* successful= */ true); return;
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 4bcef6f..88103a4 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" +#include "components/autofill_assistant/browser/service.pb.h" #include "testing/gmock/include/gmock/gmock.h" namespace autofill_assistant { @@ -108,6 +109,8 @@ MOCK_METHOD0(GetPersonalDataManager, autofill::PersonalDataManager*()); MOCK_METHOD0(GetWebContents, content::WebContents*()); MOCK_METHOD1(StopCurrentScript, void(const std::string& message)); + MOCK_METHOD0(HideDetails, void()); + MOCK_METHOD1(ShowDetails, void(const DetailsProto& details)); }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/show_details_action.cc b/components/autofill_assistant/browser/actions/show_details_action.cc new file mode 100644 index 0000000..6dbc6ec1 --- /dev/null +++ b/components/autofill_assistant/browser/actions/show_details_action.cc
@@ -0,0 +1,31 @@ +// Copyright 2018 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_assistant/browser/actions/show_details_action.h" + +#include "base/callback.h" +#include "components/autofill_assistant/browser/actions/action_delegate.h" + +namespace autofill_assistant { + +ShowDetailsAction::ShowDetailsAction(const ActionProto& proto) : Action(proto) { + DCHECK(proto_.has_show_details()); +} + +ShowDetailsAction::~ShowDetailsAction() {} + +void ShowDetailsAction::ProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) { + if (!proto_.show_details().has_details()) { + delegate->HideDetails(); + } else { + delegate->ShowDetails(proto_.show_details().details()); + } + + processed_action_proto_ = std::make_unique<ProcessedActionProto>(); + UpdateProcessedAction(ACTION_APPLIED); + std::move(callback).Run(std::move(processed_action_proto_)); +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/show_details_action.h b/components/autofill_assistant/browser/actions/show_details_action.h new file mode 100644 index 0000000..0446327 --- /dev/null +++ b/components/autofill_assistant/browser/actions/show_details_action.h
@@ -0,0 +1,27 @@ +// Copyright 2018 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_ASSISTANT_BROWSER_ACTIONS_SHOW_DETAILS_ACTION_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_DETAILS_ACTION_H_ + +#include "base/macros.h" +#include "components/autofill_assistant/browser/actions/action.h" + +namespace autofill_assistant { +// An action to show contextual information. +class ShowDetailsAction : public Action { + public: + explicit ShowDetailsAction(const ActionProto& proto); + ~ShowDetailsAction() override; + + // Overrides Action: + void ProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ShowDetailsAction); +}; + +} // namespace autofill_assistant +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_DETAILS_ACTION_H_
diff --git a/components/autofill_assistant/browser/actions/wait_for_dom_action.cc b/components/autofill_assistant/browser/actions/wait_for_dom_action.cc index 5c9ab23..13eca47 100644 --- a/components/autofill_assistant/browser/actions/wait_for_dom_action.cc +++ b/components/autofill_assistant/browser/actions/wait_for_dom_action.cc
@@ -4,6 +4,7 @@ #include "components/autofill_assistant/browser/actions/wait_for_dom_action.h" +#include <algorithm> #include <cmath> #include "base/bind.h" @@ -44,7 +45,9 @@ int timeout_ms = proto_.wait_for_dom().timeout_ms(); if (timeout_ms > 0) - check_rounds = std::ceil(timeout_ms / kCheckPeriodInMilliseconds); + check_rounds = std::min( + 1, + static_cast<int>(std::ceil(timeout_ms / kCheckPeriodInMilliseconds))); CheckElementExists(delegate, check_rounds, std::move(callback)); } @@ -52,7 +55,7 @@ void WaitForDomAction::CheckElementExists(ActionDelegate* delegate, int rounds, ProcessActionCallback callback) { - DCHECK(rounds > 0); + DCHECK_GT(rounds, 0); std::vector<std::string> selectors; for (const auto& selector : proto_.wait_for_dom().selectors()) { selectors.emplace_back(selector); @@ -73,13 +76,14 @@ return; } - if (rounds == 0) { + --rounds; + if (rounds <= 0) { + DCHECK_EQ(rounds, 0); UpdateProcessedAction(ELEMENT_RESOLUTION_FAILED); std::move(callback).Run(std::move(processed_action_proto_)); return; } - --rounds; base::PostDelayedTaskWithTraits( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&WaitForDomAction::CheckElementExists,
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index bc5a3b5..b5c0d1e 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -104,7 +104,6 @@ } GetUiController()->SetUiDelegate(this); - GetUiController()->ShowOverlay(); if (!web_contents->IsLoading()) { GetOrCheckScripts(web_contents->GetLastCommittedURL()); }
diff --git a/components/autofill_assistant/browser/mock_ui_controller.h b/components/autofill_assistant/browser/mock_ui_controller.h index d02b43c4..0e363ae 100644 --- a/components/autofill_assistant/browser/mock_ui_controller.h +++ b/components/autofill_assistant/browser/mock_ui_controller.h
@@ -40,6 +40,8 @@ } MOCK_METHOD1(OnChooseCard, void(base::OnceCallback<void(const std::string&)>& callback)); + MOCK_METHOD0(HideDetails, void()); + MOCK_METHOD1(ShowDetails, void(const DetailsProto& details)); }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc index 074c742..975a4dd3 100644 --- a/components/autofill_assistant/browser/protocol_utils.cc +++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -14,6 +14,7 @@ #include "components/autofill_assistant/browser/actions/navigate_action.h" #include "components/autofill_assistant/browser/actions/reset_action.h" #include "components/autofill_assistant/browser/actions/select_option_action.h" +#include "components/autofill_assistant/browser/actions/show_details_action.h" #include "components/autofill_assistant/browser/actions/stop_action.h" #include "components/autofill_assistant/browser/actions/tell_action.h" #include "components/autofill_assistant/browser/actions/unsupported_action.h" @@ -199,6 +200,10 @@ actions->emplace_back(std::make_unique<UploadDomAction>(action)); break; } + case ActionProto::ActionInfoCase::kShowDetails: { + actions->emplace_back(std::make_unique<ShowDetailsAction>(action)); + break; + } default: case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: { DLOG(ERROR) << "Unknown or unsupported action with action_case="
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index cace7297..0094705 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -147,6 +147,14 @@ return delegate_->GetWebContents(); } +void ScriptExecutor::HideDetails() { + delegate_->GetUiController()->HideDetails(); +} + +void ScriptExecutor::ShowDetails(const DetailsProto& details) { + delegate_->GetUiController()->ShowDetails(details); +} + void ScriptExecutor::OnGetActions(bool result, const std::string& response) { if (!result) { RunCallback(false);
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index 2d32421..63410cf8 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -88,6 +88,8 @@ autofill::PersonalDataManager* GetPersonalDataManager() override; content::WebContents* GetWebContents() override; void StopCurrentScript(const std::string& message) override; + void HideDetails() override; + void ShowDetails(const DetailsProto& details) override; private: void OnGetActions(bool result, const std::string& response);
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 68771d2..1556a52 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -195,6 +195,7 @@ UseAddressProto use_address = 29; UploadDomProto upload_dom = 18; HighlightElementProto highlight_element = 31; + ShowDetailsProto show_details = 32; ResetProto reset = 34; StopProto stop = 35; } @@ -350,3 +351,44 @@ // Stop Autofill Assistant. message StopProto {} + +message DateProto { + optional int64 year = 1; + + // Month of the year in the range [1-12]. + optional int32 month = 2; + + // Day of the month in the range [1-31]. + optional int32 day = 3; +} + +message TimeProto { + // Hour in the range [0-23]. + optional int32 hour = 1; + + // Minute in the range [0-59]. + optional int32 minute = 2; + + // Second in the range [0-59]. + optional int32 second = 3; +} + +message DateTimeProto { + optional DateProto date = 1; + optional TimeProto time = 2; +} + +message DetailsProto { + optional string title = 1; + + optional string url = 2; + + optional DateTimeProto datetime = 3; + + optional string description = 4; +} + +// Show contextual information. +message ShowDetailsProto { + optional DetailsProto details = 1; +} \ No newline at end of file
diff --git a/components/autofill_assistant/browser/ui_controller.h b/components/autofill_assistant/browser/ui_controller.h index 3c35482..af5eaba 100644 --- a/components/autofill_assistant/browser/ui_controller.h +++ b/components/autofill_assistant/browser/ui_controller.h
@@ -14,6 +14,7 @@ namespace autofill_assistant { struct ScriptHandle; +class DetailsProto; // Controller to control autofill assistant UI. class UiController { @@ -56,6 +57,12 @@ virtual void ChooseCard( base::OnceCallback<void(const std::string&)> callback) = 0; + // Hide contextual information. + virtual void HideDetails() = 0; + + // Show contextual information. + virtual void ShowDetails(const DetailsProto& details) = 0; + protected: UiController() = default; };
diff --git a/components/autofill_assistant/browser/web_controller.cc b/components/autofill_assistant/browser/web_controller.cc index e743070..0525be4 100644 --- a/components/autofill_assistant/browser/web_controller.cc +++ b/components/autofill_assistant/browser/web_controller.cc
@@ -507,17 +507,14 @@ DLOG(ERROR) << "Failed to click the element for filling form."; OnResult(false, std::move(callback)); } - - std::vector<std::string> element_selectors = selectors; - DCHECK(element_selectors.size() > - element_result->container_frame_selector_index); - for (size_t i = element_result->container_frame_selector_index; i > 0; i++) { - element_selectors.erase(element_selectors.begin()); - } ContentAutofillDriver* driver = ContentAutofillDriver::GetForRenderFrameHost( element_result->container_frame_host); + DCHECK(!selectors.empty()); + // TODO(crbug.com/806868): Figure out whether there are cases where we need + // more than one selector, and come up with a solution that can figure out the + // right number of selectors to include. driver->GetAutofillAgent()->GetElementFormAndFieldData( - element_selectors, + std::vector<std::string>(1, selectors.back()), base::BindOnce(&WebController::OnGetFormAndFieldDataForFillingForm, weak_ptr_factory_.GetWeakPtr(), std::move(data_to_autofill), std::move(callback),
diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmarks/browser/bookmark_codec.cc index 40a6a43..36d60c0 100644 --- a/components/bookmarks/browser/bookmark_codec.cc +++ b/components/bookmarks/browser/bookmark_codec.cc
@@ -167,8 +167,7 @@ std::unique_ptr<base::Value> BookmarkCodec::EncodeMetaInfo( const BookmarkNode::MetaInfoMap& meta_info_map) { auto meta_info = std::make_unique<base::DictionaryValue>(); - for (BookmarkNode::MetaInfoMap::const_iterator it = meta_info_map.begin(); - it != meta_info_map.end(); ++it) { + for (auto it = meta_info_map.begin(); it != meta_info_map.end(); ++it) { meta_info->SetKey(it->first, base::Value(it->second)); } return std::move(meta_info); @@ -435,8 +434,7 @@ // transaction version to its value, then delete the field. if (deserialized_holder) { const char kBookmarkTransactionVersionKey[] = "sync.transaction_version"; - BookmarkNode::MetaInfoMap::iterator it = - meta_info_map->find(kBookmarkTransactionVersionKey); + auto it = meta_info_map->find(kBookmarkTransactionVersionKey); if (it != meta_info_map->end()) { base::StringToInt64(it->second, sync_transaction_version); meta_info_map->erase(it);
diff --git a/components/bookmarks/browser/bookmark_expanded_state_tracker.cc b/components/bookmarks/browser/bookmark_expanded_state_tracker.cc index a46fbbd..2799881 100644 --- a/components/bookmarks/browser/bookmark_expanded_state_tracker.cc +++ b/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
@@ -48,8 +48,7 @@ return nodes; bool changed = false; - for (base::ListValue::const_iterator i = value->begin(); - i != value->end(); ++i) { + for (auto i = value->begin(); i != value->end(); ++i) { std::string value; int64_t node_id; const BookmarkNode* node;
diff --git a/components/bookmarks/browser/bookmark_node.cc b/components/bookmarks/browser/bookmark_node.cc index 8b68d4e..ddc6e04 100644 --- a/components/bookmarks/browser/bookmark_node.cc +++ b/components/bookmarks/browser/bookmark_node.cc
@@ -67,7 +67,7 @@ if (!meta_info_map_) meta_info_map_.reset(new MetaInfoMap); - MetaInfoMap::iterator it = meta_info_map_->find(key); + auto it = meta_info_map_->find(key); if (it == meta_info_map_->end()) { (*meta_info_map_)[key] = value; return true;
diff --git a/components/bookmarks/browser/bookmark_node_data.cc b/components/bookmarks/browser/bookmark_node_data.cc index f3a0ac3..72c89d9 100644 --- a/components/bookmarks/browser/bookmark_node_data.cc +++ b/components/bookmarks/browser/bookmark_node_data.cc
@@ -48,15 +48,13 @@ pickle->WriteString16(title); pickle->WriteInt64(id_); pickle->WriteUInt32(static_cast<uint32_t>(meta_info_map.size())); - for (BookmarkNode::MetaInfoMap::const_iterator it = meta_info_map.begin(); - it != meta_info_map.end(); ++it) { + for (auto it = meta_info_map.begin(); it != meta_info_map.end(); ++it) { pickle->WriteString(it->first); pickle->WriteString(it->second); } if (!is_url) { pickle->WriteUInt32(static_cast<uint32_t>(children.size())); - for (std::vector<Element>::const_iterator i = children.begin(); - i != children.end(); ++i) { + for (auto i = children.begin(); i != children.end(); ++i) { i->WriteToPickle(pickle); } }
diff --git a/components/bookmarks/browser/bookmark_utils.cc b/components/bookmarks/browser/bookmark_utils.cc index af04fd3f..88b6122d 100644 --- a/components/bookmarks/browser/bookmark_utils.cc +++ b/components/bookmarks/browser/bookmark_utils.cc
@@ -354,9 +354,8 @@ if (max_count == 0) { nodes.push_back(parent); } else { - std::vector<const BookmarkNode*>::iterator i = - std::upper_bound(nodes.begin(), nodes.end(), parent, - &MoreRecentlyModified); + auto i = std::upper_bound(nodes.begin(), nodes.end(), parent, + &MoreRecentlyModified); if (nodes.size() < max_count || i != nodes.end()) { nodes.insert(i, parent); while (nodes.size() > max_count) @@ -393,9 +392,8 @@ while (iterator.has_next()) { const BookmarkNode* node = iterator.Next(); if (node->is_url()) { - std::vector<const BookmarkNode*>::iterator insert_position = - std::upper_bound(nodes->begin(), nodes->end(), node, - &MoreRecentlyAdded); + auto insert_position = std::upper_bound(nodes->begin(), nodes->end(), + node, &MoreRecentlyAdded); if (nodes->size() < count || insert_position != nodes->end()) { nodes->insert(insert_position, node); while (nodes->size() > count) @@ -498,9 +496,7 @@ const std::vector<int64_t>& ids) { // Remove the folders that were removed. This has to be done after all the // other changes have been committed. - for (std::vector<int64_t>::const_iterator iter = ids.begin(); - iter != ids.end(); - ++iter) { + for (auto iter = ids.begin(); iter != ids.end(); ++iter) { const BookmarkNode* node = GetBookmarkNodeByID(model, *iter); if (!node) continue;
diff --git a/components/bookmarks/browser/titled_url_index.cc b/components/bookmarks/browser/titled_url_index.cc index bacf382..dfe1181 100644 --- a/components/bookmarks/browser/titled_url_index.cc +++ b/components/bookmarks/browser/titled_url_index.cc
@@ -211,8 +211,7 @@ while (i != index_.end() && i->first.size() >= term.size() && term.compare(0, term.size(), i->first, 0, term.size()) == 0) { - for (TitledUrlNodeSet::const_iterator n = i->second.begin(); - n != i->second.end(); ++n) { + for (auto n = i->second.begin(); n != i->second.end(); ++n) { prefix_matches->insert(prefix_matches->end(), *n); } ++i; @@ -243,7 +242,7 @@ void TitledUrlIndex::UnregisterNode(const base::string16& term, const TitledUrlNode* node) { - Index::iterator i = index_.find(term); + auto i = index_.find(term); if (i == index_.end()) { // We can get here if the node has the same term more than once. For // example, a node with the title 'foo foo' would end up here.
diff --git a/components/bookmarks/browser/titled_url_match.cc b/components/bookmarks/browser/titled_url_match.cc index 039f335..6ebe5646 100644 --- a/components/bookmarks/browser/titled_url_match.cc +++ b/components/bookmarks/browser/titled_url_match.cc
@@ -19,8 +19,7 @@ std::vector<size_t> TitledUrlMatch::OffsetsFromMatchPositions( const MatchPositions& match_positions) { std::vector<size_t> offsets; - for (MatchPositions::const_iterator i = match_positions.begin(); - i != match_positions.end(); ++i) { + for (auto i = match_positions.begin(); i != match_positions.end(); ++i) { offsets.push_back(i->first); offsets.push_back(i->second); } @@ -33,8 +32,8 @@ const std::vector<size_t>& offsets) { DCHECK_EQ(2 * match_positions.size(), offsets.size()); MatchPositions new_match_positions; - std::vector<size_t>::const_iterator offset_iter = offsets.begin(); - for (MatchPositions::const_iterator match_iter = match_positions.begin(); + auto offset_iter = offsets.begin(); + for (auto match_iter = match_positions.begin(); match_iter != match_positions.end(); ++match_iter, ++offset_iter) { const size_t begin = *offset_iter; ++offset_iter;
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index 15db980..6130462a 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -337,8 +337,7 @@ bool ProfileSyncService::IsDataTypeControllerRunning( syncer::ModelType type) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DataTypeController::TypeMap::const_iterator iter = - data_type_controllers_.find(type); + auto iter = data_type_controllers_.find(type); if (iter == data_type_controllers_.end()) { return false; }
diff --git a/components/browser_sync/profile_sync_service_autofill_unittest.cc b/components/browser_sync/profile_sync_service_autofill_unittest.cc index 7b2c897a3..84bfc96 100644 --- a/components/browser_sync/profile_sync_service_autofill_unittest.cc +++ b/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -388,6 +388,7 @@ profile_sync_service_bundle()->pref_service(), /*identity_manager=*/nullptr, /*client_profile_validator=*/nullptr, + /*history_service=*/nullptr, /*is_off_the_record=*/false); web_data_service_->StartSyncableService();
diff --git a/components/browser_sync/profile_sync_service_bookmark_unittest.cc b/components/browser_sync/profile_sync_service_bookmark_unittest.cc index c26a96e4..b1404be0 100644 --- a/components/browser_sync/profile_sync_service_bookmark_unittest.cc +++ b/components/browser_sync/profile_sync_service_bookmark_unittest.cc
@@ -296,7 +296,7 @@ // (a) the implementation isn't sensitive to the order and // (b) the original meta info isn't blindly overwritten by // BookmarkChangeProcessor unless there is a real change. - BookmarkNode::MetaInfoMap::const_iterator it = meta_info_map.end(); + auto it = meta_info_map.end(); while (it != meta_info_map.begin()) { --it; sync_pb::MetaInfo* meta_info = specifics->add_meta_info(); @@ -643,8 +643,7 @@ EXPECT_EQ(meta_info_map->size(), static_cast<size_t>(specifics.meta_info_size())); for (int i = 0; i < specifics.meta_info_size(); i++) { - BookmarkNode::MetaInfoMap::const_iterator it = - meta_info_map->find(specifics.meta_info(i).key()); + auto it = meta_info_map->find(specifics.meta_info(i).key()); EXPECT_TRUE(it != meta_info_map->end()); EXPECT_EQ(it->second, specifics.meta_info(i).value()); } @@ -2441,8 +2440,7 @@ ASSERT_TRUE( model_associator()->InitSyncNodeFromChromeId(it->first, &sync_node)); EXPECT_EQ(sync_node.GetTransactionVersion(), it->second); - BookmarkNodeVersionMap::const_iterator expected_ver_it = - version_expected.find(it->first); + auto expected_ver_it = version_expected.find(it->first); if (expected_ver_it != version_expected.end()) EXPECT_EQ(expected_ver_it->second, it->second); }
diff --git a/components/certificate_transparency/chrome_require_ct_delegate.cc b/components/certificate_transparency/chrome_require_ct_delegate.cc index f6f6eb4d..846e62b 100644 --- a/components/certificate_transparency/chrome_require_ct_delegate.cc +++ b/components/certificate_transparency/chrome_require_ct_delegate.cc
@@ -232,8 +232,7 @@ return false; // Determine the overall policy by determining the most specific policy. - std::map<url_matcher::URLMatcherConditionSet::ID, Filter>::const_iterator it = - filters_.begin(); + auto it = filters_.begin(); const Filter* active_filter = nullptr; for (const auto& match : matching_ids) { // Because both |filters_| and |matching_ids| are sorted on the ID,
diff --git a/components/component_updater/component_updater_command_line_config_policy.cc b/components/component_updater/component_updater_command_line_config_policy.cc index c9b6093..9d72dd1c 100644 --- a/components/component_updater/component_updater_command_line_config_policy.cc +++ b/components/component_updater/component_updater_command_line_config_policy.cc
@@ -55,8 +55,7 @@ const char* test) { if (vec.empty()) return std::string(); - for (std::vector<std::string>::const_iterator it = vec.begin(); - it != vec.end(); ++it) { + for (auto it = vec.begin(); it != vec.end(); ++it) { const std::size_t found = it->find("="); if (found != std::string::npos) { if (it->substr(0, found) == test) {
diff --git a/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc b/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc index a8758321..5a8fff9d 100644 --- a/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc +++ b/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc
@@ -99,7 +99,7 @@ std::unique_ptr<base::AutoLock> auto_lock; if (lock) auto_lock.reset(new base::AutoLock(*lock)); - EntryMap::const_iterator it = entries_.find(key); + auto it = entries_.find(key); if (it == entries_.end()) return nullptr; return std::unique_ptr<RuleIterator>(new RuleIteratorImpl( @@ -123,7 +123,7 @@ ContentSettingsType content_type, const ResourceIdentifier& resource_identifier) const { EntryMapKey key(content_type, resource_identifier); - EntryMap::const_iterator it = entries_.find(key); + auto it = entries_.find(key); if (it == entries_.end()) return nullptr; @@ -149,10 +149,10 @@ EntryMapKey key(content_type, resource_identifier); PatternPair patterns(primary_pattern, secondary_pattern); - EntryMap::const_iterator it = entries_.find(key); + auto it = entries_.find(key); if (it == entries_.end()) return base::Time(); - Rules::const_iterator r = it->second.find(patterns); + auto r = it->second.find(patterns); if (r == it->second.end()) return base::Time(); return r->second.last_modified; @@ -186,7 +186,7 @@ const ResourceIdentifier& resource_identifier) { EntryMapKey key(content_type, resource_identifier); PatternPair patterns(primary_pattern, secondary_pattern); - EntryMap::iterator it = entries_.find(key); + auto it = entries_.find(key); if (it == entries_.end()) return; it->second.erase(patterns);
diff --git a/components/content_settings/core/browser/content_settings_usages_state.cc b/components/content_settings/core/browser/content_settings_usages_state.cc index a07d32c..b9fbf9f 100644 --- a/components/content_settings/core/browser/content_settings_usages_state.cc +++ b/components/content_settings/core/browser/content_settings_usages_state.cc
@@ -57,16 +57,14 @@ std::set<std::string> repeated_formatted_hosts; // Build a set of repeated formatted hosts - for (StateMap::const_iterator i(state_map_.begin()); - i != state_map_.end(); ++i) { + for (auto i(state_map_.begin()); i != state_map_.end(); ++i) { std::string formatted_host = GURLToFormattedHost(i->first); if (!formatted_hosts.insert(formatted_host).second) { repeated_formatted_hosts.insert(formatted_host); } } - for (StateMap::const_iterator i(state_map_.begin()); - i != state_map_.end(); ++i) { + for (auto i(state_map_.begin()); i != state_map_.end(); ++i) { if (i->second == CONTENT_SETTING_ALLOW) *tab_state_flags |= TABSTATE_HAS_ANY_ALLOWED; if (formatted_hosts_per_state) {
diff --git a/components/cronet/BUILD.gn b/components/cronet/BUILD.gn index 87a8025..62f209d 100644 --- a/components/cronet/BUILD.gn +++ b/components/cronet/BUILD.gn
@@ -242,4 +242,20 @@ ":generate_license", ] } + + executable("cronet_native_perf_test") { + testonly = true + sources = [ + "native/perftest/main.cc", + "native/perftest/perf_test.cc", + ] + deps = [ + "//base", + "//components/cronet", + "//components/cronet/native:cronet_native_headers", + "//components/cronet/native/test:cronet_native_tests", + "//components/cronet/native/test:cronet_native_testutil", + "//net:test_support", + ] + } }
diff --git a/components/cronet/android/test/javaperftests/run.py b/components/cronet/android/test/javaperftests/run.py index 9b433eb..ff788f59 100755 --- a/components/cronet/android/test/javaperftests/run.py +++ b/components/cronet/android/test/javaperftests/run.py
@@ -61,6 +61,7 @@ sys.path.append(os.path.join(REPOSITORY_ROOT, 'build', 'android')) sys.path.append(os.path.join( REPOSITORY_ROOT, 'third_party', 'catapult', 'devil')) +sys.path.append(os.path.join(REPOSITORY_ROOT, 'components', 'cronet', 'tools')) import android_rndis_forwarder from chrome_telemetry_build import chromium_config @@ -74,56 +75,8 @@ from telemetry import story from telemetry.value import scalar from telemetry.web_perf import timeline_based_measurement +import perf_test_utils -BUILD_TYPE = 'Release' -BUILD_DIR = os.path.join(REPOSITORY_ROOT, 'out', BUILD_TYPE) -QUIC_SERVER = os.path.join(BUILD_DIR, 'quic_server') -CERT_PATH = os.path.join('net', 'data', 'ssl', 'certificates') -QUIC_CERT_DIR = os.path.join(REPOSITORY_ROOT, CERT_PATH) -QUIC_CERT_HOST = 'test.example.com' -QUIC_CERT_FILENAME = 'quic-chain.pem' -QUIC_CERT = os.path.join(QUIC_CERT_DIR, QUIC_CERT_FILENAME) -QUIC_KEY = os.path.join(QUIC_CERT_DIR, 'quic-leaf-cert.key') -APP_APK = os.path.join(BUILD_DIR, 'apks', 'CronetPerfTest.apk') -APP_PACKAGE = 'org.chromium.net' -APP_ACTIVITY = '.CronetPerfTestActivity' -APP_ACTION = 'android.intent.action.MAIN' -BENCHMARK_CONFIG = { - # Control various metric recording for further investigation. - 'CAPTURE_NETLOG': False, - 'CAPTURE_TRACE': False, - 'CAPTURE_SAMPLED_TRACE': False, - # While running Cronet Async API benchmarks, indicate if callbacks should be - # run on network thread rather than posted back to caller thread. This allows - # measuring if thread-hopping overhead is significant. - 'CRONET_ASYNC_USE_NETWORK_THREAD': False, - # A small resource for device to fetch from host. - 'SMALL_RESOURCE': 'small.html', - 'SMALL_RESOURCE_SIZE': 26, - # Number of times to fetch SMALL_RESOURCE. - 'SMALL_ITERATIONS': 1000, - # A large resource for device to fetch from host. - 'LARGE_RESOURCE': 'large.html', - 'LARGE_RESOURCE_SIZE': 10000026, - # Number of times to fetch LARGE_RESOURCE. - 'LARGE_ITERATIONS': 4, - # An on-device file containing benchmark timings. Written by benchmark app. - 'RESULTS_FILE': '/data/data/' + APP_PACKAGE + '/results.txt', - # An on-device file whose presence indicates benchmark app has terminated. - 'DONE_FILE': '/data/data/' + APP_PACKAGE + '/done.txt', - # Ports of HTTP and QUIC servers on host. - 'HTTP_PORT': 9000, - 'QUIC_PORT': 9001, - # Maximum read/write buffer size to use. - 'MAX_BUFFER_SIZE': 16384, - 'HOST': QUIC_CERT_HOST, - 'QUIC_CERT_FILE': QUIC_CERT_FILENAME, -} -# Add benchmark config to global state for easy access. -globals().update(BENCHMARK_CONFIG) -# Pylint doesn't really interpret the file, so it won't find the definitions -# added from BENCHMARK_CONFIG, so suppress the undefined variable warning. -#pylint: disable=undefined-variable def GetDevice(): devices = device_utils.DeviceUtils.HealthyDevices() @@ -131,18 +84,6 @@ return devices[0] -def GetAndroidRndisConfig(device): - return android_rndis_forwarder.AndroidRndisConfigurator(device) - - -def GetServersHost(device): - return GetAndroidRndisConfig(device).host_ip - - -def GetHttpServerURL(device, resource): - return 'http://%s:%d/%s' % (GetServersHost(device), HTTP_PORT, resource) - - class CronetPerfTestAndroidStory(android.AndroidStory): # Android AppStory implementation wrapping CronetPerfTest app. # Launches Cronet perf test app and waits for execution to complete @@ -150,14 +91,13 @@ def __init__(self, device): self._device = device - device.RemovePath(DONE_FILE, force=True) - config = BENCHMARK_CONFIG - config['HOST_IP'] = GetServersHost(device) + config = perf_test_utils.GetConfig(device) + device.RemovePath(config['DONE_FILE'], force=True) self.url ='http://dummy/?'+urllib.urlencode(config) start_intent = intent.Intent( - package=APP_PACKAGE, - activity=APP_ACTIVITY, - action=APP_ACTION, + package=perf_test_utils.APP_PACKAGE, + activity=perf_test_utils.APP_ACTIVITY, + action=perf_test_utils.APP_ACTION, # |config| maps from configuration value names to the configured values. # |config| is encoded as URL parameter names and values and passed to # the Cronet perf test app via the Intent data field. @@ -172,7 +112,8 @@ is_app_ready_predicate=lambda app: True) def Run(self, shared_user_story_state): - while not self._device.FileExists(DONE_FILE): + while not self._device.FileExists( + perf_test_utils.GetConfig(self._device)['DONE_FILE']): sleep(1.0) @@ -201,7 +142,8 @@ def Measure(self, platform, results): # Reads results from |RESULTS_FILE| on target and adds to |results|. - jsonResults = json.loads(self._device.ReadFile(RESULTS_FILE)) + jsonResults = json.loads(self._device.ReadFile( + perf_test_utils.GetConfig(self._device)['RESULTS_FILE'])) for test in jsonResults: results.AddValue(scalar.ScalarValue(results.current_page, test, 'ms', jsonResults[test])) @@ -228,89 +170,6 @@ return CronetPerfTestStorySet(self._device) -class QuicServer(object): - - def __init__(self, quic_server_doc_root): - self._process = None - self._quic_server_doc_root = quic_server_doc_root - - def StartupQuicServer(self, device): - cmd = [QUIC_SERVER, - '--quic_response_cache_dir=%s' % self._quic_server_doc_root, - '--certificate_file=%s' % QUIC_CERT, - '--key_file=%s' % QUIC_KEY, - '--port=%d' % QUIC_PORT] - logging.info("Starting Quic Server: %s", cmd) - self._process = subprocess.Popen(cmd) - assert self._process != None - # Wait for quic_server to start serving. - waited_s = 0 - while subprocess.call(['lsof', '-i', 'udp:%d' % QUIC_PORT, '-p', - '%d' % self._process.pid], - stdout=open(os.devnull, 'w')) != 0: - sleep(0.1) - waited_s += 0.1 - assert waited_s < 5, "quic_server failed to start after %fs" % waited_s - # Push certificate to device. - cert = open(QUIC_CERT, 'r').read() - device_cert_path = posixpath.join( - device.GetExternalStoragePath(), 'chromium_tests_root', CERT_PATH) - device.RunShellCommand(['mkdir', '-p', device_cert_path], check_return=True) - device.WriteFile(os.path.join(device_cert_path, QUIC_CERT_FILENAME), cert) - - def ShutdownQuicServer(self): - if self._process: - self._process.terminate() - - -def GenerateHttpTestResources(): - http_server_doc_root = tempfile.mkdtemp() - # Create a small test file to serve. - small_file_name = os.path.join(http_server_doc_root, SMALL_RESOURCE) - small_file = open(small_file_name, 'wb') - small_file.write('<html><body></body></html>'); - small_file.close() - assert SMALL_RESOURCE_SIZE == os.path.getsize(small_file_name) - # Create a large (10MB) test file to serve. - large_file_name = os.path.join(http_server_doc_root, LARGE_RESOURCE) - large_file = open(large_file_name, 'wb') - large_file.write('<html><body>'); - for _ in range(0, 1000000): - large_file.write('1234567890'); - large_file.write('</body></html>'); - large_file.close() - assert LARGE_RESOURCE_SIZE == os.path.getsize(large_file_name) - return http_server_doc_root - - -def GenerateQuicTestResources(device): - quic_server_doc_root = tempfile.mkdtemp() - # Use wget to build up fake QUIC in-memory cache dir for serving. - # quic_server expects the dir/file layout that wget produces. - for resource in [SMALL_RESOURCE, LARGE_RESOURCE]: - assert subprocess.Popen(['wget', '-p', '-q', '--save-headers', - GetHttpServerURL(device, resource)], - cwd=quic_server_doc_root).wait() == 0 - # wget places results in host:port directory. Adjust for QUIC port. - os.rename(os.path.join(quic_server_doc_root, - "%s:%d" % (GetServersHost(device), HTTP_PORT)), - os.path.join(quic_server_doc_root, - "%s:%d" % (QUIC_CERT_HOST, QUIC_PORT))) - return quic_server_doc_root - - -def GenerateLighttpdConfig(config_file, http_server_doc_root, http_server): - # Must create customized config file to allow overriding the server.bind - # setting. - config_file.write('server.document-root = "%s"\n' % http_server_doc_root) - config_file.write('server.port = %d\n' % HTTP_PORT) - # These lines are added so lighttpd_server.py's internal test succeeds. - config_file.write('server.tag = "%s"\n' % http_server.server_tag) - config_file.write('server.pid-file = "%s"\n' % http_server.pid_file) - config_file.write('dir-listing.activate = "enable"\n') - config_file.flush() - - def main(): parser = optparse.OptionParser() parser.add_option('--output-format', default='html', @@ -319,25 +178,26 @@ help='The directory for the output file. Default value is ' 'the base directory of this script.') options, _ = parser.parse_args() - constants.SetBuildType(BUILD_TYPE) + constants.SetBuildType(perf_test_utils.BUILD_TYPE) # Install APK device = GetDevice() device.EnableRoot() - device.Install(APP_APK) + device.Install(perf_test_utils.APP_APK) # Start USB reverse tethering. android_rndis_forwarder.AndroidRndisForwarder(device, - GetAndroidRndisConfig(device)) + perf_test_utils.GetAndroidRndisConfig(device)) # Start HTTP server. - http_server_doc_root = GenerateHttpTestResources() + http_server_doc_root = perf_test_utils.GenerateHttpTestResources() config_file = tempfile.NamedTemporaryFile() http_server = lighttpd_server.LighttpdServer(http_server_doc_root, - port=HTTP_PORT, base_config_path=config_file.name) - GenerateLighttpdConfig(config_file, http_server_doc_root, http_server) + port=perf_test_utils.HTTP_PORT, base_config_path=config_file.name) + perf_test_utils.GenerateLighttpdConfig(config_file, http_server_doc_root, + http_server) assert http_server.StartupHttpServer() config_file.close() # Start QUIC server. - quic_server_doc_root = GenerateQuicTestResources(device) - quic_server = QuicServer(quic_server_doc_root) + quic_server_doc_root = perf_test_utils.GenerateQuicTestResources(device) + quic_server = perf_test_utils.QuicServer(quic_server_doc_root) quic_server.StartupQuicServer(device) # Launch Telemetry's benchmark_runner on CronetPerfTestBenchmark. # By specifying this file's directory as the benchmark directory, it will @@ -351,7 +211,7 @@ expectations_file=expectations_file) sys.argv.insert(1, 'run') sys.argv.insert(2, 'run.CronetPerfTestBenchmark') - sys.argv.insert(3, '--browser=any') + sys.argv.insert(3, '--browser=android-system-chrome') sys.argv.insert(4, '--output-format=' + options.output_format) if options.output_dir: sys.argv.insert(5, '--output-dir=' + options.output_dir)
diff --git a/components/cronet/native/perftest/main.cc b/components/cronet/native/perftest/main.cc new file mode 100644 index 0000000..f1f2e71 --- /dev/null +++ b/components/cronet/native/perftest/main.cc
@@ -0,0 +1,14 @@ +// Copyright 2018 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/cronet/native/perftest/perf_test.h" + +#include "base/logging.h" + +// When invoked, passes first and only argument to native performance test. +int main(int argc, char* argv[]) { + CHECK_EQ(argc, 2) << "Must include experimental options in JSON as only arg."; + PerfTest(argv[1]); + return 0; +} \ No newline at end of file
diff --git a/components/cronet/native/perftest/perf_test.cc b/components/cronet/native/perftest/perf_test.cc new file mode 100644 index 0000000..88b6bbb --- /dev/null +++ b/components/cronet/native/perftest/perf_test.cc
@@ -0,0 +1,442 @@ +// Copyright 2018 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 <string> + +#include "base/at_exit.h" +#include "base/atomic_sequence_num.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "base/values.h" +#include "components/cronet/native/test/test_upload_data_provider.h" +#include "components/cronet/native/test/test_url_request_callback.h" +#include "components/cronet/native/test/test_util.h" +#include "cronet_c.h" +#include "net/base/net_errors.h" +#include "net/cert/mock_cert_verifier.h" + +namespace { + +// Type of executor to use for a particular benchmark: +enum ExecutorType { + EXECUTOR_DIRECT, // Direct executor (on network thread). + EXECUTOR_THREAD, // Post to main thread. +}; + +// Upload or download benchmark. +enum Direction { + DIRECTION_UP, + DIRECTION_DOWN, +}; + +// Small or large benchmark payload. +enum Size { + SIZE_LARGE, + SIZE_SMALL, +}; + +// Protocol to benchmark. +enum Protocol { + PROTOCOL_HTTP, + PROTOCOL_QUIC, +}; + +// Dictionary of benchmark options. +std::unique_ptr<base::DictionaryValue> g_options; + +// Return a string configuration option. +std::string GetConfigString(const char* key) { + std::string value; + CHECK(g_options->GetString(key, &value)) << "Cannot find key: " << key; + return value; +} + +// Return an int configuration option. +int GetConfigInt(const char* key) { + int value; + CHECK(g_options->GetInteger(key, &value)) << "Cannot find key: " << key; + return value; +} + +// Put together a benchmark configuration into a benchmark name. +// Make it fixed length for more readable tables. +// Benchmark names are written to the JSON output file and slurped up by +// Telemetry on the host. +std::string BuildBenchmarkName(ExecutorType executor, + Direction direction, + Protocol protocol, + int concurrency, + int iterations) { + std::string name = direction == DIRECTION_UP ? "Up___" : "Down_"; + switch (protocol) { + case PROTOCOL_HTTP: + name += "H_"; + break; + case PROTOCOL_QUIC: + name += "Q_"; + break; + } + name += std::to_string(iterations) + "_" + std::to_string(concurrency) + "_"; + switch (executor) { + case EXECUTOR_DIRECT: + name += "ExDir"; + break; + case EXECUTOR_THREAD: + name += "ExThr"; + break; + } + return name; +} + +// Cronet UploadDataProvider to use for benchmark. +class UploadDataProvider : public cronet::test::TestUploadDataProvider { + public: + // |length| indicates how many bytes to upload. + UploadDataProvider(size_t length) + : TestUploadDataProvider(cronet::test::TestUploadDataProvider::SYNC, + nullptr), + length_(length), + remaining_(length) {} + + private: + int64_t GetLength() const override { return length_; } + + // Override of TestUploadDataProvider::Read() to simply report buffers filled. + void Read(Cronet_UploadDataSinkPtr upload_data_sink, + Cronet_BufferPtr buffer) override { + CHECK(remaining_ > 0); + size_t buffer_size = Cronet_Buffer_GetSize(buffer); + size_t sending = std::min(buffer_size, remaining_); + Cronet_UploadDataSink_OnReadSucceeded(upload_data_sink, sending, false); + remaining_ -= sending; + } + + const size_t length_; + // Count of bytes remaining to be uploaded. + size_t remaining_; +}; + +// Cronet UrlRequestCallback to use for benchmarking. +class Callback : public cronet::test::TestUrlRequestCallback { + public: + Callback() + : TestUrlRequestCallback(true), + message_loop_(base::MessageLoop::current()) {} + ~Callback() override { Cronet_UrlRequestCallback_Destroy(callback_); } + + // Start one repeated UrlRequest. |iterations_completed| is used to keep track + // of how many requests have completed. Final iteration should Quit() + // |run_loop|. + void Start(size_t buffer_size, + int iterations, + int concurrency, + size_t length, + const std::string& url, + base::AtomicSequenceNumber* iterations_completed, + Cronet_EnginePtr engine, + ExecutorType executor, + Direction direction, + base::RunLoop* run_loop) { + iterations_ = iterations; + concurrency_ = concurrency; + length_ = length; + url_ = &url; + iterations_completed_ = iterations_completed; + engine_ = engine; + callback_ = CreateUrlRequestCallback(); + CHECK(!executor_); + switch (executor) { + case EXECUTOR_DIRECT: + // TestUrlRequestCallback(true) was called above, so parent will create + // a direct executor. + GetExecutor(); + break; + case EXECUTOR_THREAD: + // Create an executor that posts back to this thread. + executor_ = Cronet_Executor_CreateWith(Callback::Execute); + Cronet_Executor_SetClientContext(executor_, this); + break; + } + CHECK(executor_); + direction_ = direction; + buffer_size_ = buffer_size; + run_loop_ = run_loop; + StartRequest(); + } + + private: + // Create and start a UrlRequest. + void StartRequest() { + Cronet_UrlRequestPtr request = Cronet_UrlRequest_Create(); + Cronet_UrlRequestParamsPtr request_params = + Cronet_UrlRequestParams_Create(); + if (direction_ == DIRECTION_UP) { + // Create and set an UploadDataProvider on the UrlRequest. + upload_data_provider_ = std::make_unique<UploadDataProvider>(length_); + cronet_upload_data_provider_ = + upload_data_provider_->CreateUploadDataProvider(); + Cronet_UrlRequestParams_upload_data_provider_set( + request_params, cronet_upload_data_provider_); + // Set Content-Type header. + Cronet_HttpHeaderPtr header = Cronet_HttpHeader_Create(); + Cronet_HttpHeader_name_set(header, "Content-Type"); + Cronet_HttpHeader_value_set(header, "application/octet-stream"); + Cronet_UrlRequestParams_request_headers_add(request_params, header); + Cronet_HttpHeader_Destroy(header); + } + Cronet_UrlRequest_InitWithParams(request, engine_, url_->c_str(), + request_params, callback_, executor_); + Cronet_UrlRequestParams_Destroy(request_params); + Cronet_UrlRequest_Start(request); + } + + void OnResponseStarted(Cronet_UrlRequestPtr request, + Cronet_UrlResponseInfoPtr info) override { + CHECK_EQ(200, Cronet_UrlResponseInfo_http_status_code_get(info)); + response_step_ = ON_RESPONSE_STARTED; + Cronet_BufferPtr buffer = Cronet_Buffer_Create(); + Cronet_Buffer_InitWithAlloc(buffer, buffer_size_); + StartNextRead(request, buffer); + } + + void OnSucceeded(Cronet_UrlRequestPtr request, + Cronet_UrlResponseInfoPtr info) override { + Cronet_UrlRequest_Destroy(request); + if (cronet_upload_data_provider_) + Cronet_UploadDataProvider_Destroy(cronet_upload_data_provider_); + + int iteration = iterations_completed_->GetNext(); + // If this was the final iteration, quit the RunLoop. + if (iteration == (iterations_ - 1)) + run_loop_->Quit(); + // Don't start another request if complete. + if (iteration >= (iterations_ - concurrency_)) + return; + // Start another request. + StartRequest(); + } + + void OnFailed(Cronet_UrlRequestPtr request, + Cronet_UrlResponseInfoPtr info, + Cronet_ErrorPtr error) override { + CHECK(false) << "Request failed with error " + << Cronet_Error_error_code_get(error); + } + + // A simple executor that posts back to |message_loop_|. + static void Execute(Cronet_ExecutorPtr self, Cronet_RunnablePtr runnable) { + auto* callback = + static_cast<Callback*>(Cronet_Executor_GetClientContext(self)); + callback->message_loop_->task_runner()->PostTask( + FROM_HERE, cronet::test::RunnableWrapper::CreateOnceClosure(runnable)); + } + + Direction direction_; + int iterations_; + int concurrency_; + size_t length_; + const std::string* url_; + base::AtomicSequenceNumber* iterations_completed_; + Cronet_EnginePtr engine_; + Cronet_UrlRequestCallbackPtr callback_; + Cronet_UploadDataProviderPtr cronet_upload_data_provider_ = nullptr; + base::MessageLoop* const message_loop_; + base::RunLoop* run_loop_; + size_t buffer_size_; + std::unique_ptr<UploadDataProvider> upload_data_provider_; +}; + +// An individual benchmark instance. +class Benchmark { + public: + ~Benchmark() { Cronet_Engine_Destroy(engine_); } + + // Run and time the benchmark. + static void Run(ExecutorType executor, + Direction direction, + Size size, + Protocol protocol, + int concurrency, + base::DictionaryValue* results) { + std::string resource; + int iterations; + size_t length; + switch (size) { + case SIZE_SMALL: + resource = GetConfigString("SMALL_RESOURCE"); + iterations = GetConfigInt("SMALL_ITERATIONS"); + length = GetConfigInt("SMALL_RESOURCE_SIZE"); + break; + case SIZE_LARGE: + // When measuring a large upload, only download a small amount so + // download time isn't significant. + resource = GetConfigString( + direction == DIRECTION_UP ? "SMALL_RESOURCE" : "LARGE_RESOURCE"); + iterations = GetConfigInt("LARGE_ITERATIONS"); + length = GetConfigInt("LARGE_RESOURCE_SIZE"); + break; + } + std::string name = BuildBenchmarkName(executor, direction, protocol, + concurrency, iterations); + std::string scheme; + std::string host; + int port; + switch (protocol) { + case PROTOCOL_HTTP: + scheme = "http"; + host = GetConfigString("HOST_IP"); + port = GetConfigInt("HTTP_PORT"); + break; + case PROTOCOL_QUIC: + scheme = "https"; + host = GetConfigString("HOST"); + port = GetConfigInt("QUIC_PORT"); + break; + } + std::string url = + scheme + "://" + host + ":" + std::to_string(port) + "/" + resource; + size_t buffer_size = length > (size_t)GetConfigInt("MAX_BUFFER_SIZE") + ? GetConfigInt("MAX_BUFFER_SIZE") + : length; + Benchmark(executor, direction, size, protocol, concurrency, iterations, + length, buffer_size, name, url, host, port, results) + .RunInternal(); + } + + private: + Benchmark(ExecutorType executor, + Direction direction, + Size size, + Protocol protocol, + int concurrency, + int iterations, + size_t length, + size_t buffer_size, + const std::string& name, + const std::string& url, + const std::string& host, + int port, + base::DictionaryValue* results) + : iterations_(iterations), + concurrency_(concurrency), + length_(length), + buffer_size_(buffer_size), + name_(name), + url_(url), + callbacks_(concurrency), + executor_(executor), + direction_(direction), + results_(results) { + Cronet_EngineParamsPtr engine_params = Cronet_EngineParams_Create(); + // Add Host Resolver Rules. + std::string host_resolver_rules = + "MAP test.example.com " + GetConfigString("HOST_IP") + ","; + Cronet_EngineParams_experimental_options_set( + engine_params, + base::StringPrintf( + "{ \"HostResolverRules\": { \"host_resolver_rules\" : \"%s\" } }", + host_resolver_rules.c_str()) + .c_str()); + // Create Cronet Engine. + engine_ = Cronet_Engine_Create(); + if (protocol == PROTOCOL_QUIC) { + Cronet_EngineParams_enable_quic_set(engine_params, true); + // Set QUIC hint. + Cronet_QuicHintPtr quic_hint = Cronet_QuicHint_Create(); + Cronet_QuicHint_host_set(quic_hint, host.c_str()); + Cronet_QuicHint_port_set(quic_hint, port); + Cronet_QuicHint_alternate_port_set(quic_hint, port); + Cronet_EngineParams_quic_hints_add(engine_params, quic_hint); + Cronet_QuicHint_Destroy(quic_hint); + // Set Mock Cert Verifier. + auto cert_verifier = std::make_unique<net::MockCertVerifier>(); + cert_verifier->set_default_result(net::OK); + Cronet_Engine_SetMockCertVerifierForTesting(engine_, + cert_verifier.release()); + } + + // Start Cronet Engine. + Cronet_Engine_StartWithParams(engine_, engine_params); + Cronet_EngineParams_Destroy(engine_params); + } + + // Run and time the benchmark. + void RunInternal() { + base::RunLoop run_loop; + base::TimeTicks start_time = base::TimeTicks::Now(); + // Start all concurrent requests. + for (auto& callback : callbacks_) { + callback.Start(buffer_size_, iterations_, concurrency_, length_, url_, + &iterations_completed_, engine_, executor_, direction_, + &run_loop); + } + run_loop.Run(); + base::TimeDelta run_time = base::TimeTicks::Now() - start_time; + results_->SetInteger(name_, static_cast<int>(run_time.InMilliseconds())); + } + + base::MessageLoop message_loop_; + const int iterations_; + const int concurrency_; + const size_t length_; + const size_t buffer_size_; + const std::string name_; + const std::string url_; + std::vector<Callback> callbacks_; + base::AtomicSequenceNumber iterations_completed_; + Cronet_EnginePtr engine_; + const ExecutorType executor_; + const Direction direction_; + base::DictionaryValue* const results_; +}; + +} // namespace + +void PerfTest(const char* json_args) { + base::AtExitManager exit_manager; + + // Parse benchmark options into |g_options|. + std::string benchmark_options = json_args; + std::unique_ptr<base::Value> options_value = + base::JSONReader::Read(benchmark_options); + CHECK(options_value) << "Parsing benchmark options failed: " + << benchmark_options; + g_options = base::DictionaryValue::From(std::move(options_value)); + CHECK(g_options) << "Benchmark options string is not a dictionary: " + << benchmark_options + << " See DEFAULT_BENCHMARK_CONFIG in perf_test_util.py."; + + // Run benchmarks putting timing results into |results|. + base::DictionaryValue results; + for (ExecutorType executor : {EXECUTOR_DIRECT, EXECUTOR_THREAD}) { + for (Direction direction : {DIRECTION_DOWN, DIRECTION_UP}) { + for (Protocol protocol : {PROTOCOL_HTTP, PROTOCOL_QUIC}) { + // Run large and small benchmarks one at a time to test single-threaded + // use. Also run them four at a time to see how they benefit from + // concurrency. The value four was chosen as many devices are now + // quad-core. + Benchmark::Run(executor, direction, SIZE_LARGE, protocol, 1, &results); + Benchmark::Run(executor, direction, SIZE_LARGE, protocol, 4, &results); + Benchmark::Run(executor, direction, SIZE_SMALL, protocol, 1, &results); + Benchmark::Run(executor, direction, SIZE_SMALL, protocol, 4, &results); + // Large benchmarks are generally bandwidth bound and unaffected by + // per-request overhead. Small benchmarks are not, so test at + // further increased concurrency to see if further benefit is possible. + Benchmark::Run(executor, direction, SIZE_SMALL, protocol, 8, &results); + } + } + } + + // Write |results| into results file. + std::string results_string; + base::JSONWriter::Write(results, &results_string); + FILE* results_file = fopen(GetConfigString("RESULTS_FILE").c_str(), "wb"); + fwrite(results_string.c_str(), results_string.length(), 1, results_file); + fclose(results_file); + fclose(fopen(GetConfigString("DONE_FILE").c_str(), "wb")); +} \ No newline at end of file
diff --git a/components/cronet/native/perftest/perf_test.h b/components/cronet/native/perftest/perf_test.h new file mode 100644 index 0000000..c3ccb99b --- /dev/null +++ b/components/cronet/native/perftest/perf_test.h
@@ -0,0 +1,7 @@ +// Copyright 2018 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. + +// Run Cronet native performance test. |json_args| is the string containing +// the JSON formatted arguments from components/cronet/native/perftest/run.py. +void PerfTest(const char* json_args);
diff --git a/components/cronet/native/perftest/run.py b/components/cronet/native/perftest/run.py new file mode 100755 index 0000000..1b1fa98 --- /dev/null +++ b/components/cronet/native/perftest/run.py
@@ -0,0 +1,71 @@ +#!/usr/bin/env python +# Copyright 2018 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. + +"""This script runs an automated Cronet native performance benchmark. + +This script: +1. Starts HTTP and QUIC servers on the host machine. +2. Runs benchmark executable. + +Prerequisites: +1. quic_server and cronet_native_perf_test have been built for the host machine, + e.g. via: + gn gen out/Release --args="is_debug=false" + ninja -C out/Release quic_server cronet_native_perf_test +2. sudo apt-get install lighttpd + +Invocation: +./run.py + +Output: +Benchmark timings are output to /tmp/cronet_perf_test_results.txt + +""" + +import json +import os +import shutil +import sys +import tempfile + +REPOSITORY_ROOT = os.path.abspath(os.path.join( + os.path.dirname(__file__), '..', '..', '..', '..')) + +sys.path.append(os.path.join(REPOSITORY_ROOT, 'build', 'android')) +import lighttpd_server +sys.path.append(os.path.join(REPOSITORY_ROOT, 'components', 'cronet', 'tools')) +import perf_test_utils + +def main(): + device = perf_test_utils.NativeDevice() + # Start HTTP server. + http_server_doc_root = perf_test_utils.GenerateHttpTestResources() + config_file = tempfile.NamedTemporaryFile() + http_server = lighttpd_server.LighttpdServer(http_server_doc_root, + port=perf_test_utils.HTTP_PORT, base_config_path=config_file.name) + perf_test_utils.GenerateLighttpdConfig(config_file, http_server_doc_root, + http_server) + assert http_server.StartupHttpServer() + config_file.close() + # Start QUIC server. + quic_server_doc_root = perf_test_utils.GenerateQuicTestResources(device) + quic_server = perf_test_utils.QuicServer(quic_server_doc_root) + quic_server.StartupQuicServer(device) + # Run test + os.environ['LD_LIBRARY_PATH'] = perf_test_utils.BUILD_DIR + device.RunShellCommand( + [os.path.join(perf_test_utils.BUILD_DIR, 'cronet_native_perf_test'), + json.dumps(perf_test_utils.GetConfig(device))], + check_return=True) + # Shutdown. + quic_server.ShutdownQuicServer() + shutil.rmtree(quic_server_doc_root) + http_server.ShutdownHttpServer() + shutil.rmtree(http_server_doc_root) + + +if __name__ == '__main__': + main() +
diff --git a/components/cronet/native/test/test_upload_data_provider.h b/components/cronet/native/test/test_upload_data_provider.h index d2fe3ec..4d8693b 100644 --- a/components/cronet/native/test/test_upload_data_provider.h +++ b/components/cronet/native/test/test_upload_data_provider.h
@@ -40,7 +40,7 @@ TestUploadDataProvider(SuccessCallbackMode success_callback_mode, Cronet_ExecutorPtr executor); - ~TestUploadDataProvider(); + virtual ~TestUploadDataProvider(); Cronet_UploadDataProviderPtr CreateUploadDataProvider(); @@ -64,11 +64,12 @@ /** * Returns the cumulative length of all data added by calls to addRead. */ - int64_t GetLength() const; + virtual int64_t GetLength() const; int64_t GetUploadedLength() const; - void Read(Cronet_UploadDataSinkPtr upload_data_sink, Cronet_BufferPtr buffer); + virtual void Read(Cronet_UploadDataSinkPtr upload_data_sink, + Cronet_BufferPtr buffer); void Rewind(Cronet_UploadDataSinkPtr upload_data_sink);
diff --git a/components/cronet/native/test/url_request_test.cc b/components/cronet/native/test/url_request_test.cc index c6bd7d15..4e90c41 100644 --- a/components/cronet/native/test/url_request_test.cc +++ b/components/cronet/native/test/url_request_test.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 <atomic> #include <memory> #include "base/files/file_util.h" @@ -25,6 +26,75 @@ namespace { +// A Cronet_UrlRequestStatusListener impl that waits for OnStatus callback. +class StatusListener { + public: + // |callback| is verified to not yet have reached a final state when + // OnStatus() is called back. + explicit StatusListener(TestUrlRequestCallback* callback) + : status_listener_(Cronet_UrlRequestStatusListener_CreateWith( + StatusListener::OnStatus)), + callback_(callback), + expect_request_not_done_(false) { + Cronet_UrlRequestStatusListener_SetClientContext(status_listener_, this); + } + + ~StatusListener() { + Cronet_UrlRequestStatusListener_Destroy(status_listener_); + } + + // Wait for and return request status. + Cronet_UrlRequestStatusListener_Status GetStatus( + Cronet_UrlRequestPtr request) { + Cronet_UrlRequest_GetStatus(request, status_listener_); + // NOTE(pauljensen): There's no guarantee this line will get executed + // before OnStatus() reads |expect_request_not_done_|. It's very unlikely + // it will get read before this write, but if it does it just means + // OnStatus() won't check that the final callback has not been issued yet. + expect_request_not_done_ = !Cronet_UrlRequest_IsDone(request); + awaiting_status_.Wait(); + return status_; + } + + private: + // Cronet_UrlRequestStatusListener OnStatus impl. + static void OnStatus(Cronet_UrlRequestStatusListenerPtr self, + Cronet_UrlRequestStatusListener_Status status) { + StatusListener* listener = static_cast<StatusListener*>( + Cronet_UrlRequestStatusListener_GetClientContext(self)); + + // Enforce we call OnStatus() before OnSucceeded/OnFailed/OnCanceled(). + if (listener->expect_request_not_done_) + EXPECT_FALSE(listener->callback_->IsDone()); + + listener->status_ = status; + listener->awaiting_status_.Signal(); + } + + Cronet_UrlRequestStatusListenerPtr const status_listener_; + TestUrlRequestCallback* const callback_; + + Cronet_UrlRequestStatusListener_Status status_ = + Cronet_UrlRequestStatusListener_Status_INVALID; + base::WaitableEvent awaiting_status_; + + // Indicates if GetStatus() was called before request finished, indicating + // that OnStatus() should be called before request finishes. The writing of + // this variable races the reading of it, but it's initialized to a safe + // value. + std::atomic_bool expect_request_not_done_; + + DISALLOW_COPY_AND_ASSIGN(StatusListener); +}; + +// Query and return status of |request|. |callback| is verified to not yet have +// reached a final state by the time OnStatus is called. +Cronet_UrlRequestStatusListener_Status GetRequestStatus( + Cronet_UrlRequestPtr request, + TestUrlRequestCallback* callback) { + return StatusListener(callback).GetStatus(request); +} + // Parameterized off whether to use a direct executor. class UrlRequestTest : public ::testing::TestWithParam<bool> { protected: @@ -880,4 +950,67 @@ cronet::TestServer::ReleaseBigDataURL(); } +TEST_P(UrlRequestTest, GetStatus) { + Cronet_EnginePtr engine = cronet::test::CreateTestEngine(0); + Cronet_UrlRequestPtr request = Cronet_UrlRequest_Create(); + Cronet_UrlRequestParamsPtr request_params = Cronet_UrlRequestParams_Create(); + std::string url = cronet::TestServer::GetSimpleURL(); + + TestUrlRequestCallback test_callback(GetParam()); + test_callback.set_auto_advance(false); + // Executor provided by the application is owned by |test_callback|. + Cronet_ExecutorPtr executor = test_callback.GetExecutor(); + // Callback provided by the application. + Cronet_UrlRequestCallbackPtr callback = + test_callback.CreateUrlRequestCallback(); + + Cronet_UrlRequest_InitWithParams(request, engine, url.c_str(), request_params, + callback, executor); + EXPECT_EQ(Cronet_UrlRequestStatusListener_Status_INVALID, + GetRequestStatus(request, &test_callback)); + + Cronet_UrlRequest_Start(request); + EXPECT_LE(Cronet_UrlRequestStatusListener_Status_IDLE, + GetRequestStatus(request, &test_callback)); + EXPECT_GE(Cronet_UrlRequestStatusListener_Status_READING_RESPONSE, + GetRequestStatus(request, &test_callback)); + + test_callback.WaitForNextStep(); + EXPECT_EQ(Cronet_UrlRequestStatusListener_Status_WAITING_FOR_DELEGATE, + GetRequestStatus(request, &test_callback)); + + Cronet_BufferPtr buffer = Cronet_Buffer_Create(); + Cronet_Buffer_InitWithAlloc(buffer, 100); + Cronet_UrlRequest_Read(request, buffer); + EXPECT_LE(Cronet_UrlRequestStatusListener_Status_IDLE, + GetRequestStatus(request, &test_callback)); + EXPECT_GE(Cronet_UrlRequestStatusListener_Status_READING_RESPONSE, + GetRequestStatus(request, &test_callback)); + + test_callback.WaitForNextStep(); + EXPECT_LE(Cronet_UrlRequestStatusListener_Status_IDLE, + GetRequestStatus(request, &test_callback)); + EXPECT_GE(Cronet_UrlRequestStatusListener_Status_READING_RESPONSE, + GetRequestStatus(request, &test_callback)); + + buffer = Cronet_Buffer_Create(); + Cronet_Buffer_InitWithAlloc(buffer, 100); + Cronet_UrlRequest_Read(request, buffer); + // Verify that late calls to GetStatus() don't invoke OnStatus() after + // final callbacks. + GetRequestStatus(request, &test_callback); + test_callback.WaitForNextStep(); + EXPECT_EQ(Cronet_UrlRequestStatusListener_Status_INVALID, + GetRequestStatus(request, &test_callback)); + + EXPECT_TRUE(test_callback.IsDone()); + ASSERT_EQ("The quick brown fox jumps over the lazy dog.", + test_callback.response_as_string_); + + Cronet_UrlRequestParams_Destroy(request_params); + Cronet_UrlRequest_Destroy(request); + Cronet_UrlRequestCallback_Destroy(callback); + Cronet_Engine_Destroy(engine); +} + } // namespace
diff --git a/components/cronet/native/upload_data_sink.cc b/components/cronet/native/upload_data_sink.cc index 8678d8e..5458021 100644 --- a/components/cronet/native/upload_data_sink.cc +++ b/components/cronet/native/upload_data_sink.cc
@@ -110,7 +110,7 @@ } CHECK(bytes_read > 0 || (final_chunk && bytes_read == 0)); // Bytes read exceeds buffer length. - CHECK_LT(static_cast<size_t>(bytes_read), buffer_->io_buffer_len()); + CHECK_LE(static_cast<size_t>(bytes_read), buffer_->io_buffer_len()); if (!is_chunked_) { // Only chunked upload can have the final chunk. CHECK(!final_chunk);
diff --git a/components/cronet/native/url_request.cc b/components/cronet/native/url_request.cc index 89c535d..c594826 100644 --- a/components/cronet/native/url_request.cc +++ b/components/cronet/native/url_request.cc
@@ -17,6 +17,7 @@ #include "components/cronet/native/runnables.h" #include "components/cronet/native/upload_data_sink.h" #include "net/base/io_buffer.h" +#include "net/base/load_states.h" namespace { @@ -148,6 +149,64 @@ }; #endif // DCHECK_IS_ON() +// Convert net::LoadState to Cronet_UrlRequestStatusListener_Status. +Cronet_UrlRequestStatusListener_Status ConvertLoadState( + net::LoadState load_state) { + switch (load_state) { + case net::LOAD_STATE_IDLE: + return Cronet_UrlRequestStatusListener_Status_IDLE; + + case net::LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL: + return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_STALLED_SOCKET_POOL; + + case net::LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET: + return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_AVAILABLE_SOCKET; + + case net::LOAD_STATE_WAITING_FOR_DELEGATE: + return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_DELEGATE; + + case net::LOAD_STATE_WAITING_FOR_CACHE: + return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_CACHE; + + case net::LOAD_STATE_DOWNLOADING_PAC_FILE: + return Cronet_UrlRequestStatusListener_Status_DOWNLOADING_PAC_FILE; + + case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL: + return Cronet_UrlRequestStatusListener_Status_RESOLVING_PROXY_FOR_URL; + + case net::LOAD_STATE_RESOLVING_HOST_IN_PAC_FILE: + return Cronet_UrlRequestStatusListener_Status_RESOLVING_HOST_IN_PAC_FILE; + + case net::LOAD_STATE_ESTABLISHING_PROXY_TUNNEL: + return Cronet_UrlRequestStatusListener_Status_ESTABLISHING_PROXY_TUNNEL; + + case net::LOAD_STATE_RESOLVING_HOST: + return Cronet_UrlRequestStatusListener_Status_RESOLVING_HOST; + + case net::LOAD_STATE_CONNECTING: + return Cronet_UrlRequestStatusListener_Status_CONNECTING; + + case net::LOAD_STATE_SSL_HANDSHAKE: + return Cronet_UrlRequestStatusListener_Status_SSL_HANDSHAKE; + + case net::LOAD_STATE_SENDING_REQUEST: + return Cronet_UrlRequestStatusListener_Status_SENDING_REQUEST; + + case net::LOAD_STATE_WAITING_FOR_RESPONSE: + return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_RESPONSE; + + case net::LOAD_STATE_READING_RESPONSE: + return Cronet_UrlRequestStatusListener_Status_READING_RESPONSE; + + default: + // A load state is retrieved but there is no corresponding + // request status. This most likely means that the mapping is + // incorrect. + CHECK(false); + return Cronet_UrlRequestStatusListener_Status_INVALID; + } +} + } // namespace namespace cronet { @@ -159,6 +218,10 @@ NetworkTasks(const std::string& url, Cronet_UrlRequestImpl* url_request); ~NetworkTasks() override = default; + // Callback function used for GetStatus(). + void OnStatus(Cronet_UrlRequestStatusListenerPtr listener, + net::LoadState load_state); + private: // CronetURLRequest::Callback implementation: void OnReceivedRedirect(const std::string& new_location, @@ -212,6 +275,11 @@ // Cronet_UrlRequestCallback::OnRedirectReceived is called. std::vector<std::string> url_chain_; + // Set to true when OnCanceled/OnSucceeded/OnFailed is posted. + // When true it is unsafe to attempt to post other callbacks + // like OnStatus because the request may be destroyed. + bool final_callback_posted_ = false; + // All methods except constructor are invoked on the network thread. THREAD_CHECKER(network_thread_checker_); DISALLOW_COPY_AND_ASSIGN(NetworkTasks); @@ -259,11 +327,13 @@ callback_ = callback; executor_ = executor; + auto network_tasks = std::make_unique<NetworkTasks>(url, this); + network_tasks_ = network_tasks.get(); + request_ = new CronetURLRequest( - engine_->cronet_url_request_context(), - std::make_unique<NetworkTasks>(url, this), GURL(url), - ConvertRequestPriority(params->priority), params->disable_cache, - true /* params->disableConnectionMigration */, + engine_->cronet_url_request_context(), std::move(network_tasks), + GURL(url), ConvertRequestPriority(params->priority), + params->disable_cache, true /* params->disableConnectionMigration */, false /* params->enableMetrics */, // TODO(pauljensen): Consider exposing TrafficStats API via C++ API. false /* traffic_stats_tag_set */, 0 /* traffic_stats_tag */, @@ -393,7 +463,19 @@ void Cronet_UrlRequestImpl::GetStatus( Cronet_UrlRequestStatusListenerPtr listener) { - NOTIMPLEMENTED(); + { + base::AutoLock lock(lock_); + if (started_ && request_) { + status_listeners_.insert(listener); + request_->GetStatus( + base::BindOnce(&Cronet_UrlRequestImpl::NetworkTasks::OnStatus, + base::Unretained(network_tasks_), listener)); + return; + } + } + PostTaskToExecutor( + base::BindOnce(Cronet_UrlRequestStatusListener_OnStatus, listener, + Cronet_UrlRequestStatusListener_Status_INVALID)); } void Cronet_UrlRequestImpl::OnUploadDataProviderError( @@ -458,6 +540,7 @@ Cronet_RequestFinishedInfo_FINISHED_REASON_SUCCEEDED)) { return; } + InvokeAllStatusListeners(); Cronet_UrlRequestCallback_OnSucceeded(callback_, this, response_info_.get()); } @@ -466,14 +549,36 @@ Cronet_RequestFinishedInfo_FINISHED_REASON_FAILED)) { return; } + InvokeAllStatusListeners(); Cronet_UrlRequestCallback_OnFailed(callback_, this, response_info_.get(), error_.get()); } void Cronet_UrlRequestImpl::InvokeCallbackOnCanceled() { + InvokeAllStatusListeners(); Cronet_UrlRequestCallback_OnCanceled(callback_, this, response_info_.get()); } +void Cronet_UrlRequestImpl::InvokeAllStatusListeners() { + std::unordered_multiset<Cronet_UrlRequestStatusListenerPtr> status_listeners; + { + base::AutoLock lock(lock_); + // Verify the request has already been destroyed, which ensures no more + // status listeners can be added. + DCHECK(!request_); + status_listeners.swap(status_listeners_); + } + for (Cronet_UrlRequestStatusListener* status_listener : status_listeners) { + Cronet_UrlRequestStatusListener_OnStatus( + status_listener, Cronet_UrlRequestStatusListener_Status_INVALID); + } +#if DCHECK_IS_ON() + // Verify no status listeners added during OnStatus() callbacks. + base::AutoLock lock(lock_); + DCHECK(status_listeners_.empty()); +#endif // DCHECK_IS_ON() +} + Cronet_UrlRequestImpl::NetworkTasks::NetworkTasks( const std::string& url, Cronet_UrlRequestImpl* url_request) @@ -568,6 +673,7 @@ url_request_->PostTaskToExecutor( base::BindOnce(&Cronet_UrlRequestImpl::InvokeCallbackOnSucceeded, base::Unretained(url_request_))); + final_callback_posted_ = true; } void Cronet_UrlRequestImpl::NetworkTasks::OnError( @@ -591,6 +697,7 @@ url_request_->PostTaskToExecutor( base::BindOnce(&Cronet_UrlRequestImpl::InvokeCallbackOnFailed, base::Unretained(url_request_))); + final_callback_posted_ = true; } void Cronet_UrlRequestImpl::NetworkTasks::OnCanceled() { @@ -602,6 +709,7 @@ url_request_->PostTaskToExecutor( base::BindOnce(&Cronet_UrlRequestImpl::InvokeCallbackOnCanceled, base::Unretained(url_request_))); + final_callback_posted_ = true; } void Cronet_UrlRequestImpl::NetworkTasks::OnDestroyed() { @@ -630,6 +738,25 @@ DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_); } +void Cronet_UrlRequestImpl::NetworkTasks::OnStatus( + Cronet_UrlRequestStatusListenerPtr listener, + net::LoadState load_state) { + DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_); + if (final_callback_posted_) + return; + { + base::AutoLock lock(url_request_->lock_); + auto element = url_request_->status_listeners_.find(listener); + CHECK(element != url_request_->status_listeners_.end()); + url_request_->status_listeners_.erase(element); + } + + // Invoke Cronet_UrlRequestCallback_OnCanceled on client executor. + url_request_->PostTaskToExecutor( + base::BindOnce(&Cronet_UrlRequestStatusListener_OnStatus, listener, + ConvertLoadState(load_state))); +} + }; // namespace cronet CRONET_EXPORT Cronet_UrlRequestPtr Cronet_UrlRequest_Create() {
diff --git a/components/cronet/native/url_request.h b/components/cronet/native/url_request.h index 967d5f3..7e3a708b 100644 --- a/components/cronet/native/url_request.h +++ b/components/cronet/native/url_request.h
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include <unordered_set> #include "base/macros.h" #include "base/synchronization/lock.h" @@ -15,6 +16,10 @@ #include "components/cronet/cronet_url_request_context.h" #include "components/cronet/native/generated/cronet.idl_impl_interface.h" +namespace net { +enum LoadState; +} // namespace net + namespace cronet { class Cronet_EngineImpl; @@ -75,14 +80,24 @@ void InvokeCallbackOnFailed(); void InvokeCallbackOnCanceled(); + // Invoke all members of |status_listeners_|. Should be called prior to + // invoking a final callback. Once a final callback has been called, |this| + // and |executor_| may be deleted and so the callbacks cannot be issued. + void InvokeAllStatusListeners(); + // Synchronize access to |request_| and other objects below from different // threads. base::Lock lock_; + // NetworkTask object lives on the network thread. Owned by |request_|. + // Outlives this. + NetworkTasks* network_tasks_ = nullptr; // Cronet URLRequest used for this operation. CronetURLRequest* request_ = nullptr; bool started_ = false; bool waiting_on_redirect_ = false; bool waiting_on_read_ = false; + // Set of status_listeners_ that have not yet been called back. + std::unordered_multiset<Cronet_UrlRequestStatusListenerPtr> status_listeners_; // Response info updated by callback with number of bytes received. May be // nullptr, if no response has been received. @@ -100,7 +115,7 @@ // Cronet Engine used to run network operations. Not owned, accessed from // client thread. Must outlive this request. - Cronet_EngineImpl* engine_; + Cronet_EngineImpl* engine_ = nullptr; #if DCHECK_IS_ON() // Event indicating Executor is properly destroying Runnables.
diff --git a/components/cronet/android/test/javaperftests/android_rndis_forwarder.py b/components/cronet/tools/android_rndis_forwarder.py similarity index 97% rename from components/cronet/android/test/javaperftests/android_rndis_forwarder.py rename to components/cronet/tools/android_rndis_forwarder.py index b9601ccb..4969496 100644 --- a/components/cronet/android/test/javaperftests/android_rndis_forwarder.py +++ b/components/cronet/tools/android_rndis_forwarder.py
@@ -9,6 +9,13 @@ import socket import struct import subprocess +import sys + +REPOSITORY_ROOT = os.path.abspath(os.path.join( + os.path.dirname(__file__), '..', '..', '..')) +sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools', 'perf')) +from core import path_util +sys.path.append(path_util.GetTelemetryDir()) from telemetry.core import platform from telemetry.core import util @@ -282,7 +289,11 @@ # For some combinations of devices and host kernels, adb won't work unless the # interface is up, but if we bring it up immediately, it will break adb. #sleep 1 - ifconfig rndis0 %(device_ip_address)s netmask 255.255.255.0 up + if ip link show rndis0 ; then + ifconfig rndis0 %(device_ip_address)s netmask 255.255.255.0 up + else + ifconfig usb0 %(device_ip_address)s netmask 255.255.255.0 up + fi echo DONE >> %(prefix)s.log }
diff --git a/components/cronet/tools/perf_test_utils.py b/components/cronet/tools/perf_test_utils.py new file mode 100755 index 0000000..7792ad9 --- /dev/null +++ b/components/cronet/tools/perf_test_utils.py
@@ -0,0 +1,186 @@ +#!/usr/bin/env python +# Copyright 2018 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. + +"""Utilities for Cronet performance tests.""" + +import android_rndis_forwarder +import logging +import os +import posixpath +import subprocess +import tempfile + +REPOSITORY_ROOT = os.path.abspath(os.path.join( + os.path.dirname(__file__), '..', '..', '..')) +BUILD_TYPE = 'Release' +BUILD_DIR = os.path.join(REPOSITORY_ROOT, 'out', BUILD_TYPE) +QUIC_SERVER = os.path.join(BUILD_DIR, 'quic_server') +CERT_PATH = os.path.join('net', 'data', 'ssl', 'certificates') +QUIC_CERT_DIR = os.path.join(REPOSITORY_ROOT, CERT_PATH) +QUIC_CERT_HOST = 'test.example.com' +QUIC_CERT_FILENAME = 'quic-chain.pem' +QUIC_CERT = os.path.join(QUIC_CERT_DIR, QUIC_CERT_FILENAME) +QUIC_KEY = os.path.join(QUIC_CERT_DIR, 'quic-leaf-cert.key') +APP_APK = os.path.join(BUILD_DIR, 'apks', 'CronetPerfTest.apk') +APP_PACKAGE = 'org.chromium.net' +APP_ACTIVITY = '.CronetPerfTestActivity' +APP_ACTION = 'android.intent.action.MAIN' +DEFAULT_BENCHMARK_CONFIG = { + # Control various metric recording for further investigation. + 'CAPTURE_NETLOG': False, + 'CAPTURE_TRACE': False, + 'CAPTURE_SAMPLED_TRACE': False, + # While running Cronet Async API benchmarks, indicate if callbacks should be + # run on network thread rather than posted back to caller thread. This allows + # measuring if thread-hopping overhead is significant. + 'CRONET_ASYNC_USE_NETWORK_THREAD': False, + # A small resource for device to fetch from host. + 'SMALL_RESOURCE': 'small.html', + 'SMALL_RESOURCE_SIZE': 26, + # Number of times to fetch SMALL_RESOURCE. + 'SMALL_ITERATIONS': 1000, + # A large resource for device to fetch from host. + 'LARGE_RESOURCE': 'large.html', + 'LARGE_RESOURCE_SIZE': 10000026, + # Number of times to fetch LARGE_RESOURCE. + 'LARGE_ITERATIONS': 4, + # Ports of HTTP and QUIC servers on host. + 'HTTP_PORT': 9000, + 'QUIC_PORT': 9001, + # Maximum read/write buffer size to use. + 'MAX_BUFFER_SIZE': 16384, + 'HOST': QUIC_CERT_HOST, + 'QUIC_CERT_FILE': QUIC_CERT_FILENAME, +} +# Add benchmark config to global state for easy access. +globals().update(DEFAULT_BENCHMARK_CONFIG) +# Pylint doesn't really interpret the file, so it won't find the definitions +# added from DEFAULT_BENCHMARK_CONFIG, so suppress the undefined variable +# warning. +#pylint: disable=undefined-variable + +class NativeDevice(object): + def GetExternalStoragePath(self): + return '/tmp' + + def RunShellCommand(self, cmd, check_return=False): + if check_return: + subprocess.check_call(cmd) + else: + subprocess.call(cmd) + + def WriteFile(self, path, data): + with open(path, 'w') as f: + f.write(data) + +def GetConfig(device): + config = DEFAULT_BENCHMARK_CONFIG + config['HOST_IP'] = GetServersHost(device) + if isinstance(device, NativeDevice): + config['RESULTS_FILE'] = '/tmp/cronet_perf_test_results.txt' + config['DONE_FILE'] = '/tmp/cronet_perf_test_done.txt' + else: + # An on-device file containing benchmark timings. Written by benchmark app. + config['RESULTS_FILE'] = '/data/data/' + APP_PACKAGE + '/results.txt' + # An on-device file whose presence indicates benchmark app has terminated. + config['DONE_FILE'] = '/data/data/' + APP_PACKAGE + '/done.txt' + return config + + +def GetAndroidRndisConfig(device): + return android_rndis_forwarder.AndroidRndisConfigurator(device) + + +def GetServersHost(device): + if isinstance(device, NativeDevice): + return '127.0.0.1' + return GetAndroidRndisConfig(device).host_ip + + +def GetHttpServerURL(device, resource): + return 'http://%s:%d/%s' % (GetServersHost(device), HTTP_PORT, resource) + + +class QuicServer(object): + + def __init__(self, quic_server_doc_root): + self._process = None + self._quic_server_doc_root = quic_server_doc_root + + def StartupQuicServer(self, device): + cmd = [QUIC_SERVER, + '--quic_response_cache_dir=%s' % self._quic_server_doc_root, + '--certificate_file=%s' % QUIC_CERT, + '--key_file=%s' % QUIC_KEY, + '--port=%d' % QUIC_PORT] + logging.info("Starting Quic Server: %s", cmd) + self._process = subprocess.Popen(cmd) + assert self._process != None + # Wait for quic_server to start serving. + waited_s = 0 + while subprocess.call(['lsof', '-i', 'udp:%d' % QUIC_PORT, '-p', + '%d' % self._process.pid], + stdout=open(os.devnull, 'w')) != 0: + sleep(0.1) + waited_s += 0.1 + assert waited_s < 5, "quic_server failed to start after %fs" % waited_s + # Push certificate to device. + cert = open(QUIC_CERT, 'r').read() + device_cert_path = posixpath.join( + device.GetExternalStoragePath(), 'chromium_tests_root', CERT_PATH) + device.RunShellCommand(['mkdir', '-p', device_cert_path], check_return=True) + device.WriteFile(os.path.join(device_cert_path, QUIC_CERT_FILENAME), cert) + + def ShutdownQuicServer(self): + if self._process: + self._process.terminate() + + +def GenerateHttpTestResources(): + http_server_doc_root = tempfile.mkdtemp() + # Create a small test file to serve. + small_file_name = os.path.join(http_server_doc_root, SMALL_RESOURCE) + small_file = open(small_file_name, 'wb') + small_file.write('<html><body></body></html>'); + small_file.close() + assert SMALL_RESOURCE_SIZE == os.path.getsize(small_file_name) + # Create a large (10MB) test file to serve. + large_file_name = os.path.join(http_server_doc_root, LARGE_RESOURCE) + large_file = open(large_file_name, 'wb') + large_file.write('<html><body>'); + for _ in range(0, 1000000): + large_file.write('1234567890'); + large_file.write('</body></html>'); + large_file.close() + assert LARGE_RESOURCE_SIZE == os.path.getsize(large_file_name) + return http_server_doc_root + + +def GenerateQuicTestResources(device): + quic_server_doc_root = tempfile.mkdtemp() + # Use wget to build up fake QUIC in-memory cache dir for serving. + # quic_server expects the dir/file layout that wget produces. + for resource in [SMALL_RESOURCE, LARGE_RESOURCE]: + assert subprocess.Popen(['wget', '-p', '-q', '--save-headers', + GetHttpServerURL(device, resource)], + cwd=quic_server_doc_root).wait() == 0 + # wget places results in host:port directory. Adjust for QUIC port. + os.rename(os.path.join(quic_server_doc_root, + "%s:%d" % (GetServersHost(device), HTTP_PORT)), + os.path.join(quic_server_doc_root, + "%s:%d" % (QUIC_CERT_HOST, QUIC_PORT))) + return quic_server_doc_root + + +def GenerateLighttpdConfig(config_file, http_server_doc_root, http_server): + # Must create customized config file to allow overriding the server.bind + # setting. + config_file.write('server.document-root = "%s"\n' % http_server_doc_root) + config_file.write('server.port = %d\n' % HTTP_PORT) + # These lines are added so lighttpd_server.py's internal test succeeds. + config_file.write('server.tag = "%s"\n' % http_server.server_tag) + config_file.write('server.pid-file = "%s"\n' % http_server.pid_file) + config_file.write('dir-listing.activate = "enable"\n') + config_file.flush()
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc index 9154d3e..9f8cac6 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc
@@ -488,15 +488,13 @@ } if (expected_num_bad_proxies >= 1u) { - ProxyRetryInfoMap::const_iterator i = - retry_info.find(GetProxyKey(bad_proxy)); + auto i = retry_info.find(GetProxyKey(bad_proxy)); ASSERT_TRUE(i != retry_info.end()); EXPECT_TRUE(expected_min_duration <= (*i).second.current_delay); EXPECT_TRUE((*i).second.current_delay <= expected_max_duration); } if (expected_num_bad_proxies == 2u) { - ProxyRetryInfoMap::const_iterator i = - retry_info.find(GetProxyKey(bad_proxy2)); + auto i = retry_info.find(GetProxyKey(bad_proxy2)); ASSERT_TRUE(i != retry_info.end()); EXPECT_TRUE(expected_min_duration <= (*i).second.current_delay); EXPECT_TRUE((*i).second.current_delay <= expected_max_duration);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc index d35e777..2ff3610 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -559,7 +559,7 @@ if (delay_.is_zero()) return pref_service_->GetInt64(pref_path); - DataReductionProxyPrefMap::iterator iter = pref_map_.find(pref_path); + auto iter = pref_map_.find(pref_path); return iter->second; } @@ -597,8 +597,7 @@ if (delay_.is_zero()) return; - for (DataReductionProxyPrefMap::iterator iter = pref_map_.begin(); - iter != pref_map_.end(); ++iter) { + for (auto iter = pref_map_.begin(); iter != pref_map_.end(); ++iter) { pref_service_->SetInt64(iter->first, iter->second); }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index 7e5dc6c..de2305e 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -51,6 +51,7 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_status.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #if defined(OS_ANDROID) #include "net/android/network_library.h" @@ -216,8 +217,7 @@ void DataReductionProxyConfig::InitializeOnIOThread( const scoped_refptr<net::URLRequestContextGetter>& basic_url_request_context_getter, - const scoped_refptr<net::URLRequestContextGetter>& - url_request_context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, NetworkPropertiesManager* manager) { DCHECK(thread_checker_.CalledOnValidThread()); network_properties_manager_ = manager; @@ -226,7 +226,7 @@ secure_proxy_checker_.reset( new SecureProxyChecker(basic_url_request_context_getter)); warmup_url_fetcher_.reset(new WarmupURLFetcher( - url_request_context_getter, + std::move(url_loader_factory), base::BindRepeating( &DataReductionProxyConfig::HandleWarmupFetcherResponse, base::Unretained(this)), @@ -355,8 +355,7 @@ const net::ProxyServer& proxy_server, base::TimeDelta* retry_delay) const { DCHECK(thread_checker_.CalledOnValidThread()); - net::ProxyRetryInfoMap::const_iterator found = - retry_map.find(proxy_server.ToURI()); + auto found = retry_map.find(proxy_server.ToURI()); if (found == retry_map.end() || found->second.bad_until < GetTicksNow()) { return false;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h index 33665e8..e793657 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -107,11 +107,11 @@ // disables the use of alternative protocols and proxies. // |url_request_context_getter| is the default net::URLRequestContextGetter // used for making URL requests. - void InitializeOnIOThread(const scoped_refptr<net::URLRequestContextGetter>& - basic_url_request_context_getter, - const scoped_refptr<net::URLRequestContextGetter>& - url_request_context_getter, - NetworkPropertiesManager* manager); + void InitializeOnIOThread( + const scoped_refptr<net::URLRequestContextGetter>& + basic_url_request_context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + NetworkPropertiesManager* manager); // Sets the proxy configs, enabling or disabling the proxy according to // the value of |enabled|. If |restricted| is true, only enable the fallback
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc index 0b08eb0..a7d7fd4 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -436,7 +436,7 @@ base::DefaultClock::GetInstance(), test_context_->pref_service(), test_context_->task_runner()); config.InitializeOnIOThread(test_context_->request_context_getter(), - test_context_->request_context_getter(), + test_context_->url_loader_factory(), &network_properties_manager); RunUntilIdle();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc index d0987c1..389fb85 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -211,6 +211,7 @@ DCHECK(ui_task_runner_->BelongsToCurrentThread()); service_ = data_reduction_proxy_service; url_request_context_getter_ = service_->url_request_context_getter(); + url_loader_factory_info_ = service_->url_loader_factory_info(); // Using base::Unretained is safe here, unless the browser is being shut down // before the Initialize task can be executed. The task is only created as // part of class initialization. @@ -226,8 +227,13 @@ void DataReductionProxyIOData::InitializeOnIOThread() { DCHECK(io_task_runner_->BelongsToCurrentThread()); DCHECK(network_properties_manager_); + + DCHECK(url_loader_factory_info_); + auto url_loader_factory = network::SharedURLLoaderFactory::Create( + std::move(url_loader_factory_info_)); + config_->InitializeOnIOThread(basic_url_request_context_getter_.get(), - url_request_context_getter_, + url_loader_factory, network_properties_manager_.get()); bypass_stats_->InitializeOnIOThread(); proxy_delegate_->InitializeOnIOThread(this);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h index 79b7c7dc..ba85b72 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
@@ -39,6 +39,7 @@ namespace network { class NetworkConnectionTracker; +class SharedURLLoaderFactoryInfo; } namespace data_reduction_proxy { @@ -318,6 +319,9 @@ // does not use alternate protocols. scoped_refptr<net::URLRequestContextGetter> basic_url_request_context_getter_; + // The network::SharedURLLoaderFactoryInfo used for making URL requests. + std::unique_ptr<network::SharedURLLoaderFactoryInfo> url_loader_factory_info_; + // The production channel of this build. const std::string channel_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc index 3f2e4d5..28d20e7 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
@@ -34,6 +34,7 @@ DataReductionProxySettings* settings, PrefService* prefs, net::URLRequestContextGetter* request_context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, std::unique_ptr<DataStore> store, std::unique_ptr<DataReductionProxyPingbackClient> pingback_client, network::NetworkQualityTracker* network_quality_tracker, @@ -42,6 +43,7 @@ const scoped_refptr<base::SequencedTaskRunner>& db_task_runner, const base::TimeDelta& commit_delay) : url_request_context_getter_(request_context_getter), + url_loader_factory_(std::move(url_loader_factory)), pingback_client_(std::move(pingback_client)), settings_(settings), prefs_(prefs),
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h index 320e0097..70bd015 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
@@ -23,6 +23,7 @@ #include "components/data_use_measurement/core/data_use_user_data.h" #include "net/nqe/effective_connection_type.h" #include "services/network/public/cpp/network_quality_tracker.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" class PrefService; @@ -64,6 +65,7 @@ DataReductionProxySettings* settings, PrefService* prefs, net::URLRequestContextGetter* request_context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, std::unique_ptr<DataStore> store, std::unique_ptr<DataReductionProxyPingbackClient> pingback_client, network::NetworkQualityTracker* network_quality_tracker, @@ -166,6 +168,11 @@ return url_request_context_getter_; } + std::unique_ptr<network::SharedURLLoaderFactoryInfo> url_loader_factory_info() + const { + return url_loader_factory_->Clone(); + } + DataReductionProxyPingbackClient* pingback_client() const { return pingback_client_.get(); } @@ -188,6 +195,7 @@ void ReadPersistedClientConfig(); net::URLRequestContextGetter* url_request_context_getter_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; // Tracks compression statistics to be displayed to the user. std::unique_ptr<DataReductionProxyCompressionStats> compression_stats_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc index f206866..1adc9737 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -43,8 +43,10 @@ #include "net/url_request/url_request_intercepting_job_factory.h" #include "net/url_request/url_request_job_factory_impl.h" #include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/test/test_network_connection_tracker.h" #include "services/network/test/test_network_quality_tracker.h" +#include "services/network/test/test_shared_url_loader_factory.h" #include "url/gurl.h" namespace { @@ -241,10 +243,12 @@ network::TestNetworkQualityTracker* test_network_quality_tracker, PrefService* prefs, net::URLRequestContextGetter* request_context, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) : DataReductionProxyService(settings, prefs, request_context, + std::move(url_loader_factory), std::make_unique<TestDataStore>(), nullptr, test_network_quality_tracker, @@ -429,6 +433,7 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner = base::ThreadTaskRunnerHandle::Get(); scoped_refptr<net::URLRequestContextGetter> request_context_getter; + scoped_refptr<network::TestSharedURLLoaderFactory> url_loader_factory; std::unique_ptr<TestingPrefServiceSimple> pref_service( new TestingPrefServiceSimple()); std::unique_ptr<net::TestNetLog> net_log(new net::TestNetLog()); @@ -451,6 +456,14 @@ task_runner, std::move(test_request_context)); } + // In theory, when the other related classes (namely SecureProxyChecker + // and DataReductionProxyConfigServiceClient) get migrated away from + // using URLFetcher in favor of SimpleURLLoader, there will be a + // Builder::WithURLLoaderFactory, and specific tests will pass in + // a URLLoaderFactory instance. For now, we can just create our own. + url_loader_factory = + base::MakeRefCounted<network::TestSharedURLLoaderFactory>(); + std::unique_ptr<TestDataReductionProxyEventStorageDelegate> storage_delegate( new TestDataReductionProxyEventStorageDelegate()); std::unique_ptr<DataReductionProxyEventCreator> event_creator( @@ -549,8 +562,8 @@ std::unique_ptr<DataReductionProxyTestContext> test_context( new DataReductionProxyTestContext( task_runner, std::move(pref_service), std::move(net_log), - request_context_getter, mock_socket_factory_, std::move(io_data), - std::move(settings), std::move(storage_delegate), + request_context_getter, url_loader_factory, mock_socket_factory_, + std::move(io_data), std::move(settings), std::move(storage_delegate), std::move(config_storer), raw_params, test_context_flags)); if (!skip_settings_initialization_) @@ -564,6 +577,7 @@ std::unique_ptr<TestingPrefServiceSimple> simple_pref_service, std::unique_ptr<net::TestNetLog> net_log, scoped_refptr<net::URLRequestContextGetter> request_context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, net::MockClientSocketFactory* mock_socket_factory, std::unique_ptr<TestDataReductionProxyIOData> io_data, std::unique_ptr<DataReductionProxySettings> settings, @@ -577,6 +591,7 @@ simple_pref_service_(std::move(simple_pref_service)), net_log_(std::move(net_log)), request_context_getter_(request_context_getter), + url_loader_factory_(std::move(url_loader_factory)), mock_socket_factory_(mock_socket_factory), io_data_(std::move(io_data)), settings_(std::move(settings)), @@ -652,11 +667,11 @@ return std::make_unique<MockDataReductionProxyService>( settings, test_network_quality_tracker_.get(), simple_pref_service_.get(), request_context_getter_.get(), - task_runner_); + url_loader_factory_, task_runner_); } return std::make_unique<DataReductionProxyService>( settings, simple_pref_service_.get(), request_context_getter_.get(), - base::WrapUnique(new TestDataStore()), nullptr, + url_loader_factory_, base::WrapUnique(new TestDataStore()), nullptr, test_network_quality_tracker_.get(), task_runner_, task_runner_, task_runner_, base::TimeDelta()); }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h index 157997d..2cdccaa 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
@@ -44,6 +44,7 @@ } namespace network { +class SharedURLLoaderFactory; class TestNetworkQualityTracker; } @@ -189,6 +190,7 @@ network::TestNetworkQualityTracker* test_network_quality_tracker, PrefService* prefs, net::URLRequestContextGetter* request_context, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); ~MockDataReductionProxyService() override; @@ -474,6 +476,10 @@ return request_context_getter_.get(); } + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory() const { + return url_loader_factory_; + } + DataReductionProxyBypassStats* bypass_stats() const { return io_data_->bypass_stats(); } @@ -527,6 +533,7 @@ std::unique_ptr<TestingPrefServiceSimple> simple_pref_service, std::unique_ptr<net::TestNetLog> net_log, scoped_refptr<net::URLRequestContextGetter> request_context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, net::MockClientSocketFactory* mock_socket_factory, std::unique_ptr<TestDataReductionProxyIOData> io_data, std::unique_ptr<DataReductionProxySettings> settings, @@ -545,6 +552,7 @@ std::unique_ptr<TestingPrefServiceSimple> simple_pref_service_; std::unique_ptr<net::TestNetLog> net_log_; scoped_refptr<net::URLRequestContextGetter> request_context_getter_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; // Non-owned pointer. Will be NULL if |this| was built without specifying a // |net::MockClientSocketFactory|. net::MockClientSocketFactory* mock_socket_factory_;
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc index 174048b9..32a815e 100644 --- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc +++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
@@ -17,29 +17,27 @@ #include "net/base/load_flags.h" #include "net/http/http_status_code.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_fetcher.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" -#include "net/url_request/url_request_status.h" #include "services/network/public/cpp/features.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" namespace data_reduction_proxy { +namespace { + +const int kInvalidResponseCode = -1; +} + WarmupURLFetcher::WarmupURLFetcher( - const scoped_refptr<net::URLRequestContextGetter>& - url_request_context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, WarmupURLFetcherCallback callback, GetHttpRttCallback get_http_rtt_callback) : is_fetch_in_flight_(false), previous_attempt_counts_(0), - url_request_context_getter_(url_request_context_getter), + url_loader_factory_(std::move(url_loader_factory)), callback_(callback), get_http_rtt_callback_(get_http_rtt_callback) { - // TODO(crbug.com/721403): DRP is disabled with network service enabled. When - // DRP is switched to mojo, we won't need URLRequestContext. - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { - DCHECK(url_request_context_getter_); - } + DCHECK(url_loader_factory_); } WarmupURLFetcher::~WarmupURLFetcher() {} @@ -109,29 +107,37 @@ GURL warmup_url_with_query_params; GetWarmupURLWithQueryParam(&warmup_url_with_query_params); - fetcher_.reset(); + url_loader_.reset(); fetch_timeout_timer_.Stop(); is_fetch_in_flight_ = true; - fetcher_ = - net::URLFetcher::Create(warmup_url_with_query_params, - net::URLFetcher::GET, this, traffic_annotation); - data_use_measurement::DataUseUserData::AttachToFetcher( - fetcher_.get(), - data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY); + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = warmup_url_with_query_params; // Do not disable cookies. This allows the warmup connection to be reused - // for fetching user initiated requests. - fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE); - fetcher_->SetRequestContext(url_request_context_getter_.get()); - // |fetcher| should not retry on 5xx errors. |fetcher_| should retry on + // for loading user initiated requests. + resource_request->load_flags = net::LOAD_BYPASS_CACHE; + + url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request), + traffic_annotation); + // |url_loader_| should not retry on 5xx errors. |url_loader_| should retry on // network changes since the network stack may receive the connection change // event later than |this|. static const int kMaxRetries = 5; - fetcher_->SetAutomaticallyRetryOn5xx(false); - fetcher_->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries); + url_loader_->SetRetryOptions( + kMaxRetries, network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE); + url_loader_->SetAllowHttpErrorResults(true); + fetch_timeout_timer_.Start(FROM_HERE, GetFetchTimeout(), this, &WarmupURLFetcher::OnFetchTimeout); - fetcher_->Start(); + + url_loader_->SetOnResponseStartedCallback(base::BindOnce( + &WarmupURLFetcher::OnURLLoadResponseStarted, base::Unretained(this))); + url_loader_->SetOnRedirectCallback(base::BindRepeating( + &WarmupURLFetcher::OnURLLoaderRedirect, base::Unretained(this))); + url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + url_loader_factory_.get(), + base::BindOnce(&WarmupURLFetcher::OnURLLoadComplete, + base::Unretained(this))); } void WarmupURLFetcher::GetWarmupURLWithQueryParam( @@ -151,31 +157,51 @@ warmup_url_with_query_params->has_query()); } -void WarmupURLFetcher::OnURLFetchComplete(const net::URLFetcher* source) { +void WarmupURLFetcher::OnURLLoadResponseStarted( + const GURL& final_url, + const network::ResourceResponseHead& response_head) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(source, fetcher_.get()); + proxy_server_ = response_head.proxy_server; +} + +void WarmupURLFetcher::OnURLLoaderRedirect( + const net::RedirectInfo& redirect_info, + const network::ResourceResponseHead& response_head, + std::vector<std::string>* to_be_removed_headers) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + proxy_server_ = response_head.proxy_server; +} + +void WarmupURLFetcher::OnURLLoadComplete( + std::unique_ptr<std::string> response_body) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(is_fetch_in_flight_); - UMA_HISTOGRAM_BOOLEAN( - "DataReductionProxy.WarmupURL.FetchSuccessful", - source->GetStatus().status() == net::URLRequestStatus::SUCCESS); + UMA_HISTOGRAM_BOOLEAN("DataReductionProxy.WarmupURL.FetchSuccessful", + !!response_body); base::UmaHistogramSparse("DataReductionProxy.WarmupURL.NetError", - std::abs(source->GetStatus().error())); + std::abs(url_loader_->NetError())); + + scoped_refptr<net::HttpResponseHeaders> response_headers; + int response_code = kInvalidResponseCode; + if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) { + response_headers = url_loader_->ResponseInfo()->headers; + response_code = response_headers->response_code(); + } base::UmaHistogramSparse("DataReductionProxy.WarmupURL.HttpResponseCode", - std::abs(source->GetResponseCode())); + std::abs(response_code)); - if (source->GetResponseHeaders()) { + if (response_headers) { UMA_HISTOGRAM_BOOLEAN( "DataReductionProxy.WarmupURL.HasViaHeader", - HasDataReductionProxyViaHeader(*source->GetResponseHeaders(), + HasDataReductionProxyViaHeader(*response_headers, nullptr /* has_intermediary */)); - - UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.WarmupURL.ProxySchemeUsed", - util::ConvertNetProxySchemeToProxyScheme( - source->ProxyServerUsed().scheme()), - PROXY_SCHEME_MAX); + UMA_HISTOGRAM_ENUMERATION( + "DataReductionProxy.WarmupURL.ProxySchemeUsed", + util::ConvertNetProxySchemeToProxyScheme(proxy_server_.scheme()), + PROXY_SCHEME_MAX); } if (!GetFieldTrialParamByFeatureAsBool( @@ -185,8 +211,7 @@ return; } - if (!source->GetStatus().is_success() && - source->GetStatus().error() == net::ERR_INTERNET_DISCONNECTED) { + if (url_loader_->NetError() == net::ERR_INTERNET_DISCONNECTED) { // Fetching failed due to Internet unavailability, and not due to some // error. No need to run the callback. CleanupAfterFetch(); @@ -194,15 +219,13 @@ } bool success_response = - source->GetStatus().status() == net::URLRequestStatus::SUCCESS && - params::IsWhitelistedHttpResponseCodeForProbes( - source->GetResponseCode()) && - source->GetResponseHeaders() && - HasDataReductionProxyViaHeader(*(source->GetResponseHeaders()), + response_body && + params::IsWhitelistedHttpResponseCodeForProbes(response_code) && + response_headers && + HasDataReductionProxyViaHeader(*response_headers, nullptr /* has_intermediary */); - callback_.Run(source->ProxyServerUsed(), success_response - ? FetchResult::kSuccessful - : FetchResult::kFailed); + callback_.Run(proxy_server_, success_response ? FetchResult::kSuccessful + : FetchResult::kFailed); CleanupAfterFetch(); } @@ -263,16 +286,15 @@ void WarmupURLFetcher::OnFetchTimeout() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(is_fetch_in_flight_); - DCHECK(fetcher_); + DCHECK(url_loader_); - const net::ProxyServer proxy_server = fetcher_->ProxyServerUsed(); - DCHECK_LE(1, proxy_server.scheme()); + DCHECK_LE(1, proxy_server_.scheme()); UMA_HISTOGRAM_BOOLEAN("DataReductionProxy.WarmupURL.FetchSuccessful", false); base::UmaHistogramSparse("DataReductionProxy.WarmupURL.NetError", net::ERR_ABORTED); base::UmaHistogramSparse("DataReductionProxy.WarmupURL.HttpResponseCode", - std::abs(net::URLFetcher::RESPONSE_CODE_INVALID)); + std::abs(kInvalidResponseCode)); if (!GetFieldTrialParamByFeatureAsBool( features::kDataReductionProxyRobustConnection, @@ -282,13 +304,14 @@ return; } - callback_.Run(proxy_server, FetchResult::kTimedOut); + callback_.Run(proxy_server_, FetchResult::kTimedOut); CleanupAfterFetch(); } void WarmupURLFetcher::CleanupAfterFetch() { is_fetch_in_flight_ = false; - fetcher_.reset(); + url_loader_.reset(); + proxy_server_ = net::ProxyServer(); fetch_timeout_timer_.Stop(); fetch_delay_timer_.Stop(); }
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h index 6e186d9bf..89128c6d 100644 --- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h +++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h
@@ -13,22 +13,23 @@ #include "base/optional.h" #include "base/sequence_checker.h" #include "base/timer/timer.h" -#include "net/url_request/url_fetcher_delegate.h" +#include "net/base/proxy_server.h" class GURL; namespace net { - -class ProxyServer; -class URLFetcher; -class URLRequestContextGetter; - +struct RedirectInfo; } // namespace net +namespace network { +struct ResourceResponseHead; +class SharedURLLoaderFactory; +class SimpleURLLoader; +} // namespace network + namespace data_reduction_proxy { -// URLFetcherDelegate for fetching the warmup URL. -class WarmupURLFetcher : public net::URLFetcherDelegate { +class WarmupURLFetcher { public: enum class FetchResult { kFailed, kSuccessful, kTimedOut }; @@ -41,14 +42,14 @@ typedef base::RepeatingCallback<base::Optional<base::TimeDelta>()> GetHttpRttCallback; - WarmupURLFetcher(const scoped_refptr<net::URLRequestContextGetter>& - url_request_context_getter, - WarmupURLFetcherCallback callback, - GetHttpRttCallback get_http_rtt_callback); + WarmupURLFetcher( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + WarmupURLFetcherCallback callback, + GetHttpRttCallback get_http_rtt_callback); - ~WarmupURLFetcher() override; + virtual ~WarmupURLFetcher(); - // Creates and starts a URLFetcher that fetches the warmup URL. + // Creates and starts a URLLoader that loads the warmup URL. // |previous_attempt_counts| is the count of fetch attempts that have been // made to the proxy which is being probed. The fetching may happen after some // delay depending on |previous_attempt_counts|. @@ -73,11 +74,22 @@ // Called when the fetch timeouts. void OnFetchTimeout(); - void OnURLFetchComplete(const net::URLFetcher* source) override; + // URL loader callback when response starts. + void OnURLLoadResponseStarted( + const GURL& final_url, + const network::ResourceResponseHead& response_head); - // The URLFetcher being used for fetching the warmup URL. Protected for + // URL loader callback for redirections. + void OnURLLoaderRedirect(const net::RedirectInfo& redirect_info, + const network::ResourceResponseHead& response_head, + std::vector<std::string>* to_be_removed_headers); + + // URL loader completion callback. + void OnURLLoadComplete(std::unique_ptr<std::string> response_body); + + // The URLLoader being used for loading the warmup URL. Protected for // testing. - std::unique_ptr<net::URLFetcher> fetcher_; + std::unique_ptr<network::SimpleURLLoader> url_loader_; // Timer used to delay the fetching of the warmup probe URL. base::OneShotTimer fetch_delay_timer_; @@ -85,11 +97,14 @@ // Timer to enforce timeout of fetching the warmup URL. base::OneShotTimer fetch_timeout_timer_; - // True if the fetcher for warmup URL is in-flight. + // True if the loader for warmup URL is in-flight. bool is_fetch_in_flight_; + // Proxy server used on the last resource loaded. + net::ProxyServer proxy_server_; + private: - // Creates and immediately starts a URLFetcher that fetches the warmup URL. + // Creates and immediately starts a URLLoader that fetches the warmup URL. void FetchWarmupURLNow(); // Resets the variable after the fetching of the warmup URL has completed or @@ -100,7 +115,7 @@ // probed. size_t previous_attempt_counts_; - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; // Callback that should be executed when the fetching of the warmup URL is // completed.
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc index 299a602..3f5e383 100644 --- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc +++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
@@ -16,6 +16,7 @@ #include "base/test/gtest_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/platform_thread.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_util.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h" @@ -23,9 +24,9 @@ #include "net/base/proxy_server.h" #include "net/http/http_status_code.h" #include "net/socket/socket_test_util.h" -#include "net/url_request/url_fetcher.h" -#include "net/url_request/url_request_context_getter.h" -#include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "services/network/test/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -35,16 +36,15 @@ class WarmupURLFetcherTest : public WarmupURLFetcher { public: - WarmupURLFetcherTest(const scoped_refptr<net::URLRequestContextGetter>& - url_request_context_getter) + WarmupURLFetcherTest( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) : WarmupURLFetcher( - url_request_context_getter, + std::move(url_loader_factory), base::BindRepeating( &WarmupURLFetcherTest::HandleWarmupFetcherResponse, base::Unretained(this)), base::BindRepeating(&WarmupURLFetcherTest::GetHttpRttEstimate, base::Unretained(this))) {} - ~WarmupURLFetcherTest() override {} size_t callback_received_count() const { return callback_received_count_; } @@ -104,7 +104,7 @@ using WarmupURLFetcher::FetchWarmupURL; using WarmupURLFetcher::GetWarmupURLWithQueryParam; using WarmupURLFetcher::OnFetchTimeout; - using WarmupURLFetcher::OnURLFetchComplete; + using WarmupURLFetcher::OnURLLoadComplete; base::TimeDelta GetFetchTimeout() const override { if (!fetch_timeout_) @@ -113,14 +113,12 @@ } void VerifyStateCleanedUp() const { - DCHECK(!fetcher_); + DCHECK(!url_loader_); DCHECK(!fetch_delay_timer_.IsRunning()); DCHECK(!fetch_timeout_timer_.IsRunning()); DCHECK(!is_fetch_in_flight_); } - net::URLFetcher* fetcher() const { return fetcher_.get(); } - void SetHttpRttOverride(base::TimeDelta http_rtt) { http_rtt_override_ = http_rtt; } @@ -149,11 +147,13 @@ // Test that query param for the warmup URL is randomly set. TEST(WarmupURLFetcherTest, TestGetWarmupURLWithQueryParam) { - base::MessageLoopForIO message_loop; - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner()); + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); GURL gurl_original; warmup_url_fetcher.GetWarmupURLWithQueryParam(&gurl_original); @@ -185,35 +185,28 @@ base::test::ScopedFeatureList scoped_feature_list; WarmupURLFetcherTest::InitExperiment(&scoped_feature_list); + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); + base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - const std::string config = "foobarbaz"; - std::vector<std::unique_ptr<net::SocketDataProvider>> socket_data_providers; - net::MockClientSocketFactory mock_socket_factory; - net::MockRead success_reads[3]; - success_reads[0] = net::MockRead("HTTP/1.1 200 OK\r\n\r\n"); - success_reads[1] = net::MockRead(net::ASYNC, config.c_str(), config.length()); - success_reads[2] = net::MockRead(net::SYNCHRONOUS, net::OK); - socket_data_providers.push_back( - std::make_unique<net::StaticSocketDataProvider>( - success_reads, base::span<net::MockWrite>())); - mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get()); - - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); - - test_request_context->set_client_socket_factory(&mock_socket_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); warmup_url_fetcher.FetchWarmupURL(0); EXPECT_TRUE(warmup_url_fetcher.IsFetchInFlight()); - base::RunLoop().RunUntilIdle(); + scoped_task_environment.RunUntilIdle(); + + auto resource_response_head = + network::CreateResourceResponseHead(net::HTTP_OK); + resource_response_head.proxy_server = + net::ProxyServer(net::ProxyServer::SCHEME_DIRECT, net::HostPortPair()); + test_url_loader_factory.SimulateResponseWithoutRemovingFromPendingList( + test_url_loader_factory.GetPendingRequest(0), resource_response_head, + "foobarbaz", network::URLLoaderCompletionStatus(net::OK)); + EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); histogram_tester.ExpectUniqueSample( @@ -245,36 +238,31 @@ base::test::ScopedFeatureList scoped_feature_list; WarmupURLFetcherTest::InitExperiment(&scoped_feature_list); + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); + base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - const std::string config = "foobarbaz"; - std::vector<std::unique_ptr<net::SocketDataProvider>> socket_data_providers; - net::MockClientSocketFactory mock_socket_factory; - net::MockRead success_reads[3]; - success_reads[0] = net::MockRead( - "HTTP/1.1 404 NOT FOUND\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"); - success_reads[1] = net::MockRead(net::ASYNC, config.c_str(), config.length()); - success_reads[2] = net::MockRead(net::SYNCHRONOUS, net::OK); - socket_data_providers.push_back( - std::make_unique<net::StaticSocketDataProvider>( - success_reads, base::span<net::MockWrite>())); - mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get()); - - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); - - test_request_context->set_client_socket_factory(&mock_socket_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); warmup_url_fetcher.FetchWarmupURL(0); EXPECT_TRUE(warmup_url_fetcher.IsFetchInFlight()); - base::RunLoop().RunUntilIdle(); + scoped_task_environment.RunUntilIdle(); + + auto resource_response_head = + network::CreateResourceResponseHead(net::HTTP_NOT_FOUND); + resource_response_head.proxy_server = + net::ProxyServer(net::ProxyServer::SCHEME_DIRECT, net::HostPortPair()); + static const char kDataReductionProxyViaValue[] = + "Via: 1.1 Chrome-Compression-Proxy"; + resource_response_head.headers->AddHeader(kDataReductionProxyViaValue); + test_url_loader_factory.SimulateResponseWithoutRemovingFromPendingList( + test_url_loader_factory.GetPendingRequest(0), resource_response_head, + "foobarbaz", network::URLLoaderCompletionStatus(net::OK)); + EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); histogram_tester.ExpectUniqueSample( @@ -306,35 +294,29 @@ TEST(WarmupURLFetcherTest, TestSuccessfulFetchWarmupURLWithViaHeaderExperimentNotEnabled) { + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); + base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - const std::string config = "foobarbaz"; - std::vector<std::unique_ptr<net::SocketDataProvider>> socket_data_providers; - net::MockClientSocketFactory mock_socket_factory; - net::MockRead success_reads[3]; - success_reads[0] = net::MockRead( - "HTTP/1.1 204 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"); - success_reads[1] = net::MockRead(net::ASYNC, config.c_str(), config.length()); - success_reads[2] = net::MockRead(net::SYNCHRONOUS, net::OK); - socket_data_providers.push_back( - std::make_unique<net::StaticSocketDataProvider>( - success_reads, base::span<net::MockWrite>())); - mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get()); - - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); - - test_request_context->set_client_socket_factory(&mock_socket_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); warmup_url_fetcher.FetchWarmupURL(0); base::RunLoop().RunUntilIdle(); + auto resource_response_head = + network::CreateResourceResponseHead(net::HTTP_NO_CONTENT); + resource_response_head.proxy_server = + net::ProxyServer(net::ProxyServer::SCHEME_DIRECT, net::HostPortPair()); + static const char kDataReductionProxyViaValue[] = + "Via: 1.1 Chrome-Compression-Proxy"; + resource_response_head.headers->AddHeader(kDataReductionProxyViaValue); + test_url_loader_factory.SimulateResponseWithoutRemovingFromPendingList( + test_url_loader_factory.GetPendingRequest(0), resource_response_head, + "foobarbaz", network::URLLoaderCompletionStatus(net::OK)); + histogram_tester.ExpectUniqueSample( "DataReductionProxy.WarmupURL.FetchInitiated", 1, 1); histogram_tester.ExpectUniqueSample( @@ -359,35 +341,28 @@ base::test::ScopedFeatureList scoped_feature_list; WarmupURLFetcherTest::InitExperiment(&scoped_feature_list); + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); + base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - const std::string config = "foobarbaz"; - std::vector<std::unique_ptr<net::SocketDataProvider>> socket_data_providers; - net::MockClientSocketFactory mock_socket_factory; - net::MockRead success_reads[1]; - success_reads[0] = net::MockRead(net::SYNCHRONOUS, net::ERR_CONNECTION_RESET); - socket_data_providers.push_back( - std::make_unique<net::StaticSocketDataProvider>( - success_reads, base::span<net::MockWrite>())); - mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get()); - - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); - - test_request_context->set_client_socket_factory(&mock_socket_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); warmup_url_fetcher.FetchWarmupURL(0); EXPECT_TRUE(warmup_url_fetcher.IsFetchInFlight()); base::RunLoop().RunUntilIdle(); + + test_url_loader_factory.SimulateResponseWithoutRemovingFromPendingList( + test_url_loader_factory.GetPendingRequest(0), + network::ResourceResponseHead(), "foobarbaz", + network::URLLoaderCompletionStatus(net::ERR_CONNECTION_RESET)); + EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); + const int kInvalidHttpResponseCode = -1; histogram_tester.ExpectUniqueSample( "DataReductionProxy.WarmupURL.FetchInitiated", 1, 1); histogram_tester.ExpectUniqueSample( @@ -396,7 +371,7 @@ std::abs(net::ERR_CONNECTION_RESET), 1); histogram_tester.ExpectUniqueSample( "DataReductionProxy.WarmupURL.HttpResponseCode", - std::abs(net::URLFetcher::RESPONSE_CODE_INVALID), 1); + std::abs(kInvalidHttpResponseCode), 1); histogram_tester.ExpectTotalCount("DataReductionProxy.WarmupURL.HasViaHeader", 0); histogram_tester.ExpectTotalCount( @@ -413,32 +388,15 @@ base::test::ScopedFeatureList scoped_feature_list; WarmupURLFetcherTest::InitExperiment(&scoped_feature_list); + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); + base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - const std::string config = "foobarbaz"; - std::vector<std::unique_ptr<net::SocketDataProvider>> socket_data_providers; - net::MockClientSocketFactory mock_socket_factory; - net::MockRead success_reads[3]; - success_reads[0] = net::MockRead( - "HTTP/1.1 204 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"); - success_reads[1] = net::MockRead(net::ASYNC, config.c_str(), config.length()); - success_reads[2] = net::MockRead(net::SYNCHRONOUS, net::OK); - socket_data_providers.push_back( - std::make_unique<net::StaticSocketDataProvider>( - success_reads, base::span<net::MockWrite>())); - mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get()); - - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); - - test_request_context->set_client_socket_factory(&mock_socket_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); // Set the timeout to a very low value. This should cause warmup URL fetcher // to run the callback with appropriate error code. warmup_url_fetcher.SetFetchTimeout(base::TimeDelta::FromSeconds(0)); @@ -463,43 +421,39 @@ // If the URL fetch completes, it should cause DCHECK to trigger. EXPECT_DCHECK_DEATH( - warmup_url_fetcher.OnURLFetchComplete(warmup_url_fetcher.fetcher())); + warmup_url_fetcher.OnURLLoadComplete(std::make_unique<std::string>())); } TEST(WarmupURLFetcherTest, TestSuccessfulFetchWarmupURLWithDelay) { base::test::ScopedFeatureList scoped_feature_list; WarmupURLFetcherTest::InitExperiment(&scoped_feature_list); + base::test::ScopedTaskEnvironment scoped_task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME); + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); + base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - const std::string config = "foobarbaz"; - std::vector<std::unique_ptr<net::SocketDataProvider>> socket_data_providers; - net::MockClientSocketFactory mock_socket_factory; - net::MockRead success_reads[3]; - success_reads[0] = net::MockRead( - "HTTP/1.1 404\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"); - success_reads[1] = net::MockRead(net::ASYNC, config.c_str(), config.length()); - success_reads[2] = net::MockRead(net::SYNCHRONOUS, net::OK); - socket_data_providers.push_back( - std::make_unique<net::StaticSocketDataProvider>( - success_reads, base::span<net::MockWrite>())); - mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get()); - - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); - - test_request_context->set_client_socket_factory(&mock_socket_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); warmup_url_fetcher.SetFetchWaitTime(base::TimeDelta::FromMilliseconds(1)); warmup_url_fetcher.FetchWarmupURL(1); - base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(2)); + scoped_task_environment.FastForwardBy(base::TimeDelta::FromMilliseconds(2)); + + auto resource_response_head = + network::CreateResourceResponseHead(net::HTTP_NOT_FOUND); + resource_response_head.proxy_server = + net::ProxyServer(net::ProxyServer::SCHEME_DIRECT, net::HostPortPair()); + static const char kDataReductionProxyViaValue[] = + "Via: 1.1 Chrome-Compression-Proxy"; + resource_response_head.headers->AddHeader(kDataReductionProxyViaValue); + test_url_loader_factory.SimulateResponseWithoutRemovingFromPendingList( + test_url_loader_factory.GetPendingRequest(0), resource_response_head, + "foobarbaz", network::URLLoaderCompletionStatus(net::OK)); + EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); @@ -535,17 +489,14 @@ constexpr base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(60); base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); EXPECT_EQ(kMinTimeout, warmup_url_fetcher.GetFetchTimeout()); @@ -570,17 +521,14 @@ TEST(WarmupURLFetcherTest, TestFetchWaitTime) { base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); warmup_url_fetcher.FetchWarmupURL(1); @@ -604,17 +552,14 @@ &scoped_feature_list, first_retry, second_retry); base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); warmup_url_fetcher.FetchWarmupURL(1); @@ -636,17 +581,14 @@ constexpr base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(60); base::HistogramTester histogram_tester; - base::MessageLoopForIO message_loop; - std::unique_ptr<net::TestURLRequestContext> test_request_context( - new net::TestURLRequestContext(true)); + base::test::ScopedTaskEnvironment scoped_task_environment; + network::TestURLLoaderFactory test_url_loader_factory; + auto test_shared_url_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); - test_request_context->Init(); - scoped_refptr<net::URLRequestContextGetter> request_context_getter = - new net::TestURLRequestContextGetter(message_loop.task_runner(), - std::move(test_request_context)); - - WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + WarmupURLFetcherTest warmup_url_fetcher(test_shared_url_loader_factory); EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); EXPECT_EQ(kMinTimeout, warmup_url_fetcher.GetFetchTimeout());
diff --git a/components/device_event_log/device_event_log_impl.cc b/components/device_event_log/device_event_log_impl.cc index a7f82c1..9f5c4352a 100644 --- a/components/device_event_log/device_event_log_impl.cc +++ b/components/device_event_log/device_event_log_impl.cc
@@ -309,8 +309,7 @@ // Remove the first (oldest) non-error entry, or the oldest entry if more // than half the entries are errors. size_t error_count = 0; - for (LogEntryList::iterator iter = entries_.begin(); iter != entries_.end(); - ++iter) { + for (auto iter = entries_.begin(); iter != entries_.end(); ++iter) { if (iter->log_level != LOG_LEVEL_ERROR) { entries_.erase(iter); return; @@ -403,10 +402,10 @@ } void DeviceEventLogImpl::Clear(const base::Time& begin, const base::Time& end) { - LogEntryList::iterator begin_it = std::find_if( + auto begin_it = std::find_if( entries_.begin(), entries_.end(), [begin](const LogEntry& entry) { return entry.time >= begin; }); - LogEntryList::reverse_iterator end_rev_it = + auto end_rev_it = std::find_if(entries_.rbegin(), entries_.rend(), [end](const LogEntry& entry) { return entry.time <= end; });
diff --git a/components/discardable_memory/common/discardable_shared_memory_heap.cc b/components/discardable_memory/common/discardable_shared_memory_heap.cc index b650e58..d750db40 100644 --- a/components/discardable_memory/common/discardable_shared_memory_heap.cc +++ b/components/discardable_memory/common/discardable_shared_memory_heap.cc
@@ -146,7 +146,7 @@ num_free_blocks_ += span->length_; // Merge with previous span if possible. - SpanMap::iterator prev_it = spans_.find(span->start_ - 1); + auto prev_it = spans_.find(span->start_ - 1); if (prev_it != spans_.end() && IsInFreeList(prev_it->second)) { std::unique_ptr<Span> prev = RemoveFromFreeList(prev_it->second); DCHECK_EQ(prev->start_ + prev->length_, span->start_); @@ -159,7 +159,7 @@ } // Merge with next span if possible. - SpanMap::iterator next_it = spans_.find(span->start_ + span->length_); + auto next_it = spans_.find(span->start_ + span->length_); if (next_it != spans_.end() && IsInFreeList(next_it->second)) { std::unique_ptr<Span> next = RemoveFromFreeList(next_it->second); DCHECK_EQ(next->start_, span->start_ + span->length_);
diff --git a/components/discardable_memory/service/discardable_shared_memory_manager.cc b/components/discardable_memory/service/discardable_shared_memory_manager.cc index 99fcdfe..3d24cbd 100644 --- a/components/discardable_memory/service/discardable_shared_memory_manager.cc +++ b/components/discardable_memory/service/discardable_shared_memory_manager.cc
@@ -478,7 +478,7 @@ MemorySegmentMap& client_segments = clients_[client_id]; - MemorySegmentMap::iterator segment_it = client_segments.find(id); + auto segment_it = client_segments.find(id); if (segment_it == client_segments.end()) { LOG(ERROR) << "Invalid discardable shared memory ID"; return;
diff --git a/components/dom_distiller/core/distiller.cc b/components/dom_distiller/core/distiller.cc index 599af501..86cf468 100644 --- a/components/dom_distiller/core/distiller.cc +++ b/components/dom_distiller/core/distiller.cc
@@ -127,7 +127,7 @@ void DistillerImpl::DistillNextPage() { if (!waiting_pages_.empty()) { - std::map<int, GURL>::iterator front = waiting_pages_.begin(); + auto front = waiting_pages_.begin(); int page_num = front->first; const GURL url = front->second; @@ -382,9 +382,8 @@ std::vector<scoped_refptr<ArticleDistillationUpdate::RefCountedPageProto> > update_pages; - for (std::map<int, size_t>::const_iterator it = finished_pages_index_.begin(); - it != finished_pages_index_.end(); - ++it) { + for (auto it = finished_pages_index_.begin(); + it != finished_pages_index_.end(); ++it) { update_pages.push_back(pages_[it->second]->distilled_page_proto); } return ArticleDistillationUpdate(update_pages, has_next_page, has_prev_page); @@ -397,7 +396,7 @@ std::unique_ptr<DistilledArticleProto> article_proto( new DistilledArticleProto()); // Stitch the pages back into the article. - for (std::map<int, size_t>::iterator it = finished_pages_index_.begin(); + for (auto it = finished_pages_index_.begin(); it != finished_pages_index_.end();) { DistilledPageData* page_data = GetPageAtIndex(it->second); *(article_proto->add_pages()) = page_data->distilled_page_proto->data;
diff --git a/components/dom_distiller/core/dom_distiller_model.cc b/components/dom_distiller/core/dom_distiller_model.cc index 0450381..2bdd539 100644 --- a/components/dom_distiller/core/dom_distiller_model.cc +++ b/components/dom_distiller/core/dom_distiller_model.cc
@@ -48,7 +48,7 @@ bool DomDistillerModel::GetKeyById(const std::string& entry_id, KeyType* key) const { - StringToKeyMap::const_iterator it = entry_id_to_key_map_.find(entry_id); + auto it = entry_id_to_key_map_.find(entry_id); if (it == entry_id_to_key_map_.end()) { return false; } @@ -59,7 +59,7 @@ } bool DomDistillerModel::GetKeyByUrl(const GURL& url, KeyType* key) const { - StringToKeyMap::const_iterator it = url_to_key_map_.find(url.spec()); + auto it = url_to_key_map_.find(url.spec()); if (it == url_to_key_map_.end()) { return false; } @@ -71,7 +71,7 @@ void DomDistillerModel::GetEntryByKey(KeyType key, ArticleEntry* entry) const { if (entry != nullptr) { - EntryMap::const_iterator it = entries_.find(key); + auto it = entries_.find(key); DCHECK(it != entries_.end()); *entry = it->second; } @@ -83,8 +83,7 @@ std::vector<ArticleEntry> DomDistillerModel::GetEntries() const { std::vector<ArticleEntry> entries_list; - for (EntryMap::const_iterator it = entries_.begin(); it != entries_.end(); - ++it) { + for (auto it = entries_.begin(); it != entries_.end(); ++it) { entries_list.push_back(it->second); } return entries_list; @@ -92,8 +91,7 @@ SyncDataList DomDistillerModel::GetAllSyncData() const { SyncDataList data; - for (EntryMap::const_iterator it = entries_.begin(); it != entries_.end(); - ++it) { + for (auto it = entries_.begin(); it != entries_.end(); ++it) { data.push_back(CreateLocalData(it->second)); } return data; @@ -105,7 +103,7 @@ SyncChangeList* changes_missing) { typedef base::hash_set<std::string> StringSet; StringSet entries_to_change; - for (SyncDataList::const_iterator it = data.begin(); it != data.end(); ++it) { + for (auto it = data.begin(); it != data.end(); ++it) { std::string entry_id = GetEntryIdFromSyncData(*it); std::pair<StringSet::iterator, bool> insert_result = entries_to_change.insert(entry_id); @@ -136,8 +134,7 @@ DCHECK(changes_applied); DCHECK(changes_missing); - for (SyncChangeList::const_iterator it = changes.begin(); it != changes.end(); - ++it) { + for (auto it = changes.begin(); it != changes.end(); ++it) { ApplyChangeToModel(*it, changes_applied, changes_missing); } }
diff --git a/components/dom_distiller/core/dom_distiller_store.cc b/components/dom_distiller/core/dom_distiller_store.cc index 3ea3751..06cbad4 100644 --- a/components/dom_distiller/core/dom_distiller_store.cc +++ b/components/dom_distiller/core/dom_distiller_store.cc
@@ -142,8 +142,7 @@ void DomDistillerStore::NotifyObservers(const syncer::SyncChangeList& changes) { if (observers_.might_have_observers() && changes.size() > 0) { std::vector<DomDistillerObserver::ArticleUpdate> article_changes; - for (SyncChangeList::const_iterator it = changes.begin(); - it != changes.end(); ++it) { + for (auto it = changes.begin(); it != changes.end(); ++it) { DomDistillerObserver::ArticleUpdate article_update; switch (it->change_type()) { case SyncChange::ACTION_ADD: @@ -197,8 +196,7 @@ database_loaded_ = true; SyncDataList data; - for (EntryVector::iterator it = entries->begin(); it != entries->end(); - ++it) { + for (auto it = entries->begin(); it != entries->end(); ++it) { data.push_back(CreateLocalData(*it)); } SyncChangeList changes_applied; @@ -229,8 +227,7 @@ std::unique_ptr<std::vector<std::string>> keys_to_remove( new std::vector<std::string>()); - for (SyncChangeList::const_iterator it = change_list.begin(); - it != change_list.end(); ++it) { + for (auto it = change_list.begin(); it != change_list.end(); ++it) { if (it->change_type() == SyncChange::ACTION_DELETE) { ArticleEntry entry = GetEntryFromChange(*it); keys_to_remove->push_back(entry.entry_id());
diff --git a/components/dom_distiller/core/dom_distiller_store_unittest.cc b/components/dom_distiller/core/dom_distiller_store_unittest.cc index 5521797..762a8f5 100644 --- a/components/dom_distiller/core/dom_distiller_store_unittest.cc +++ b/components/dom_distiller/core/dom_distiller_store_unittest.cc
@@ -69,8 +69,7 @@ SyncError ProcessSyncChanges(const base::Location&, const syncer::SyncChangeList& changes) override { - for (SyncChangeList::const_iterator it = changes.begin(); - it != changes.end(); ++it) { + for (auto it = changes.begin(); it != changes.end(); ++it) { AddEntry(GetEntryFromChange(*it), model_); } return SyncError(); @@ -155,7 +154,7 @@ SyncDataList SyncDataFromEntryMap(const EntryMap& model) { SyncDataList data; - for (EntryMap::const_iterator it = model.begin(); it != model.end(); ++it) { + for (auto it = model.begin(); it != model.end(); ++it) { data.push_back(CreateSyncData(it->second)); } return data; @@ -181,9 +180,8 @@ return AssertionFailure() << "Expected " << expected_entries.size() << " entries but found " << entries.size(); - for (DomDistillerStore::EntryVector::const_iterator it = entries.begin(); - it != entries.end(); ++it) { - EntryMap::iterator expected_it = expected_entries.find(it->entry_id()); + for (auto it = entries.begin(); it != entries.end(); ++it) { + auto expected_it = expected_entries.find(it->entry_id()); if (expected_it == expected_entries.end()) { return AssertionFailure() << "Found unexpected entry with id <" << it->entry_id() << ">"; @@ -199,7 +197,7 @@ AssertionResult AreEntryMapsEqual(const EntryMap& left, const EntryMap& right) { DomDistillerStore::EntryVector entries; - for (EntryMap::const_iterator it = left.begin(); it != left.end(); ++it) { + for (auto it = left.begin(); it != left.end(); ++it) { entries.push_back(it->second); } return AreEntriesEqual(entries, right);
diff --git a/components/dom_distiller/core/dom_distiller_test_util.cc b/components/dom_distiller/core/dom_distiller_test_util.cc index 0b49d31..a69c7b7 100644 --- a/components/dom_distiller/core/dom_distiller_test_util.cc +++ b/components/dom_distiller/core/dom_distiller_test_util.cc
@@ -18,8 +18,7 @@ std::vector<ArticleEntry> EntryMapToList( const FakeDB<ArticleEntry>::EntryMap& entries) { std::vector<ArticleEntry> entry_list; - for (FakeDB<ArticleEntry>::EntryMap::const_iterator it = entries.begin(); - it != entries.end(); ++it) { + for (auto it = entries.begin(); it != entries.end(); ++it) { entry_list.push_back(it->second); } return entry_list; @@ -59,9 +58,7 @@ void ObserverUpdatesMatcher::DescribeUpdates(std::ostream* os) const { bool start = true; - for (std::vector<DomDistillerObserver::ArticleUpdate>::const_iterator i = - expected_updates_.begin(); - i != expected_updates_.end(); ++i) { + for (auto i = expected_updates_.begin(); i != expected_updates_.end(); ++i) { if (start) { start = false; } else {
diff --git a/components/dom_distiller/webui/dom_distiller_handler.cc b/components/dom_distiller/webui/dom_distiller_handler.cc index eebfca30..a3ad0bb 100644 --- a/components/dom_distiller/webui/dom_distiller_handler.cc +++ b/components/dom_distiller/webui/dom_distiller_handler.cc
@@ -102,8 +102,7 @@ void DomDistillerHandler::HandleRequestEntries(const base::ListValue* args) { base::ListValue entries; const std::vector<ArticleEntry>& entries_specifics = service_->GetEntries(); - for (std::vector<ArticleEntry>::const_iterator it = entries_specifics.begin(); - it != entries_specifics.end(); + for (auto it = entries_specifics.begin(); it != entries_specifics.end(); ++it) { const ArticleEntry& article = *it; DCHECK(IsEntryValid(article));
diff --git a/components/domain_reliability/context_manager.cc b/components/domain_reliability/context_manager.cc index e0f6a8e..2290eb4 100644 --- a/components/domain_reliability/context_manager.cc +++ b/components/domain_reliability/context_manager.cc
@@ -100,7 +100,7 @@ void DomainReliabilityContextManager::RemoveContexts( const base::Callback<bool(const GURL&)>& origin_filter) { - for (ContextMap::iterator it = contexts_.begin(); it != contexts_.end(); ) { + for (auto it = contexts_.begin(); it != contexts_.end();) { if (!origin_filter.is_null() && !origin_filter.Run(it->second->config().origin)) { ++it;
diff --git a/components/download/content/public/all_download_item_notifier.cc b/components/download/content/public/all_download_item_notifier.cc index f5f1c58b..38145a8 100644 --- a/components/download/content/public/all_download_item_notifier.cc +++ b/components/download/content/public/all_download_item_notifier.cc
@@ -30,8 +30,7 @@ AllDownloadItemNotifier::~AllDownloadItemNotifier() { if (manager_) manager_->RemoveObserver(this); - for (std::set<DownloadItem*>::const_iterator it = observing_.begin(); - it != observing_.end(); ++it) { + for (auto it = observing_.begin(); it != observing_.end(); ++it) { (*it)->RemoveObserver(this); } observing_.clear();
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc index 978fcf9c..db1d6a89 100644 --- a/components/download/internal/common/download_item_impl.cc +++ b/components/download/internal/common/download_item_impl.cc
@@ -1020,8 +1020,8 @@ // Construct a string of the URL chain. std::string url_list("<none>"); if (!request_info_.url_chain.empty()) { - std::vector<GURL>::const_iterator iter = request_info_.url_chain.begin(); - std::vector<GURL>::const_iterator last = request_info_.url_chain.end(); + auto iter = request_info_.url_chain.begin(); + auto last = request_info_.url_chain.end(); url_list = (*iter).is_valid() ? (*iter).spec() : "<invalid>"; ++iter; for (; verbose && (iter != last); ++iter) { @@ -1185,8 +1185,7 @@ // will be used with the last server that sent them to us. // - The redirect chain contains all the servers that were involved in this // download since the initial request, in order. - std::vector<GURL>::const_iterator chain_iter = - new_create_info.url_chain.begin(); + auto chain_iter = new_create_info.url_chain.begin(); if (*chain_iter == request_info_.url_chain.back()) ++chain_iter;
diff --git a/components/download/internal/common/parallel_download_utils.cc b/components/download/internal/common/parallel_download_utils.cc index 88148139..bc7266f 100644 --- a/components/download/internal/common/parallel_download_utils.cc +++ b/components/download/internal/common/parallel_download_utils.cc
@@ -43,16 +43,14 @@ return result; } - std::vector<DownloadItem::ReceivedSlice>::const_iterator iter = - received_slices.begin(); + auto iter = received_slices.begin(); DCHECK_GE(iter->offset, 0); if (iter->offset != 0) result.emplace_back(0, iter->offset); while (true) { int64_t offset = iter->offset + iter->received_bytes; - std::vector<DownloadItem::ReceivedSlice>::const_iterator next = - std::next(iter); + auto next = std::next(iter); if (next == received_slices.end()) { result.emplace_back(offset, DownloadSaveInfo::kLengthFullContent); break; @@ -69,11 +67,10 @@ size_t AddOrMergeReceivedSliceIntoSortedArray( const DownloadItem::ReceivedSlice& new_slice, std::vector<DownloadItem::ReceivedSlice>& received_slices) { - std::vector<DownloadItem::ReceivedSlice>::iterator it = - std::upper_bound(received_slices.begin(), received_slices.end(), - new_slice, compareReceivedSlices); + auto it = std::upper_bound(received_slices.begin(), received_slices.end(), + new_slice, compareReceivedSlices); if (it != received_slices.begin()) { - std::vector<DownloadItem::ReceivedSlice>::iterator prev = std::prev(it); + auto prev = std::prev(it); if (prev->offset + prev->received_bytes == new_slice.offset) { prev->received_bytes += new_slice.received_bytes; return static_cast<size_t>(std::distance(received_slices.begin(), prev)); @@ -197,8 +194,7 @@ int64_t GetMaxContiguousDataBlockSizeFromBeginning( const DownloadItem::ReceivedSlices& slices) { - std::vector<DownloadItem::ReceivedSlice>::const_iterator iter = - slices.begin(); + auto iter = slices.begin(); int64_t size = 0; while (iter != slices.end() && iter->offset == size) {
diff --git a/components/drive/file_change.cc b/components/drive/file_change.cc index f21dea2a..456b864 100644 --- a/components/drive/file_change.cc +++ b/components/drive/file_change.cc
@@ -137,16 +137,15 @@ } void FileChange::Apply(const FileChange& new_changed_files) { - for (Map::const_iterator it = new_changed_files.map().begin(); - it != new_changed_files.map().end(); - it++) { + for (auto it = new_changed_files.map().begin(); + it != new_changed_files.map().end(); it++) { Update(it->first, it->second); } } size_t FileChange::CountDirectory(const base::FilePath& directory_path) const { size_t count = 0; - for (Map::const_iterator it = map_.begin(); it != map_.end(); it++) { + for (auto it = map_.begin(); it != map_.end(); it++) { if (it->first.DirName() == directory_path) count++; } @@ -156,8 +155,7 @@ std::string FileChange::DebugString() const { std::ostringstream ss; ss << "{ "; - for (FileChange::Map::const_iterator it = map_.begin(); it != map_.end(); - it++) { + for (auto it = map_.begin(); it != map_.end(); it++) { ss << it->first.value() << ": " << it->second.DebugString() << ", "; } ss << "}";
diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc index 52a8c144..700ba4d 100644 --- a/components/favicon/core/favicon_handler.cc +++ b/components/favicon/core/favicon_handler.cc
@@ -52,7 +52,7 @@ return false; // Check if at least one of the bitmaps is expired. - std::vector<favicon_base::FaviconRawBitmapResult>::const_iterator it = + auto it = std::find_if(bitmap_results.begin(), bitmap_results.end(), IsExpired); if (it != bitmap_results.end()) return true;
diff --git a/components/favicon_base/favicon_util.cc b/components/favicon_base/favicon_util.cc index c6d6c22..55582f6 100644 --- a/components/favicon_base/favicon_util.cc +++ b/components/favicon_base/favicon_util.cc
@@ -75,8 +75,7 @@ if (pixel_size.width() != pixel_size.height()) continue; - std::map<int, float>::iterator it = - desired_pixel_sizes.find(pixel_size.width()); + auto it = desired_pixel_sizes.find(pixel_size.width()); if (it == desired_pixel_sizes.end()) continue; @@ -194,10 +193,8 @@ std::vector<float> favicon_scales_to_generate = favicon_scales; for (size_t i = 0; i < png_reps.size(); ++i) { - std::vector<float>::iterator iter = std::find( - favicon_scales_to_generate.begin(), - favicon_scales_to_generate.end(), - png_reps[i].scale); + auto iter = std::find(favicon_scales_to_generate.begin(), + favicon_scales_to_generate.end(), png_reps[i].scale); if (iter != favicon_scales_to_generate.end()) favicon_scales_to_generate.erase(iter); }
diff --git a/components/favicon_base/select_favicon_frames.cc b/components/favicon_base/select_favicon_frames.cc index 7317ab0..040ae5a 100644 --- a/components/favicon_base/select_favicon_frames.cc +++ b/components/favicon_base/select_favicon_frames.cc
@@ -123,8 +123,7 @@ return; } - std::vector<int>::const_iterator zero_size_it = - std::find(desired_sizes.begin(), desired_sizes.end(), 0); + auto zero_size_it = std::find(desired_sizes.begin(), desired_sizes.end(), 0); if (zero_size_it != desired_sizes.end()) { // Just return the biggest image available. SelectionResult result; @@ -225,8 +224,8 @@ if (desired_size_in_dip == 0) { desired_sizes.push_back(0); } else { - for (std::vector<float>::const_iterator iter = favicon_scales.begin(); - iter != favicon_scales.end(); ++iter) { + for (auto iter = favicon_scales.begin(); iter != favicon_scales.end(); + ++iter) { desired_sizes.push_back( static_cast<int>(ceil(desired_size_in_dip * (*iter)))); }
diff --git a/components/feed/core/feed_journal_database.cc b/components/feed/core/feed_journal_database.cc index 3e04d28..e9eaadbd 100644 --- a/components/feed/core/feed_journal_database.cc +++ b/components/feed/core/feed_journal_database.cc
@@ -187,8 +187,7 @@ journals_to_save->emplace_back(journal_name, std::move(*journal)); } - for (JournalMap::iterator it = copy_to_journal.begin(); - it != copy_to_journal.end(); ++it) { + for (auto it = copy_to_journal.begin(); it != copy_to_journal.end(); ++it) { journals_to_save->emplace_back(it->first, std::move(it->second)); }
diff --git a/components/feedback/tracing_manager.cc b/components/feedback/tracing_manager.cc index d5c3fc70..01049247 100644 --- a/components/feedback/tracing_manager.cc +++ b/components/feedback/tracing_manager.cc
@@ -62,8 +62,7 @@ return false; } } else { - std::map<int, scoped_refptr<base::RefCountedString> >::iterator data = - trace_data_.find(id); + auto data = trace_data_.find(id); if (data == trace_data_.end()) return false;
diff --git a/components/flags_ui/pref_service_flags_storage.cc b/components/flags_ui/pref_service_flags_storage.cc index a8b1d8c..fdcc64c 100644 --- a/components/flags_ui/pref_service_flags_storage.cc +++ b/components/flags_ui/pref_service_flags_storage.cc
@@ -23,8 +23,8 @@ const base::ListValue* enabled_experiments = prefs_->GetList(prefs::kEnabledLabsExperiments); std::set<std::string> flags; - for (base::ListValue::const_iterator it = enabled_experiments->begin(); - it != enabled_experiments->end(); ++it) { + for (auto it = enabled_experiments->begin(); it != enabled_experiments->end(); + ++it) { std::string experiment_name; if (!it->GetAsString(&experiment_name)) { LOG(WARNING) << "Invalid entry in " << prefs::kEnabledLabsExperiments; @@ -40,8 +40,7 @@ base::ListValue* experiments_list = update.Get(); experiments_list->Clear(); - for (std::set<std::string>::const_iterator it = flags.begin(); - it != flags.end(); ++it) { + for (auto it = flags.begin(); it != flags.end(); ++it) { experiments_list->AppendString(*it); }
diff --git a/components/gcm_driver/account_tracker.cc b/components/gcm_driver/account_tracker.cc index 7e7841b8..3e210e0 100644 --- a/components/gcm_driver/account_tracker.cc +++ b/components/gcm_driver/account_tracker.cc
@@ -48,9 +48,7 @@ identity_manager_->GetPrimaryAccountInfo().account_id; std::vector<AccountIds> accounts; - for (std::map<std::string, AccountState>::const_iterator it = - accounts_.begin(); - it != accounts_.end(); ++it) { + for (auto it = accounts_.begin(); it != accounts_.end(); ++it) { const AccountState& state = it->second; bool is_visible = state.is_signed_in && !state.ids.gaia.empty();
diff --git a/components/gcm_driver/account_tracker_unittest.cc b/components/gcm_driver/account_tracker_unittest.cc index 9e8bd38..7649ed4 100644 --- a/components/gcm_driver/account_tracker_unittest.cc +++ b/components/gcm_driver/account_tracker_unittest.cc
@@ -75,8 +75,7 @@ std::string Str(const std::vector<TrackingEvent>& events) { std::string str = "["; bool needs_comma = false; - for (std::vector<TrackingEvent>::const_iterator it = events.begin(); - it != events.end(); ++it) { + for (auto it = events.begin(); it != events.end(); ++it) { if (needs_comma) str += ",\n "; needs_comma = true;
diff --git a/components/gcm_driver/gcm_account_mapper.cc b/components/gcm_driver/gcm_account_mapper.cc index ef988ec..aaff875 100644 --- a/components/gcm_driver/gcm_account_mapper.cc +++ b/components/gcm_driver/gcm_account_mapper.cc
@@ -78,17 +78,13 @@ } // Start from removing the old tokens, from all of the known accounts. - for (AccountMappings::iterator iter = accounts_.begin(); - iter != accounts_.end(); - ++iter) { + for (auto iter = accounts_.begin(); iter != accounts_.end(); ++iter) { iter->access_token.clear(); } // Update the internal collection of mappings with the new tokens. - for (std::vector<GCMClient::AccountTokenInfo>::const_iterator token_iter = - account_tokens.begin(); - token_iter != account_tokens.end(); - ++token_iter) { + for (auto token_iter = account_tokens.begin(); + token_iter != account_tokens.end(); ++token_iter) { AccountMapping* account_mapping = FindMappingByAccountId(token_iter->account_id); if (!account_mapping) { @@ -114,8 +110,7 @@ // Decide what to do with each account (either start mapping, or start // removing). - for (AccountMappings::iterator mappings_iter = accounts_.begin(); - mappings_iter != accounts_.end(); + for (auto mappings_iter = accounts_.begin(); mappings_iter != accounts_.end(); ++mappings_iter) { if (mappings_iter->access_token.empty()) { // Send a remove message if the account was not previously being removed, @@ -165,7 +160,7 @@ return; } - MessageData::const_iterator it = message.data.find(kGCMSendToGaiaIdAppIdKey); + auto it = message.data.find(kGCMSendToGaiaIdAppIdKey); if (it == message.data.end()) { DVLOG(1) << "Send to Gaia ID failure: Embedded app ID missing."; return; @@ -192,7 +187,7 @@ const GCMClient::SendErrorDetails& send_error_details) { DCHECK_EQ(app_id, kGCMAccountMapperAppId); - AccountMappings::iterator account_mapping_it = + auto account_mapping_it = FindMappingByMessageId(send_error_details.message_id); if (account_mapping_it == accounts_.end()) @@ -226,8 +221,7 @@ void GCMAccountMapper::OnSendAcknowledged(const std::string& app_id, const std::string& message_id) { DCHECK_EQ(app_id, kGCMAccountMapperAppId); - AccountMappings::iterator account_mapping_it = - FindMappingByMessageId(message_id); + auto account_mapping_it = FindMappingByMessageId(message_id); DVLOG(1) << "OnSendAcknowledged with message ID: " << message_id; @@ -369,9 +363,7 @@ AccountMapping* GCMAccountMapper::FindMappingByAccountId( const std::string& account_id) { - for (AccountMappings::iterator iter = accounts_.begin(); - iter != accounts_.end(); - ++iter) { + for (auto iter = accounts_.begin(); iter != accounts_.end(); ++iter) { if (iter->account_id == account_id) return &*iter; } @@ -381,9 +373,7 @@ GCMAccountMapper::AccountMappings::iterator GCMAccountMapper::FindMappingByMessageId(const std::string& message_id) { - for (std::vector<AccountMapping>::iterator iter = accounts_.begin(); - iter != accounts_.end(); - ++iter) { + for (auto iter = accounts_.begin(); iter != accounts_.end(); ++iter) { if (iter->last_message_id == message_id) return iter; }
diff --git a/components/gcm_driver/gcm_account_mapper_unittest.cc b/components/gcm_driver/gcm_account_mapper_unittest.cc index 279ac337..5907cbf 100644 --- a/components/gcm_driver/gcm_account_mapper_unittest.cc +++ b/components/gcm_driver/gcm_account_mapper_unittest.cc
@@ -57,10 +57,8 @@ const std::string& verification_info) { EXPECT_EQ(expected_mappings.size(), actual_mappings.size()) << "Verification Info: " << verification_info; - GCMAccountMapper::AccountMappings::const_iterator expected_iter = - expected_mappings.begin(); - GCMAccountMapper::AccountMappings::const_iterator actual_iter = - actual_mappings.begin(); + auto expected_iter = expected_mappings.begin(); + auto actual_iter = actual_mappings.begin(); for (; expected_iter != expected_mappings.end() && actual_iter != actual_mappings.end(); ++expected_iter, ++actual_iter) { @@ -948,8 +946,7 @@ EXPECT_EQ(kTestAppId, last_received_app_id()); EXPECT_EQ(1UL, last_received_message().data.size()); - MessageData::const_iterator it = - last_received_message().data.find(kTestDataKey); + auto it = last_received_message().data.find(kTestDataKey); EXPECT_TRUE(it != last_received_message().data.end()); EXPECT_EQ(kTestDataValue, it->second); EXPECT_EQ(kTestCollapseKey, last_received_message().collapse_key);
diff --git a/components/gcm_driver/gcm_account_tracker.cc b/components/gcm_driver/gcm_account_tracker.cc index fc182cb..b85bfc6 100644 --- a/components/gcm_driver/gcm_account_tracker.cc +++ b/components/gcm_driver/gcm_account_tracker.cc
@@ -116,7 +116,7 @@ std::string account_id, GoogleServiceAuthError error, identity::AccessTokenInfo access_token_info) { - AccountInfos::iterator iter = account_infos_.find(account_id); + auto iter = account_infos_.find(account_id); DCHECK(iter != account_infos_.end()); if (iter != account_infos_.end()) { DCHECK_EQ(GETTING_TOKEN, iter->second.state); @@ -174,8 +174,7 @@ bool account_removed = false; // Stop tracking the accounts, that were removed, as it will be reported to // the driver. - for (AccountInfos::iterator iter = account_infos_.begin(); - iter != account_infos_.end();) { + for (auto iter = account_infos_.begin(); iter != account_infos_.end();) { if (iter->second.state == ACCOUNT_REMOVED) { account_removed = true; account_infos_.erase(iter++); @@ -185,8 +184,8 @@ } std::vector<GCMClient::AccountTokenInfo> account_tokens; - for (AccountInfos::iterator iter = account_infos_.begin(); - iter != account_infos_.end(); ++iter) { + for (auto iter = account_infos_.begin(); iter != account_infos_.end(); + ++iter) { if (iter->second.state == TOKEN_PRESENT) { GCMClient::AccountTokenInfo token_info; token_info.account_id = iter->first; @@ -213,8 +212,7 @@ } void GCMAccountTracker::SanitizeTokens() { - for (AccountInfos::iterator iter = account_infos_.begin(); - iter != account_infos_.end(); + for (auto iter = account_infos_.begin(); iter != account_infos_.end(); ++iter) { if (iter->second.state == TOKEN_PRESENT && iter->second.expiration_time < @@ -232,8 +230,7 @@ return true; bool reporting_required = false; - for (AccountInfos::const_iterator iter = account_infos_.begin(); - iter != account_infos_.end(); + for (auto iter = account_infos_.begin(); iter != account_infos_.end(); ++iter) { if (iter->second.state == ACCOUNT_REMOVED) reporting_required = true; @@ -244,8 +241,7 @@ bool GCMAccountTracker::IsTokenFetchingRequired() const { bool token_needed = false; - for (AccountInfos::const_iterator iter = account_infos_.begin(); - iter != account_infos_.end(); + for (auto iter = account_infos_.begin(); iter != account_infos_.end(); ++iter) { if (iter->second.state == TOKEN_NEEDED) token_needed = true; @@ -284,8 +280,7 @@ if (!driver_->IsConnected()) return; - for (AccountInfos::iterator iter = account_infos_.begin(); - iter != account_infos_.end(); + for (auto iter = account_infos_.begin(); iter != account_infos_.end(); ++iter) { if (iter->second.state == TOKEN_NEEDED) GetToken(iter); @@ -318,7 +313,7 @@ void GCMAccountTracker::OnAccountSignedIn(const AccountIds& ids) { DVLOG(1) << "Account signed in: " << ids.email; - AccountInfos::iterator iter = account_infos_.find(ids.account_key); + auto iter = account_infos_.find(ids.account_key); if (iter == account_infos_.end()) { DCHECK(!ids.email.empty()); account_infos_.insert( @@ -332,7 +327,7 @@ void GCMAccountTracker::OnAccountSignedOut(const AccountIds& ids) { DVLOG(1) << "Account signed out: " << ids.email; - AccountInfos::iterator iter = account_infos_.find(ids.account_key); + auto iter = account_infos_.find(ids.account_key); if (iter == account_infos_.end()) return;
diff --git a/components/gcm_driver/gcm_account_tracker_unittest.cc b/components/gcm_driver/gcm_account_tracker_unittest.cc index 8fbfd44..10b8a4e 100644 --- a/components/gcm_driver/gcm_account_tracker_unittest.cc +++ b/components/gcm_driver/gcm_account_tracker_unittest.cc
@@ -63,11 +63,10 @@ const std::vector<GCMClient::AccountTokenInfo>& expected_tokens, const std::vector<GCMClient::AccountTokenInfo>& actual_tokens) { EXPECT_EQ(expected_tokens.size(), actual_tokens.size()); - for (std::vector<GCMClient::AccountTokenInfo>::const_iterator - expected_iter = expected_tokens.begin(), - actual_iter = actual_tokens.begin(); + for (auto expected_iter = expected_tokens.begin(), + actual_iter = actual_tokens.begin(); expected_iter != expected_tokens.end() && - actual_iter != actual_tokens.end(); + actual_iter != actual_tokens.end(); ++expected_iter, ++actual_iter) { EXPECT_EQ(expected_iter->account_id, actual_iter->account_id); EXPECT_EQ(expected_iter->email, actual_iter->email);
diff --git a/components/gcm_driver/gcm_client_impl.cc b/components/gcm_driver/gcm_client_impl.cc index 35c31f6..7e12cd5 100644 --- a/components/gcm_driver/gcm_client_impl.cc +++ b/components/gcm_driver/gcm_client_impl.cc
@@ -297,9 +297,7 @@ void GCMClientImpl::CheckinInfo::SnapshotCheckinAccounts() { last_checkin_accounts.clear(); - for (std::map<std::string, std::string>::iterator iter = - account_tokens.begin(); - iter != account_tokens.end(); + for (auto iter = account_tokens.begin(); iter != account_tokens.end(); ++iter) { last_checkin_accounts.insert(iter->first); } @@ -578,9 +576,7 @@ void GCMClientImpl::SetAccountTokens( const std::vector<AccountTokenInfo>& account_tokens) { device_checkin_info_.account_tokens.clear(); - for (std::vector<AccountTokenInfo>::const_iterator iter = - account_tokens.begin(); - iter != account_tokens.end(); + for (auto iter = account_tokens.begin(); iter != account_tokens.end(); ++iter) { device_checkin_info_.account_tokens[iter->email] = iter->access_token; } @@ -595,10 +591,8 @@ return; bool account_removed = false; - for (std::set<std::string>::iterator iter = - device_checkin_info_.last_checkin_accounts.begin(); - iter != device_checkin_info_.last_checkin_accounts.end(); - ++iter) { + for (auto iter = device_checkin_info_.last_checkin_accounts.begin(); + iter != device_checkin_info_.last_checkin_accounts.end(); ++iter) { if (device_checkin_info_.account_tokens.find(*iter) == device_checkin_info_.account_tokens.end()) { account_removed = true; @@ -1220,9 +1214,7 @@ stanza.set_to(receiver_id); stanza.set_category(app_id); - for (MessageData::const_iterator iter = message.data.begin(); - iter != message.data.end(); - ++iter) { + for (auto iter = message.data.begin(); iter != message.data.end(); ++iter) { mcs_proto::AppData* app_data = stanza.add_app_data(); app_data->set_key(iter->first); app_data->set_value(iter->second); @@ -1287,8 +1279,7 @@ recorder_.CollectActivities(&stats.recorded_activities); - for (RegistrationInfoMap::const_iterator it = registrations_.begin(); - it != registrations_.end(); ++it) { + for (auto it = registrations_.begin(); it != registrations_.end(); ++it) { stats.registered_app_ids.push_back(it->first->app_id); } return stats; @@ -1402,7 +1393,7 @@ std::string app_id = use_subtype ? subtype : data_message_stanza.category(); MessageType message_type = DATA_MESSAGE; - MessageData::iterator type_iter = message_data.find(kMessageTypeKey); + auto type_iter = message_data.find(kMessageTypeKey); if (type_iter != message_data.end()) { message_type = DecodeMessageType(type_iter->second); message_data.erase(type_iter); @@ -1457,7 +1448,7 @@ const mcs_proto::DataMessageStanza& data_message_stanza, MessageData& message_data) { int deleted_count = 0; - MessageData::iterator count_iter = message_data.find(kDeletedCountKey); + auto count_iter = message_data.find(kDeletedCountKey); if (count_iter != message_data.end()) { if (!base::StringToInt(count_iter->second, &deleted_count)) deleted_count = 0; @@ -1478,8 +1469,7 @@ send_error_details.additional_data = message_data; send_error_details.result = SERVER_ERROR; - MessageData::iterator iter = - send_error_details.additional_data.find(kSendErrorMessageIdKey); + auto iter = send_error_details.additional_data.find(kSendErrorMessageIdKey); if (iter != send_error_details.additional_data.end()) { send_error_details.message_id = iter->second; send_error_details.additional_data.erase(iter);
diff --git a/components/gcm_driver/gcm_client_impl_unittest.cc b/components/gcm_driver/gcm_client_impl_unittest.cc index 09306d1..a4bb30b 100644 --- a/components/gcm_driver/gcm_client_impl_unittest.cc +++ b/components/gcm_driver/gcm_client_impl_unittest.cc
@@ -97,9 +97,7 @@ mcs_proto::DataMessageStanza data_message; data_message.set_from(project_id); data_message.set_category(category); - for (std::map<std::string, std::string>::const_iterator iter = data.begin(); - iter != data.end(); - ++iter) { + for (auto iter = data.begin(); iter != data.end(); ++iter) { mcs_proto::AppData* app_data = data_message.add_app_data(); app_data->set_key(iter->first); app_data->set_value(iter->second); @@ -124,8 +122,8 @@ std::map<std::string, std::string> MakeEmailToTokenMap( const std::vector<GCMClient::AccountTokenInfo>& account_tokens) { std::map<std::string, std::string> email_token_map; - for (std::vector<GCMClient::AccountTokenInfo>::const_iterator iter = - account_tokens.begin(); iter != account_tokens.end(); ++iter) { + for (auto iter = account_tokens.begin(); iter != account_tokens.end(); + ++iter) { email_token_map[iter->email] = iter->access_token; } return email_token_map; @@ -560,10 +558,7 @@ // For testing G-services settings. if (!digest.empty()) { response.set_digest(digest); - for (std::map<std::string, std::string>::const_iterator it = - settings.begin(); - it != settings.end(); - ++it) { + for (auto it = settings.begin(); it != settings.end(); ++it) { checkin_proto::GservicesSetting* setting = response.add_setting(); setting->set_name(it->first); setting->set_value(it->second); @@ -1134,8 +1129,7 @@ EXPECT_EQ(kExtensionAppId, last_app_id()); EXPECT_EQ("007", last_error_details().message_id); EXPECT_EQ(1UL, last_error_details().additional_data.size()); - MessageData::const_iterator iter = - last_error_details().additional_data.find("error_details"); + auto iter = last_error_details().additional_data.find("error_details"); EXPECT_TRUE(iter != last_error_details().additional_data.end()); EXPECT_EQ("some details", iter->second); }
diff --git a/components/gcm_driver/gcm_driver.cc b/components/gcm_driver/gcm_driver.cc index d026b733..8345ce3d 100644 --- a/components/gcm_driver/gcm_driver.cc +++ b/components/gcm_driver/gcm_driver.cc
@@ -70,8 +70,7 @@ // finishes. We don't want to throw ASYNC_OPERATION_PENDING when the user // uninstalls an app (ungistering) and then reinstalls the app again // (registering). - std::map<std::string, UnregisterCallback>::iterator unregister_iter = - unregister_callbacks_.find(app_id); + auto unregister_iter = unregister_callbacks_.find(app_id); if (unregister_iter != unregister_callbacks_.end()) { // Replace the original unregister callback with an intermediate callback // that will invoke the original unregister callback and trigger the pending @@ -172,8 +171,7 @@ void GCMDriver::RegisterFinished(const std::string& app_id, const std::string& registration_id, GCMClient::Result result) { - std::map<std::string, RegisterCallback>::iterator callback_iter = - register_callbacks_.find(app_id); + auto callback_iter = register_callbacks_.find(app_id); if (callback_iter == register_callbacks_.end()) { // The callback could have been removed when the app is uninstalled. return; @@ -194,8 +192,7 @@ void GCMDriver::UnregisterFinished(const std::string& app_id, GCMClient::Result result) { - std::map<std::string, UnregisterCallback>::iterator callback_iter = - unregister_callbacks_.find(app_id); + auto callback_iter = unregister_callbacks_.find(app_id); if (callback_iter == unregister_callbacks_.end()) return; @@ -207,9 +204,8 @@ void GCMDriver::SendFinished(const std::string& app_id, const std::string& message_id, GCMClient::Result result) { - std::map<std::pair<std::string, std::string>, SendCallback>::iterator - callback_iter = send_callbacks_.find( - std::pair<std::string, std::string>(app_id, message_id)); + auto callback_iter = send_callbacks_.find( + std::pair<std::string, std::string>(app_id, message_id)); if (callback_iter == send_callbacks_.end()) { // The callback could have been removed when the app is uninstalled. return;
diff --git a/components/gcm_driver/registration_info.cc b/components/gcm_driver/registration_info.cc index 5eddf8c..f08388f 100644 --- a/components/gcm_driver/registration_info.cc +++ b/components/gcm_driver/registration_info.cc
@@ -88,8 +88,7 @@ // Serialize as: // sender1,sender2,...=reg_id#time_of_last_validation std::string value; - for (std::vector<std::string>::const_iterator iter = sender_ids.begin(); - iter != sender_ids.end(); ++iter) { + for (auto iter = sender_ids.begin(); iter != sender_ids.end(); ++iter) { DCHECK(!iter->empty() && iter->find(',') == std::string::npos && iter->find('=') == std::string::npos);
diff --git a/components/history/core/browser/download_database.cc b/components/history/core/browser/download_database.cc index 938b437..df40855 100644 --- a/components/history/core/browser/download_database.cc +++ b/components/history/core/browser/download_database.cc
@@ -536,8 +536,7 @@ QueryDownloadSlices(&info_map); - for (DownloadRowMap::iterator it = info_map.begin(); it != info_map.end(); - ++it) { + for (auto it = info_map.begin(); it != info_map.end(); ++it) { DownloadRow* row = it->second; bool empty_url_chain = row->url_chain.empty(); UMA_HISTOGRAM_BOOLEAN("Download.DatabaseEmptyUrlChain", empty_url_chain); @@ -844,7 +843,7 @@ // Confirm the download_id has already been seen--if it hasn't, discard the // record. - DownloadRowMap::iterator it = download_row_map->find(info.download_id); + auto it = download_row_map->find(info.download_id); bool found = (it != download_row_map->end()); UMA_HISTOGRAM_BOOLEAN( "Download.DatabaseDownloadExistsForDownloadSlice", found);
diff --git a/components/history/core/browser/expire_history_backend.cc b/components/history/core/browser/expire_history_backend.cc index eb264c4..be43789 100644 --- a/components/history/core/browser/expire_history_backend.cc +++ b/components/history/core/browser/expire_history_backend.cc
@@ -191,8 +191,7 @@ return; DeleteEffects effects; - for (std::vector<GURL>::const_iterator url = urls.begin(); url != urls.end(); - ++url) { + for (auto url = urls.begin(); url != urls.end(); ++url) { const bool is_bookmarked = backend_client_ && backend_client_->IsBookmarked(*url); URLRow url_row; @@ -236,13 +235,11 @@ main_db_->GetAllVisitsInRange(begin_time, end_time, 0, &visits); if (!restrict_urls.empty()) { std::set<URLID> url_ids; - for (std::set<GURL>::const_iterator url = restrict_urls.begin(); - url != restrict_urls.end(); ++url) + for (auto url = restrict_urls.begin(); url != restrict_urls.end(); ++url) url_ids.insert(main_db_->GetRowForURL(*url, nullptr)); VisitVector all_visits; all_visits.swap(visits); - for (VisitVector::iterator visit = all_visits.begin(); - visit != all_visits.end(); ++visit) { + for (auto visit = all_visits.begin(); visit != all_visits.end(); ++visit) { if (url_ids.find(visit->url_id) != url_ids.end()) visits.push_back(*visit); } @@ -362,8 +359,7 @@ if (!thumb_db_) return; - for (std::set<favicon_base::FaviconID>::const_iterator i = - effects->affected_favicons.begin(); + for (auto i = effects->affected_favicons.begin(); i != effects->affected_favicons.end(); ++i) { if (!thumb_db_->HasMappingFor(*i)) { GURL icon_url; @@ -444,8 +440,7 @@ // Collect shared information. std::vector<IconMapping> icon_mappings; if (thumb_db_ && thumb_db_->GetIconMappingsForPageURL(gurl, &icon_mappings)) { - for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); - m != icon_mappings.end(); ++m) { + for (auto m = icon_mappings.begin(); m != icon_mappings.end(); ++m) { effects->affected_favicons.insert(m->icon_id); } // Delete the mapping entries for the url.
diff --git a/components/history/core/browser/expire_history_backend_unittest.cc b/components/history/core/browser/expire_history_backend_unittest.cc index a0215c0..c0422c5 100644 --- a/components/history/core/browser/expire_history_backend_unittest.cc +++ b/components/history/core/browser/expire_history_backend_unittest.cc
@@ -375,8 +375,8 @@ for (const auto& info : urls_deleted_notifications_) { EXPECT_EQ(expired, info.is_from_expiration()); const history::URLRows& rows(info.deleted_rows()); - history::URLRows::const_iterator it_row = std::find_if( - rows.begin(), rows.end(), history::URLRow::URLRowHasURL(row.url())); + auto it_row = std::find_if(rows.begin(), rows.end(), + history::URLRow::URLRowHasURL(row.url())); if (it_row != rows.end()) { // Further verify that the ID is set to what had been in effect in the // main database before the deletion. The InMemoryHistoryBackend relies
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc index dd3e5d00..3de7cad 100644 --- a/components/history/core/browser/history_backend.cc +++ b/components/history/core/browser/history_backend.cc
@@ -899,7 +899,7 @@ return; URLRows changed_urls; - for (URLRows::const_iterator i = urls.begin(); i != urls.end(); ++i) { + for (auto i = urls.begin(); i != urls.end(); ++i) { DCHECK(!i->last_visit().is_null()); // As of M37, we no longer maintain an archived database, ignore old visits. @@ -962,7 +962,7 @@ // the processing below can be the same. RedirectList dummy_list; RedirectList* redirects; - RedirectCache::iterator iter = recent_redirects_.Get(url); + auto iter = recent_redirects_.Get(url); if (iter != recent_redirects_.end()) { redirects = &iter->second; @@ -1056,7 +1056,7 @@ return 0; URLRows changed_urls; - for (URLRows::const_iterator it = urls.begin(); it != urls.end(); ++it) { + for (auto it = urls.begin(); it != urls.end(); ++it) { DCHECK(it->id()); if (db_->UpdateURLRow(it->id(), *it)) changed_urls.push_back(*it); @@ -1076,8 +1076,7 @@ const std::vector<VisitInfo>& visits, VisitSource visit_source) { if (db_) { - for (std::vector<VisitInfo>::const_iterator visit = visits.begin(); - visit != visits.end(); ++visit) { + for (auto visit = visits.begin(); visit != visits.end(); ++visit) { if (!AddPageVisit(url, visit->first, 0, visit->second, !ui::PageTransitionIsMainFrame(visit->second), visit_source, IsTypedIncrement(visit->second)) @@ -1205,8 +1204,7 @@ if (db_->GetKeywordSearchTermRows(term, &rows)) { std::vector<GURL> items_to_delete; URLRow row; - for (std::vector<KeywordSearchTermRow>::iterator it = rows.begin(); - it != rows.end(); ++it) { + for (auto it = rows.begin(); it != rows.end(); ++it) { if ((it->keyword_id == keyword_id) && db_->GetURLRow(it->url_id, &row)) items_to_delete.push_back(row.url()); } @@ -1271,8 +1269,7 @@ size_t downloads_count_before = db_->CountDownloads(); // HistoryBackend uses a long-running Transaction that is committed // periodically, so this loop doesn't actually hit the disk too hard. - for (std::set<uint32_t>::const_iterator it = ids.begin(); it != ids.end(); - ++it) { + for (auto it = ids.begin(); it != ids.end(); ++it) { db_->RemoveDownload(*it); } ScheduleCommit(); @@ -1797,9 +1794,8 @@ // a favicon bitmap mapped to |icon_url|. The one there is more correct // and having multiple equally sized favicon bitmaps for |page_url| is // ambiguous in terms of GetFaviconsForURL(). - std::vector<gfx::Size>::iterator it = - std::find(favicon_sizes.begin(), favicon_sizes.end(), - bitmaps_to_copy[j].pixel_size); + auto it = std::find(favicon_sizes.begin(), favicon_sizes.end(), + bitmaps_to_copy[j].pixel_size); if (it != favicon_sizes.end()) continue; @@ -1928,8 +1924,7 @@ !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) return; - for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); - m != icon_mappings.end(); ++m) { + for (auto m = icon_mappings.begin(); m != icon_mappings.end(); ++m) { thumbnail_db_->SetFaviconOutOfDate(m->icon_id); } ScheduleCommit(); @@ -1967,7 +1962,7 @@ } // Save the mapping from all the URLs to the favicon. - for (std::set<GURL>::const_iterator url = favicon_usage[i].urls.begin(); + for (auto url = favicon_usage[i].urls.begin(); url != favicon_usage[i].urls.end(); ++url) { URLRow url_row; if (!db_->GetRowForURL(*url, &url_row)) { @@ -2100,9 +2095,8 @@ bool favicon_bitmaps_changed = false; for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { const gfx::Size& pixel_size = bitmap_id_sizes[i].pixel_size; - std::vector<PNGEncodedBitmap>::iterator match_it = to_add.end(); - for (std::vector<PNGEncodedBitmap>::iterator it = to_add.begin(); - it != to_add.end(); ++it) { + auto match_it = to_add.end(); + for (auto it = to_add.begin(); it != to_add.end(); ++it) { if (it->second == pixel_size) { match_it = it; break; @@ -2316,8 +2310,7 @@ std::vector<IconMapping> icon_mappings; thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings); - for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); - m != icon_mappings.end(); ++m) { + for (auto m = icon_mappings.begin(); m != icon_mappings.end(); ++m) { if (unmapped_icon_id == m->icon_id) { unmapped_icon_id = 0; continue; @@ -2344,7 +2337,7 @@ } RedirectList HistoryBackend::GetCachedRecentRedirects(const GURL& page_url) { - RedirectCache::iterator iter = recent_redirects_.Get(page_url); + auto iter = recent_redirects_.Get(page_url); if (iter != recent_redirects_.end()) { // The redirect chain should have the destination URL as the last item. DCHECK(!iter->second.empty()); @@ -2554,9 +2547,7 @@ if (db_) { bool update_first_recorded_time = false; - for (std::vector<ExpireHistoryArgs>::const_iterator it = - expire_list.begin(); - it != expire_list.end(); ++it) { + for (auto it = expire_list.begin(); it != expire_list.end(); ++it) { expirer_.ExpireHistoryBetween(it->urls, it->begin_time, it->end_time); if (it->begin_time < first_recorded_time_) @@ -2581,7 +2572,7 @@ if (!db_) return; - for (std::set<GURL>::const_iterator i = urls.begin(); i != urls.end(); ++i) { + for (auto i = urls.begin(); i != urls.end(); ++i) { VisitVector visits; URLRow url_row; if (db_->GetRowForURL(*i, &url_row)) @@ -2809,8 +2800,7 @@ return false; // Insert the URLs into the temporary table. - for (URLRows::const_iterator i = kept_urls.begin(); i != kept_urls.end(); - ++i) { + for (auto i = kept_urls.begin(); i != kept_urls.end(); ++i) { db_->AddTemporaryURL(*i); }
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc index 0c0e730..f69ee1e 100644 --- a/components/history/core/browser/history_backend_unittest.cc +++ b/components/history/core/browser/history_backend_unittest.cc
@@ -1023,21 +1023,18 @@ const URLRows& changed_urls = urls_modified_notifications()[0]; EXPECT_EQ(3u, changed_urls.size()); - URLRows::const_iterator it_row1 = - std::find_if(changed_urls.begin(), changed_urls.end(), - history::URLRow::URLRowHasURL(row1.url())); + auto it_row1 = std::find_if(changed_urls.begin(), changed_urls.end(), + history::URLRow::URLRowHasURL(row1.url())); ASSERT_NE(changed_urls.end(), it_row1); EXPECT_EQ(stored_row1.id(), it_row1->id()); - URLRows::const_iterator it_row2 = - std::find_if(changed_urls.begin(), changed_urls.end(), - history::URLRow::URLRowHasURL(row2.url())); + auto it_row2 = std::find_if(changed_urls.begin(), changed_urls.end(), + history::URLRow::URLRowHasURL(row2.url())); ASSERT_NE(changed_urls.end(), it_row2); EXPECT_EQ(stored_row2.id(), it_row2->id()); - URLRows::const_iterator it_row3 = - std::find_if(changed_urls.begin(), changed_urls.end(), - history::URLRow::URLRowHasURL(row3.url())); + auto it_row3 = std::find_if(changed_urls.begin(), changed_urls.end(), + history::URLRow::URLRowHasURL(row3.url())); ASSERT_NE(changed_urls.end(), it_row3); EXPECT_EQ(stored_row3.id(), it_row3->id()); } @@ -1094,16 +1091,14 @@ const URLRows& changed_urls = urls_modified_notifications()[0]; EXPECT_EQ(2u, changed_urls.size()); - URLRows::const_iterator it_row1 = - std::find_if(changed_urls.begin(), changed_urls.end(), - history::URLRow::URLRowHasURL(row1.url())); + auto it_row1 = std::find_if(changed_urls.begin(), changed_urls.end(), + history::URLRow::URLRowHasURL(row1.url())); ASSERT_NE(changed_urls.end(), it_row1); EXPECT_EQ(altered_row1.id(), it_row1->id()); EXPECT_EQ(altered_row1.visit_count(), it_row1->visit_count()); - URLRows::const_iterator it_row3 = - std::find_if(changed_urls.begin(), changed_urls.end(), - history::URLRow::URLRowHasURL(row3.url())); + auto it_row3 = std::find_if(changed_urls.begin(), changed_urls.end(), + history::URLRow::URLRowHasURL(row3.url())); ASSERT_NE(changed_urls.end(), it_row3); EXPECT_EQ(altered_row3.id(), it_row3->id()); EXPECT_EQ(altered_row3.visit_count(), it_row3->visit_count());
diff --git a/components/history/core/browser/history_types.cc b/components/history/core/browser/history_types.cc index aae0d22..2ba16c6 100644 --- a/components/history/core/browser/history_types.cc +++ b/components/history/core/browser/history_types.cc
@@ -41,7 +41,7 @@ const size_t* QueryResults::MatchesForURL(const GURL& url, size_t* num_matches) const { - URLToResultIndices::const_iterator found = url_to_results_.find(url); + auto found = url_to_results_.find(url); if (found == url_to_results_.end()) { if (num_matches) *num_matches = 0; @@ -94,7 +94,7 @@ // Delete the indicies referencing the deleted entries. for (const auto& url : urls_modified) { - URLToResultIndices::iterator found = url_to_results_.find(url); + auto found = url_to_results_.find(url); if (found == url_to_results_.end()) { NOTREACHED(); continue; @@ -121,7 +121,7 @@ } void QueryResults::AddURLUsageAtIndex(const GURL& url, size_t index) { - URLToResultIndices::iterator found = url_to_results_.find(url); + auto found = url_to_results_.find(url); if (found != url_to_results_.end()) { // The URL is already in the list, so we can just append the new index. found->second->push_back(index); @@ -135,8 +135,7 @@ } void QueryResults::AdjustResultMap(size_t begin, size_t end, ptrdiff_t delta) { - for (URLToResultIndices::iterator i = url_to_results_.begin(); - i != url_to_results_.end(); ++i) { + for (auto i = url_to_results_.begin(); i != url_to_results_.end(); ++i) { for (size_t match = 0; match < i->second->size(); match++) { size_t match_index = i->second[match]; if (match_index >= begin && match_index <= end)
diff --git a/components/history/core/browser/sync/delete_directive_handler.cc b/components/history/core/browser/sync/delete_directive_handler.cc index 71fee776..f7fa12a 100644 --- a/components/history/core/browser/sync/delete_directive_handler.cc +++ b/components/history/core/browser/sync/delete_directive_handler.cc
@@ -340,8 +340,7 @@ time_range_directive->set_start_time_usec(begin_time_usecs); time_range_directive->set_end_time_usec(end_time_usecs); } else { - for (std::set<int64_t>::const_iterator it = global_ids.begin(); - it != global_ids.end(); ++it) { + for (auto it = global_ids.begin(); it != global_ids.end(); ++it) { sync_pb::GlobalIdDirective* global_id_directive = delete_directive.mutable_global_id_directive(); global_id_directive->add_global_id(*it); @@ -390,8 +389,7 @@ } syncer::SyncDataList delete_directives; - for (syncer::SyncChangeList::const_iterator it = change_list.begin(); - it != change_list.end(); ++it) { + for (auto it = change_list.begin(); it != change_list.end(); ++it) { switch (it->change_type()) { case syncer::SyncChange::ACTION_ADD: delete_directives.push_back(it->sync_data());
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge.cc b/components/history/core/browser/sync/typed_url_sync_bridge.cc index 371106c..261bece 100644 --- a/components/history/core/browser/sync/typed_url_sync_bridge.cc +++ b/components/history/core/browser/sync/typed_url_sync_bridge.cc
@@ -50,8 +50,7 @@ // Enforce oldest to newest visit order. static bool CheckVisitOrdering(const VisitVector& visits) { int64_t previous_visit_time = 0; - for (VisitVector::const_iterator visit = visits.begin(); - visit != visits.end(); ++visit) { + for (auto visit = visits.begin(); visit != visits.end(); ++visit) { if (visit != visits.begin() && previous_visit_time > visit->visit_time.ToInternalValue()) return false; @@ -655,9 +654,9 @@ // new visits from the server need to be added to the vector containing // local visits. These visits will be passed to the server. // Insert new visits into the appropriate place in the visits vector. - VisitVector::iterator visit_ix = visits->begin(); - for (std::vector<VisitInfo>::iterator new_visit = new_visits->begin(); - new_visit != new_visits->end(); ++new_visit) { + auto visit_ix = visits->begin(); + for (auto new_visit = new_visits->begin(); new_visit != new_visits->end(); + ++new_visit) { while (visit_ix != visits->end() && new_visit->first > visit_ix->visit_time) { ++visit_ix; @@ -789,7 +788,7 @@ } // Check if local db already has the url from sync. - TypedURLMap::iterator it = local_typed_urls->find(GURL(sync_url.url())); + auto it = local_typed_urls->find(GURL(sync_url.url())); if (it == local_typed_urls->end()) { // There are no matching typed urls from the local db, check for untyped URLRow untyped_url(GURL(sync_url.url())); @@ -870,7 +869,7 @@ if (sync_url.visits_size() > 0) { base::Time earliest_visit = base::Time::FromInternalValue(sync_url.visits(0)); - for (VisitVector::iterator i = visits.begin(); + for (auto i = visits.begin(); i != visits.end() && i->visit_time < earliest_visit;) { i = visits.erase(i); }
diff --git a/components/history/core/browser/thumbnail_database.cc b/components/history/core/browser/thumbnail_database.cc index 7e4fa9bf..1f296d7a 100644 --- a/components/history/core/browser/thumbnail_database.cc +++ b/components/history/core/browser/thumbnail_database.cc
@@ -776,8 +776,7 @@ return false; bool result = false; - for (std::vector<IconMapping>::iterator m = mapping_data.begin(); - m != mapping_data.end(); ++m) { + for (auto m = mapping_data.begin(); m != mapping_data.end(); ++m) { if (required_icon_types.count(m->icon_type) != 0) { result = true; if (!filtered_mapping_data)
diff --git a/components/history/core/browser/top_sites_cache.cc b/components/history/core/browser/top_sites_cache.cc index b4465d33..ec410481 100644 --- a/components/history/core/browser/top_sites_cache.cc +++ b/components/history/core/browser/top_sites_cache.cc
@@ -56,8 +56,7 @@ bool TopSitesCache::GetPageThumbnail( const GURL& url, scoped_refptr<base::RefCountedMemory>* bytes) const { - std::map<GURL, Images>::const_iterator found = - images_.find(GetCanonicalURL(url)); + auto found = images_.find(GetCanonicalURL(url)); if (found != images_.end()) { base::RefCountedMemory* data = found->second.thumbnail.get(); if (data) { @@ -70,8 +69,7 @@ bool TopSitesCache::GetPageThumbnailScore(const GURL& url, ThumbnailScore* score) const { - std::map<GURL, Images>::const_iterator found = - images_.find(GetCanonicalURL(url)); + auto found = images_.find(GetCanonicalURL(url)); if (found != images_.end()) { *score = found->second.thumbnail_score; return true; @@ -80,13 +78,12 @@ } const GURL& TopSitesCache::GetCanonicalURL(const GURL& url) const { - CanonicalURLs::const_iterator it = GetCanonicalURLsIterator(url); + auto it = GetCanonicalURLsIterator(url); return it == canonical_urls_.end() ? url : it->first.first->url; } GURL TopSitesCache::GetGeneralizedCanonicalURL(const GURL& url) const { - CanonicalURLs::const_iterator it_hi = - canonical_urls_.lower_bound(CanonicalURLQuery(url).entry()); + auto it_hi = canonical_urls_.lower_bound(CanonicalURLQuery(url).entry()); if (it_hi != canonical_urls_.end()) { // Test match ignoring "?query#ref". This also handles exact match. if (url.ReplaceComponents(clear_query_ref_) == @@ -97,8 +94,7 @@ // Everything on or after |it_hi| is irrelevant. GURL base_url(url.ReplaceComponents(clear_path_query_ref_)); - CanonicalURLs::const_iterator it_lo = - canonical_urls_.lower_bound(CanonicalURLQuery(base_url).entry()); + auto it_lo = canonical_urls_.lower_bound(CanonicalURLQuery(base_url).entry()); if (it_lo == canonical_urls_.end()) return GURL::EmptyGURL(); GURL compare_url_lo(GetURLFromIterator(it_lo)); @@ -110,7 +106,7 @@ // Search in [|it_lo|, |it_hi|) in reversed order. The first URL found that's // a prefix of |url| (ignoring "?query#ref") would be returned. - for (CanonicalURLs::const_iterator it = it_hi; it != it_lo;) { + for (auto it = it_hi; it != it_lo;) { --it; GURL compare_url(GetURLFromIterator(it)); DCHECK(HaveSameSchemeHostAndPort(compare_url, url));
diff --git a/components/history/core/browser/top_sites_impl.cc b/components/history/core/browser/top_sites_impl.cc index 7b0e530..5a3e1a64 100644 --- a/components/history/core/browser/top_sites_impl.cc +++ b/components/history/core/browser/top_sites_impl.cc
@@ -374,7 +374,7 @@ // Add forced URLs and sort. Added to the end of the list of forced URLs // since this is almost always where it needs to go, unless the user's local // clock is fiddled with. - MostVisitedURLList::iterator mid = new_list.begin() + num_forced; + auto mid = new_list.begin() + num_forced; mid = new_list.insert(mid, new_url); std::inplace_merge(new_list.begin(), mid, mid + 1, ForcedURLComparator); SetTopSites(new_list, CALL_LOCATION_FROM_FORCED_URLS); @@ -452,7 +452,7 @@ rank++; DCHECK(new_list[i].last_forced_time.is_null() == (rank != -1)) << "Forced URLs must all appear before non-forced URLs."; - std::map<GURL, size_t>::iterator found = all_old_urls.find(new_list[i].url); + auto found = all_old_urls.find(new_list[i].url); if (found == all_old_urls.end()) { MostVisitedURLWithRank added; added.url = new_list[i]; @@ -591,8 +591,7 @@ } void TopSitesImpl::RemoveTemporaryThumbnailByURL(const GURL& url) { - for (TempImages::iterator i = temp_images_.begin(); i != temp_images_.end(); - ++i) { + for (auto i = temp_images_.begin(); i != temp_images_.end(); ++i) { if (i->first == url) { temp_images_.erase(i); return; @@ -765,8 +764,7 @@ const GURL& canonical_url = cache_->GetCanonicalURL(mv.url); // At the time we get the thumbnail redirects aren't known, so we have to // iterate through all the images. - for (TempImages::iterator it = temp_images_.begin(); - it != temp_images_.end(); ++it) { + for (auto it = temp_images_.begin(); it != temp_images_.end(); ++it) { if (canonical_url == cache_->GetCanonicalURL(it->first)) { bool success = SetPageThumbnailEncoded( mv.url, it->second.thumbnail.get(), it->second.thumbnail_score); @@ -908,8 +906,8 @@ return; MostVisitedURLList new_top_sites(cache_->top_sites()); - for (std::set<size_t>::reverse_iterator i = indices_to_delete.rbegin(); - i != indices_to_delete.rend(); i++) { + for (auto i = indices_to_delete.rbegin(); i != indices_to_delete.rend(); + i++) { new_top_sites.erase(new_top_sites.begin() + *i); } SetTopSites(new_top_sites, CALL_LOCATION_FROM_OTHER_PLACES);
diff --git a/components/history/core/browser/visit_database.cc b/components/history/core/browser/visit_database.cc index cf76ed7..8b4712c 100644 --- a/components/history/core/browser/visit_database.cc +++ b/components/history/core/browser/visit_database.cc
@@ -301,8 +301,7 @@ VisitVector* visits) { visits->clear(); - for (std::vector<base::Time>::const_iterator it = times.begin(); - it != times.end(); ++it) { + for (auto it = times.begin(); it != times.end(); ++it) { sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " "WHERE visit_time == ?"));
diff --git a/components/image_fetcher/core/image_fetcher_impl.cc b/components/image_fetcher/core/image_fetcher_impl.cc index 6e1acc45..4a845a3 100644 --- a/components/image_fetcher/core/image_fetcher_impl.cc +++ b/components/image_fetcher/core/image_fetcher_impl.cc
@@ -50,7 +50,7 @@ const net::NetworkTrafficAnnotationTag& traffic_annotation) { // Before starting to fetch the image. Look for a request in progress for // |image_url|, and queue if appropriate. - ImageRequestMap::iterator it = pending_net_requests_.find(image_url); + auto it = pending_net_requests_.find(image_url); if (it == pending_net_requests_.end()) { ImageRequest request; request.id = id; @@ -123,7 +123,7 @@ const RequestMetadata& metadata, const gfx::Image& image) { // Get request for the given image_url from the request queue. - ImageRequestMap::iterator image_iter = pending_net_requests_.find(image_url); + auto image_iter = pending_net_requests_.find(image_url); DCHECK(image_iter != pending_net_requests_.end()); ImageRequest* request = &image_iter->second;
diff --git a/components/infobars/core/infobar_container.cc b/components/infobars/core/infobar_container.cc index c9eeacc9..b4d3cee 100644 --- a/components/infobars/core/infobar_container.cc +++ b/components/infobars/core/infobar_container.cc
@@ -79,7 +79,7 @@ void InfoBarContainer::RemoveInfoBar(InfoBar* infobar) { infobar->set_container(nullptr); - InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar)); + auto i(std::find(infobars_.begin(), infobars_.end(), infobar)); DCHECK(i != infobars_.end()); PlatformSpecificRemoveInfoBar(infobar); infobars_.erase(i);
diff --git a/components/infobars/core/infobar_manager.cc b/components/infobars/core/infobar_manager.cc index a597f851..ec9d7cb 100644 --- a/components/infobars/core/infobar_manager.cc +++ b/components/infobars/core/infobar_manager.cc
@@ -76,8 +76,7 @@ return AddInfoBar(std::move(new_infobar)); // Deletes the infobar. DCHECK(new_infobar); - InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), - old_infobar)); + auto i(std::find(infobars_.begin(), infobars_.end(), old_infobar)); DCHECK(i != infobars_.end()); InfoBar* new_infobar_ptr = new_infobar.release(); @@ -138,7 +137,7 @@ return; } - InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar)); + auto i(std::find(infobars_.begin(), infobars_.end(), infobar)); DCHECK(i != infobars_.end()); // Remove the infobar before notifying, so that if any observers call back to
diff --git a/components/keyed_service/core/dependency_graph.cc b/components/keyed_service/core/dependency_graph.cc index 8d500f6..99e9b8db 100644 --- a/components/keyed_service/core/dependency_graph.cc +++ b/components/keyed_service/core/dependency_graph.cc
@@ -50,9 +50,9 @@ base::Erase(all_nodes_, node); // Remove all dependency edges that contain this node. - EdgeMap::iterator it = edges_.begin(); + auto it = edges_.begin(); while (it != edges_.end()) { - EdgeMap::iterator temp = it; + auto temp = it; ++it; if (temp->first == node || temp->second == node) @@ -106,15 +106,15 @@ std::pair<EdgeMap::iterator, EdgeMap::iterator> range = edges.equal_range(node); - EdgeMap::iterator it = range.first; + auto it = range.first; while (it != range.second) { DependencyNode* dest = it->second; - EdgeMap::iterator temp = it; + auto temp = it; it++; edges.erase(temp); bool has_incoming_edges = false; - for (EdgeMap::iterator jt = edges.begin(); jt != edges.end(); ++jt) { + for (auto jt = edges.begin(); jt != edges.end(); ++jt) { if (jt->second == dest) { has_incoming_edges = true; break;
diff --git a/components/leveldb_proto/proto_database_impl_unittest.cc b/components/leveldb_proto/proto_database_impl_unittest.cc index 5ecf6a7d..c1053b09 100644 --- a/components/leveldb_proto/proto_database_impl_unittest.cc +++ b/components/leveldb_proto/proto_database_impl_unittest.cc
@@ -165,7 +165,7 @@ const std::vector<TestProto>& actual) { EXPECT_EQ(expected.size(), actual.size()); for (size_t i = 0; i < actual.size(); i++) { - EntryMap::iterator expected_it = expected.find(actual[i].id()); + auto expected_it = expected.find(actual[i].id()); EXPECT_TRUE(expected_it != expected.end()); std::string serialized_expected = expected_it->second.SerializeAsString(); std::string serialized_actual = actual[i].SerializeAsString();
diff --git a/components/login/screens/screen_context.cc b/components/login/screens/screen_context.cc index f90bbe18..7d5e700c 100644 --- a/components/login/screens/screen_context.cc +++ b/components/login/screens/screen_context.cc
@@ -16,9 +16,7 @@ template <typename StringListType> base::ListValue* StringListToListValue(const StringListType& list) { base::ListValue* result = new base::ListValue(); - for (typename StringListType::const_iterator it = list.begin(); - it != list.end(); - ++it) { + for (auto it = list.begin(); it != list.end(); ++it) { result->AppendString(*it); } return result;
diff --git a/components/nacl/browser/nacl_browser.cc b/components/nacl/browser/nacl_browser.cc index 8f876de..de06e59 100644 --- a/components/nacl/browser/nacl_browser.cc +++ b/components/nacl/browser/nacl_browser.cc
@@ -335,7 +335,7 @@ int NaClBrowser::GetProcessGdbDebugStubPort(int process_id) { // Called from TaskManager TaskGroup impl, on CrBrowserMain. DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - GdbDebugStubPortMap::iterator i = gdb_debug_stub_port_map_.find(process_id); + auto i = gdb_debug_stub_port_map_.find(process_id); if (i != gdb_debug_stub_port_map_.end()) { return i->second; } @@ -418,8 +418,7 @@ // re-entrancy problems that could occur if the closure was invoked // directly. For example, this could result in use-after-free of the // process host. - for (std::vector<base::Closure>::iterator iter = waiting_.begin(); - iter != waiting_.end(); ++iter) { + for (auto iter = waiting_.begin(); iter != waiting_.end(); ++iter) { base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, *iter); } waiting_.clear(); @@ -455,7 +454,7 @@ if (file_token[0] != 0 || file_token[1] != 0) { // If the file_token is in use, ask for another number. std::string key(reinterpret_cast<char*>(file_token), sizeof(file_token)); - PathCacheType::iterator iter = path_cache_.Peek(key); + auto iter = path_cache_.Peek(key); if (iter == path_cache_.end()) { path_cache_.Put(key, path); *file_token_lo = file_token[0]; @@ -472,7 +471,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::IO); uint64_t file_token[2] = {file_token_lo, file_token_hi}; std::string key(reinterpret_cast<char*>(file_token), sizeof(file_token)); - PathCacheType::iterator iter = path_cache_.Peek(key); + auto iter = path_cache_.Peek(key); if (iter == path_cache_.end()) { *path = base::FilePath(FILE_PATH_LITERAL("")); return false;
diff --git a/components/nacl/browser/pnacl_host.cc b/components/nacl/browser/pnacl_host.cc index fe3dc6719..51e3f22 100644 --- a/components/nacl/browser/pnacl_host.cc +++ b/components/nacl/browser/pnacl_host.cc
@@ -238,7 +238,7 @@ } TranslationID id(render_process_id, pp_instance); - PendingTranslationMap::iterator entry = pending_translations_.find(id); + auto entry = pending_translations_.find(id); if (entry != pending_translations_.end()) { // Existing translation must have been abandonded. Clean it up. LOG(ERROR) << "GetNexeFd for already-pending translation"; @@ -288,7 +288,7 @@ scoped_refptr<net::DrainableIOBuffer> buffer) { DCHECK(thread_checker_.CalledOnValidThread()); pending_backend_operations_--; - PendingTranslationMap::iterator entry(pending_translations_.find(id)); + auto entry(pending_translations_.find(id)); if (entry == pending_translations_.end()) { LOG(ERROR) << "OnCacheQueryReturn: id not found"; DeInitIfSafe(); @@ -310,7 +310,7 @@ void PnaclHost::OnTempFileReturn(const TranslationID& id, base::File file) { DCHECK(thread_checker_.CalledOnValidThread()); - PendingTranslationMap::iterator entry(pending_translations_.find(id)); + auto entry(pending_translations_.find(id)); if (entry == pending_translations_.end()) { // The renderer may have signaled an error or closed while the temp // file was being created. @@ -348,9 +348,8 @@ if (!pt->got_cache_hit) { // Check if there is already a pending translation for this file. If there // is, we will wait for it to come back, to avoid redundant translations. - for (PendingTranslationMap::iterator it = pending_translations_.begin(); - it != pending_translations_.end(); - ++it) { + for (auto it = pending_translations_.begin(); + it != pending_translations_.end(); ++it) { // Another translation matches if it's a request for the same file, if (it->second.cache_key == entry->second.cache_key && // and it's not this translation, @@ -426,7 +425,7 @@ if (cache_state_ != CacheReady) return; TranslationID id(render_process_id, pp_instance); - PendingTranslationMap::iterator entry(pending_translations_.find(id)); + auto entry(pending_translations_.find(id)); if (entry == pending_translations_.end()) { LOG(ERROR) << "TranslationFinished: TranslationID " << render_process_id << "," << pp_instance << " not found."; @@ -474,7 +473,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (cache_state_ != CacheReady) return; - PendingTranslationMap::iterator it(pending_translations_.find(id)); + auto it(pending_translations_.find(id)); if (it == pending_translations_.end()) { LOG(ERROR) << "StoreTranslatedNexe: TranslationID " << id.first << "," << id.second << " not found."; @@ -496,7 +495,7 @@ // (Bound callbacks must re-lookup the TranslationID because the translation // could be cancelled before they get called). void PnaclHost::OnTranslatedNexeStored(const TranslationID& id, int net_error) { - PendingTranslationMap::iterator entry(pending_translations_.find(id)); + auto entry(pending_translations_.find(id)); pending_backend_operations_--; if (entry == pending_translations_.end()) { // If the renderer closed while we were storing the nexe, we land here. @@ -515,9 +514,8 @@ void PnaclHost::RequeryMatchingTranslations(const std::string& key) { DCHECK(thread_checker_.CalledOnValidThread()); // Check for outstanding misses to this same file - for (PendingTranslationMap::iterator it = pending_translations_.begin(); - it != pending_translations_.end(); - ++it) { + for (auto it = pending_translations_.begin(); + it != pending_translations_.end(); ++it) { if (it->second.cache_key == key) { // Re-send the cache read request. This time we expect a hit, but if // something goes wrong, it will just handle it like a miss. @@ -535,7 +533,7 @@ std::unique_ptr<base::File> file, int file_error) { DCHECK(thread_checker_.CalledOnValidThread()); - PendingTranslationMap::iterator entry(pending_translations_.find(id)); + auto entry(pending_translations_.find(id)); if (entry == pending_translations_.end()) { CloseBaseFile(std::move(*file.get())); return; @@ -558,9 +556,9 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (cache_state_ != CacheReady) return; - for (PendingTranslationMap::iterator it = pending_translations_.begin(); + for (auto it = pending_translations_.begin(); it != pending_translations_.end();) { - PendingTranslationMap::iterator to_erase(it++); + auto to_erase(it++); if (to_erase->first.first == render_process_id) { // Clean up the open files. if (to_erase->second.nexe_fd) {
diff --git a/components/nacl/loader/nacl_ipc_adapter.cc b/components/nacl/loader/nacl_ipc_adapter.cc index d979e42f..15d8d128 100644 --- a/components/nacl/loader/nacl_ipc_adapter.cc +++ b/components/nacl/loader/nacl_ipc_adapter.cc
@@ -508,8 +508,7 @@ if (type == IPC_REPLY_ID) { int id = IPC::SyncMessage::GetMessageId(msg); - IOThreadData::PendingSyncMsgMap::iterator it = - io_thread_data_.pending_sync_msgs_.find(id); + auto it = io_thread_data_.pending_sync_msgs_.find(id); DCHECK(it != io_thread_data_.pending_sync_msgs_.end()); if (it != io_thread_data_.pending_sync_msgs_.end()) { type = it->second;
diff --git a/components/nacl/loader/nacl_listener.cc b/components/nacl/loader/nacl_listener.cc index 42cd832..72e6d8e 100644 --- a/components/nacl/loader/nacl_listener.cc +++ b/components/nacl/loader/nacl_listener.cc
@@ -249,8 +249,7 @@ // This callback is executed only on |io_thread_| with NaClIPCAdapter's // |lock_| not being held. DCHECK(!cb.is_null()); - PrefetchedResourceFilesMap::iterator it = - prefetched_resource_files_.find(key); + auto it = prefetched_resource_files_.find(key); if (it != prefetched_resource_files_.end()) { // Fast path for prefetched FDs.
diff --git a/components/nacl/renderer/nexe_load_manager.cc b/components/nacl/renderer/nexe_load_manager.cc index 10768d5..206bab7 100644 --- a/components/nacl/renderer/nexe_load_manager.cc +++ b/components/nacl/renderer/nexe_load_manager.cc
@@ -70,7 +70,7 @@ std::string LookupAttribute(const std::map<std::string, std::string>& args, const std::string& key) { - std::map<std::string, std::string>::const_iterator it = args.find(key); + auto it = args.find(key); if (it != args.end()) return it->second; return std::string();
diff --git a/components/nacl/renderer/pnacl_translation_resource_host.cc b/components/nacl/renderer/pnacl_translation_resource_host.cc index 1ffcb62..aec91ddc 100644 --- a/components/nacl/renderer/pnacl_translation_resource_host.cc +++ b/components/nacl/renderer/pnacl_translation_resource_host.cc
@@ -110,7 +110,7 @@ IPC::PlatformFileForTransit file) { DCHECK(io_task_runner_->BelongsToCurrentThread()); base::File base_file = IPC::PlatformFileForTransitToFile(file); - CacheRequestInfoMap::iterator it = pending_cache_requests_.find(instance); + auto it = pending_cache_requests_.find(instance); if (!base_file.IsValid()) { DLOG(ERROR) << "Got invalid platformfilefortransit"; } @@ -131,9 +131,8 @@ void PnaclTranslationResourceHost::CleanupCacheRequests() { DCHECK(io_task_runner_->BelongsToCurrentThread()); - for (CacheRequestInfoMap::iterator it = pending_cache_requests_.begin(); - it != pending_cache_requests_.end(); - ++it) { + for (auto it = pending_cache_requests_.begin(); + it != pending_cache_requests_.end(); ++it) { PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( FROM_HERE, base::BindOnce(it->second, static_cast<int32_t>(PP_ERROR_ABORTED),
diff --git a/components/network_hints/renderer/renderer_dns_prefetch.cc b/components/network_hints/renderer/renderer_dns_prefetch.cc index 1352ee8..169c751 100644 --- a/components/network_hints/renderer/renderer_dns_prefetch.cc +++ b/components/network_hints/renderer/renderer_dns_prefetch.cc
@@ -135,9 +135,7 @@ // We are on the renderer thread, and just need to send things to the browser. NameList names; size_t domains_handled = 0; - for (DomainUseMap::iterator it = domain_map_.begin(); - it != domain_map_.end(); - ++it) { + for (auto it = domain_map_.begin(); it != domain_map_.end(); ++it) { if (0 == (it->second & kLookupRequested)) { it->second |= kLookupRequested; domains_handled++;
diff --git a/components/network_session_configurator/browser/network_session_configurator.cc b/components/network_session_configurator/browser/network_session_configurator.cc index 8c30849..22edc91b 100644 --- a/components/network_session_configurator/browser/network_session_configurator.cc +++ b/components/network_session_configurator/browser/network_session_configurator.cc
@@ -62,7 +62,7 @@ const std::string& GetVariationParam( const std::map<std::string, std::string>& params, const std::string& key) { - std::map<std::string, std::string>::const_iterator it = params.find(key); + auto it = params.find(key); if (it == params.end()) return base::EmptyString(); @@ -200,8 +200,7 @@ quic::QuicTagVector GetQuicConnectionOptions( const VariationParameters& quic_trial_params) { - VariationParameters::const_iterator it = - quic_trial_params.find("connection_options"); + auto it = quic_trial_params.find("connection_options"); if (it == quic_trial_params.end()) { return quic::QuicTagVector(); } @@ -211,8 +210,7 @@ quic::QuicTagVector GetQuicClientConnectionOptions( const VariationParameters& quic_trial_params) { - VariationParameters::const_iterator it = - quic_trial_params.find("client_connection_options"); + auto it = quic_trial_params.find("client_connection_options"); if (it == quic_trial_params.end()) { return quic::QuicTagVector(); }
diff --git a/components/ntp_snippets/category_rankers/click_based_category_ranker.cc b/components/ntp_snippets/category_rankers/click_based_category_ranker.cc index a62443f5..d6d5a79 100644 --- a/components/ntp_snippets/category_rankers/click_based_category_ranker.cc +++ b/components/ntp_snippets/category_rankers/click_based_category_ranker.cc
@@ -321,7 +321,7 @@ DecayClicksIfNeeded(); - std::vector<RankedCategory>::iterator current = FindCategory(category); + auto current = FindCategory(category); DCHECK_GE(current->clicks, 0); // The overflow is ignored. It is unlikely to happen, because of click count // decay. @@ -329,7 +329,7 @@ // Move the category up if appropriate. if (current != ordered_categories_.begin()) { - std::vector<RankedCategory>::iterator previous = current - 1; + auto previous = current - 1; const int passing_margin = GetPositionPassingMargin(previous); if (current->clicks >= previous->clicks + passing_margin) { const int new_index = previous - ordered_categories_.begin(); @@ -352,9 +352,9 @@ const int penalty = GetDismissedCategoryPenalty(); if (penalty != 0) { // Dismissed category penalty is turned on? - std::vector<RankedCategory>::iterator current = FindCategory(category); + auto current = FindCategory(category); for (int downgrade = 0; downgrade < penalty; ++downgrade) { - std::vector<RankedCategory>::iterator next = current + 1; + auto next = current + 1; if (next == ordered_categories_.end()) { break; } @@ -363,7 +363,7 @@ } DCHECK(current != ordered_categories_.begin()); - std::vector<RankedCategory>::iterator previous = current - 1; + auto previous = current - 1; int new_clicks = std::max(previous->clicks - GetPassingMargin(), 0); // The previous category may have more clicks (but not enough to pass the // margin, this is possible when penalty >= 2), therefore, we ensure that @@ -542,7 +542,7 @@ return; } - std::vector<RankedCategory>::iterator anchor_it = FindCategory(anchor); + auto anchor_it = FindCategory(anchor); ordered_categories_.insert(anchor_it + (after ? 1 : 0), RankedCategory(category_to_insert, /*clicks=*/anchor_it->clicks,
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc index f9a50be..d70dc34 100644 --- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc +++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
@@ -86,16 +86,14 @@ void PrefetchedPagesTrackerImpl::OfflinePageDeleted( const offline_pages::OfflinePageModel::DeletedPageInfo& page_info) { - std::map<int64_t, GURL>::iterator offline_id_it = - offline_id_to_url_mapping_.find(page_info.offline_id); + auto offline_id_it = offline_id_to_url_mapping_.find(page_info.offline_id); if (offline_id_it == offline_id_to_url_mapping_.end()) { // We did not know about this page, thus, nothing to delete. return; } - std::map<GURL, int>::iterator url_it = - prefetched_url_counts_.find(offline_id_it->second); + auto url_it = prefetched_url_counts_.find(offline_id_it->second); DCHECK(url_it != prefetched_url_counts_.end()); --url_it->second; if (url_it->second == 0) {
diff --git a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc index b0258ce..34660b5 100644 --- a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc +++ b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc
@@ -262,7 +262,7 @@ auto icon_list = std::make_unique<base::ListValue>(); for (const auto& entry : kIconTypesAndNames) { - FaviconResultMap::const_iterator it = result_map.find( + auto it = result_map.find( FaviconResultMap::key_type(tile.url, entry.type_enum)); if (it != result_map.end()) {
diff --git a/components/offline_items_collection/core/throttled_offline_content_provider.cc b/components/offline_items_collection/core/throttled_offline_content_provider.cc index d44d8a25..2d2ff2b 100644 --- a/components/offline_items_collection/core/throttled_offline_content_provider.cc +++ b/components/offline_items_collection/core/throttled_offline_content_provider.cc
@@ -157,7 +157,7 @@ void ThrottledOfflineContentProvider::UpdateItemIfPresent( const OfflineItem& item) { - OfflineItemMap::iterator it = updates_.find(item.id); + auto it = updates_.find(item.id); if (it != updates_.end()) it->second = item; }
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index aab1bd8..4b565ece 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -214,9 +214,6 @@ "//components/vector_icons", ] } - - # TODO(brettw) Fix the include cycle and remove this line. - allow_circular_includes_from = [ "//components/search_engines" ] } if (is_android) {
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index decf7182..1558a0a 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -668,13 +668,6 @@ return value.empty() || (value == "true"); } -bool OmniboxFieldTrial::KeywordRequiresRegistry() { - const std::string& value = variations::GetVariationParamValue( - kBundledExperimentFieldTrialName, - kKeywordRequiresRegistryRule); - return value.empty() || (value == "true"); -} - bool OmniboxFieldTrial::KeywordRequiresPrefixMatch() { const std::string& value = variations::GetVariationParamValue( kBundledExperimentFieldTrialName,
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h index 020c70ce..8e28fc7 100644 --- a/components/omnibox/browser/omnibox_field_trial.h +++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -389,11 +389,15 @@ // For the aggressive keyword matching experiment that's part of the bundled // omnibox field trial. - // Returns whether KeywordProvider should consider the registry portion + // One function is missing from here to avoid a cyclic dependency + // between search_engine and omnibox. In the search_engine component + // there is a OmniboxFieldTrialKeywordRequiresRegistry function + // that logically should be here. + // + // It returns whether KeywordProvider should consider the registry portion // (e.g., co.uk) of keywords that look like hostnames as an important part of // the keyword name for matching purposes. Returns true if the experiment // isn't active. - static bool KeywordRequiresRegistry(); // For keywords that look like hostnames, returns whether KeywordProvider // should require users to type a prefix of the hostname to match against
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc index d0cd6d50..cb9866cf 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -445,8 +445,7 @@ // Will point to the password included in |found_field| which is first in the // order of fields in |processed_fields|. - std::vector<ProcessedField>::const_iterator first_relevant_password = - processed_fields.end(); + auto first_relevant_password = processed_fields.end(); if (!found_fields->HasPasswords()) { // What is the best interactability among passwords?
diff --git a/components/password_manager/core/browser/password_syncable_service.cc b/components/password_manager/core/browser/password_syncable_service.cc index 02fc3ce..7fe193ba 100644 --- a/components/password_manager/core/browser/password_syncable_service.cc +++ b/components/password_manager/core/browser/password_syncable_service.cc
@@ -202,8 +202,7 @@ SyncEntries sync_entries; // Changes from password db that need to be propagated to sync. syncer::SyncChangeList updated_db_entries; - for (syncer::SyncDataList::const_iterator sync_iter = - initial_sync_data.begin(); + for (auto sync_iter = initial_sync_data.begin(); sync_iter != initial_sync_data.end(); ++sync_iter) { CreateOrUpdateEntry(*sync_iter, &new_local_entries, @@ -211,8 +210,8 @@ &updated_db_entries); } - for (PasswordEntryMap::iterator it = new_local_entries.begin(); - it != new_local_entries.end(); ++it) { + for (auto it = new_local_entries.begin(); it != new_local_entries.end(); + ++it) { updated_db_entries.push_back( syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, SyncDataFromPassword(*it->second))); @@ -275,8 +274,7 @@ SyncEntries sync_entries; base::Time time_now = base::Time::Now(); - for (syncer::SyncChangeList::const_iterator it = change_list.begin(); - it != change_list.end(); ++it) { + for (auto it = change_list.begin(); it != change_list.end(); ++it) { const sync_pb::EntitySpecifics& specifics = it->sync_data().GetSpecifics(); std::vector<std::unique_ptr<autofill::PasswordForm>>* entries = sync_entries.EntriesForChangeType(it->change_type()); @@ -309,8 +307,7 @@ if (is_processing_sync_changes_) return; syncer::SyncChangeList sync_changes; - for (PasswordStoreChangeList::const_iterator it = local_changes.begin(); - it != local_changes.end(); ++it) { + for (auto it = local_changes.begin(); it != local_changes.end(); ++it) { syncer::SyncData data = (it->type() == PasswordStoreChange::REMOVE ? syncer::SyncData::CreateLocalDelete(MakePasswordSyncTag(it->form()), syncer::PASSWORDS) : @@ -388,8 +385,7 @@ std::string tag = MakePasswordSyncTag(password_specifics); // Check whether the data from sync is already in the password store. - PasswordEntryMap::iterator existing_local_entry_iter = - unmatched_data_from_password_db->find(tag); + auto existing_local_entry_iter = unmatched_data_from_password_db->find(tag); base::Time time_now = base::Time::Now(); if (existing_local_entry_iter == unmatched_data_from_password_db->end()) { // The sync data is not in the password store, so we need to create it in
diff --git a/components/password_manager/core/browser/password_syncable_service_unittest.cc b/components/password_manager/core/browser/password_syncable_service_unittest.cc index 417eec1..ff70da8 100644 --- a/components/password_manager/core/browser/password_syncable_service_unittest.cc +++ b/components/password_manager/core/browser/password_syncable_service_unittest.cc
@@ -418,8 +418,7 @@ SyncDataList actual_list = service()->GetAllSyncData(syncer::PASSWORDS); std::vector<autofill::PasswordForm> actual_form_list; - for (SyncDataList::iterator it = actual_list.begin(); it != actual_list.end(); - ++it) { + for (auto it = actual_list.begin(); it != actual_list.end(); ++it) { actual_form_list.push_back( PasswordFromSpecifics(GetPasswordSpecifics(*it))); }
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc index 07747851..fea3746 100644 --- a/components/password_manager/core/browser/test_password_store.cc +++ b/components/password_manager/core/browser/test_password_store.cc
@@ -35,7 +35,7 @@ // The store is empty, if the sum of all stored passwords across all entries // in |stored_passwords_| is 0. size_t number_of_passwords = 0u; - for (PasswordMap::const_iterator it = stored_passwords_.begin(); + for (auto it = stored_passwords_.begin(); !number_of_passwords && it != stored_passwords_.end(); ++it) { number_of_passwords += it->second.size(); } @@ -60,8 +60,7 @@ PasswordStoreChangeList changes; std::vector<autofill::PasswordForm>& forms = stored_passwords_[form.signon_realm]; - for (std::vector<autofill::PasswordForm>::iterator it = forms.begin(); - it != forms.end(); ++it) { + for (auto it = forms.begin(); it != forms.end(); ++it) { if (ArePasswordFormUniqueKeyEqual(form, *it)) { *it = form; changes.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, form)); @@ -75,7 +74,7 @@ PasswordStoreChangeList changes; std::vector<autofill::PasswordForm>& forms = stored_passwords_[form.signon_realm]; - std::vector<autofill::PasswordForm>::iterator it = forms.begin(); + auto it = forms.begin(); while (it != forms.end()) { if (ArePasswordFormUniqueKeyEqual(form, *it)) { it = forms.erase(it);
diff --git a/components/payments/content/installable_payment_app_crawler.cc b/components/payments/content/installable_payment_app_crawler.cc index 921a264..8f3deab 100644 --- a/components/payments/content/installable_payment_app_crawler.cc +++ b/components/payments/content/installable_payment_app_crawler.cc
@@ -338,8 +338,7 @@ "app manifest " + web_app_manifest_url.spec() + "."); } else { - std::map<GURL, std::unique_ptr<WebAppInstallationInfo>>::iterator it = - installable_apps_.find(method_manifest_url); + auto it = installable_apps_.find(method_manifest_url); DCHECK(it != installable_apps_.end()); DCHECK(url::IsSameOriginWith(GURL(it->second->sw_scope), web_app_manifest_url));
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index 0391266..b3619af8 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc
@@ -79,8 +79,7 @@ if (!response_.IsNull()) { plugin->DidReceiveResponse(response_); size_t total_bytes = 0; - for (std::list<std::string>::iterator it = data_.begin(); it != data_.end(); - ++it) { + for (auto it = data_.begin(); it != data_.end(); ++it) { plugin->DidReceiveData(it->c_str(), it->length()); total_bytes += it->length(); }
diff --git a/components/prefs/pref_member.cc b/components/prefs/pref_member.cc index 59917510..6b74dde 100644 --- a/components/prefs/pref_member.cc +++ b/components/prefs/pref_member.cc
@@ -133,8 +133,7 @@ const base::ListValue* list = static_cast<const base::ListValue*>(&value); std::vector<std::string> local_vector; - for (base::ListValue::const_iterator it = list->begin(); - it != list->end(); ++it) { + for (auto it = list->begin(); it != list->end(); ++it) { std::string string_value; if (!it->GetAsString(&string_value)) return false;
diff --git a/components/prefs/pref_notifier_impl_unittest.cc b/components/prefs/pref_notifier_impl_unittest.cc index c69bece86..ee42891 100644 --- a/components/prefs/pref_notifier_impl_unittest.cc +++ b/components/prefs/pref_notifier_impl_unittest.cc
@@ -54,8 +54,7 @@ MOCK_METHOD1(FireObservers, void(const std::string& path)); size_t CountObserver(const std::string& path, PrefObserver* obs) { - PrefObserverMap::const_iterator observer_iterator = - pref_observers()->find(path); + auto observer_iterator = pref_observers()->find(path); if (observer_iterator == pref_observers()->end()) return false;
diff --git a/components/prefs/pref_service.cc b/components/prefs/pref_service.cc index e374f0e..47460cf2 100644 --- a/components/prefs/pref_service.cc +++ b/components/prefs/pref_service.cc
@@ -241,7 +241,7 @@ const PrefService::Preference* PrefService::FindPreference( const std::string& pref_name) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - PreferenceMap::iterator it = prefs_map_.find(pref_name); + auto it = prefs_map_.find(pref_name); if (it != prefs_map_.end()) return &(it->second); const base::Value* default_value = nullptr;
diff --git a/components/query_parser/query_parser.cc b/components/query_parser/query_parser.cc index b7426eaf..0686489 100644 --- a/components/query_parser/query_parser.cc +++ b/components/query_parser/query_parser.cc
@@ -36,8 +36,7 @@ // position at |index|. void CoalesceMatchesFrom(size_t index, Snippet::MatchPositions* matches) { Snippet::MatchPosition& mp = (*matches)[index]; - for (Snippet::MatchPositions::iterator i = matches->begin() + index + 1; - i != matches->end(); ) { + for (auto i = matches->begin() + index + 1; i != matches->end();) { if (SnippetIntersects(mp, *i)) { mp.second = std::max(mp.second, i->second); i = matches->erase(i);
diff --git a/components/query_parser/snippet.cc b/components/query_parser/snippet.cc index b809c79c..c702b23 100644 --- a/components/query_parser/snippet.cc +++ b/components/query_parser/snippet.cc
@@ -54,9 +54,8 @@ } // There's at least one match. Find the position of the new match, // potentially extending pairs around it. - Snippet::MatchPositions::iterator i = - std::lower_bound(match_positions->begin(), match_positions->end(), - pair, &PairFirstLessThan); + auto i = std::lower_bound(match_positions->begin(), match_positions->end(), + pair, &PairFirstLessThan); if (i != match_positions->end() && i->first == start) { // Match not at the end and there is already a pair with the same // start. @@ -194,8 +193,7 @@ size_t utf16_pos = 0; const char* utf8_cstring = utf8_string.c_str(); const int32_t utf8_length = static_cast<int32_t>(utf8_string.size()); - for (Snippet::MatchPositions::iterator i = match_positions->begin(); - i != match_positions->end(); ++i) { + for (auto i = match_positions->begin(); i != match_positions->end(); ++i) { i->first = AdvanceAndReturnUTF16Pos(utf8_cstring, utf8_length, static_cast<int32_t>(i->first), &utf8_pos, &utf16_pos);
diff --git a/components/rappor/test_rappor_service.cc b/components/rappor/test_rappor_service.cc index 3c8229f..a561f99 100644 --- a/components/rappor/test_rappor_service.cc +++ b/components/rappor/test_rappor_service.cc
@@ -116,7 +116,7 @@ TestSample::Shadow* TestRapporServiceImpl::GetRecordedSampleForMetric( const std::string& metric_name) { - ShadowMap::iterator it = shadows_.find(metric_name); + auto it = shadows_.find(metric_name); if (it == shadows_.end()) return nullptr; return &it->second; @@ -126,7 +126,7 @@ const std::string& metric_name, std::string* sample, RapporType* type) { - SamplesMap::iterator it = samples_.find(metric_name); + auto it = samples_.find(metric_name); if (it == samples_.end()) return false; *sample = it->second.value;
diff --git a/components/safe_browsing/base_blocking_page.cc b/components/safe_browsing/base_blocking_page.cc index 272eb986..e727d8b0 100644 --- a/components/safe_browsing/base_blocking_page.cc +++ b/components/safe_browsing/base_blocking_page.cc
@@ -168,7 +168,7 @@ // The user does not want to proceed, clear the queued unsafe resources // notifications we received while the interstitial was showing. UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); - UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents()); + auto iter = unsafe_resource_map->find(web_contents()); if (iter != unsafe_resource_map->end() && !iter->second.empty()) { ui_manager_->OnBlockingPageDone(iter->second, false, web_contents(), main_frame_url_); @@ -290,8 +290,8 @@ BaseBlockingPage::GetInterstitialReason( const UnsafeResourceList& unsafe_resources) { bool harmful = false; - for (UnsafeResourceList::const_iterator iter = unsafe_resources.begin(); - iter != unsafe_resources.end(); ++iter) { + for (auto iter = unsafe_resources.begin(); iter != unsafe_resources.end(); + ++iter) { const BaseUIManager::UnsafeResource& resource = *iter; safe_browsing::SBThreatType threat_type = resource.threat_type; if (threat_type == SB_THREAT_TYPE_BILLING)
diff --git a/components/safe_browsing/browser/threat_details.cc b/components/safe_browsing/browser/threat_details.cc index 0736e8f7..540c067 100644 --- a/components/safe_browsing/browser/threat_details.cc +++ b/components/safe_browsing/browser/threat_details.cc
@@ -428,8 +428,7 @@ url_resource->set_parent_id(parent_resource->id()); } if (children) { - for (std::vector<GURL>::const_iterator it = children->begin(); - it != children->end(); ++it) { + for (auto it = children->begin(); it != children->end(); ++it) { // TODO(lpz): Should this first check if the child URL is reportable // before creating the resource? ClientSafeBrowsingReportRequest::Resource* child_resource =
diff --git a/components/safe_browsing/browser/threat_details_cache.cc b/components/safe_browsing/browser/threat_details_cache.cc index c0b44d8..005d112 100644 --- a/components/safe_browsing/browser/threat_details_cache.cc +++ b/components/safe_browsing/browser/threat_details_cache.cc
@@ -126,7 +126,7 @@ ClientSafeBrowsingReportRequest::Resource* ThreatDetailsCacheCollector::GetResource(const GURL& url) { - ResourceMap::iterator it = resources_->find(url.spec()); + auto it = resources_->find(url.spec()); if (it != resources_->end()) { return it->second.get(); }
diff --git a/components/safe_browsing/common/safe_browsing_prefs.cc b/components/safe_browsing/common/safe_browsing_prefs.cc index 74a5a4e0..a3203f8 100644 --- a/components/safe_browsing/common/safe_browsing_prefs.cc +++ b/components/safe_browsing/common/safe_browsing_prefs.cc
@@ -86,56 +86,29 @@ safe_browsing::ExtendedReportingOptInLocation location) { bool pref_value = safe_browsing::IsExtendedReportingEnabled(prefs); - if (safe_browsing::IsScout(prefs)) { - switch (location) { - case safe_browsing::SBER_OPTIN_SITE_CHROME_SETTINGS: - UMA_HISTOGRAM_BOOLEAN( - "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.ChromeSettings", - pref_value); - break; - case safe_browsing::SBER_OPTIN_SITE_ANDROID_SETTINGS: - UMA_HISTOGRAM_BOOLEAN( - "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.AndroidSettings", - pref_value); - break; - case safe_browsing::SBER_OPTIN_SITE_DOWNLOAD_FEEDBACK_POPUP: - UMA_HISTOGRAM_BOOLEAN( - "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.DownloadPopup", - pref_value); - break; - case safe_browsing::SBER_OPTIN_SITE_SECURITY_INTERSTITIAL: - UMA_HISTOGRAM_BOOLEAN( - "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.SecurityInterstitial", - pref_value); - break; - default: - NOTREACHED(); - } - } else { - switch (location) { - case safe_browsing::SBER_OPTIN_SITE_CHROME_SETTINGS: - UMA_HISTOGRAM_BOOLEAN( - "SafeBrowsing.Pref.Scout.SetPref.SBER1Pref.ChromeSettings", - pref_value); - break; - case safe_browsing::SBER_OPTIN_SITE_ANDROID_SETTINGS: - UMA_HISTOGRAM_BOOLEAN( - "SafeBrowsing.Pref.Scout.SetPref.SBER1Pref.AndroidSettings", - pref_value); - break; - case safe_browsing::SBER_OPTIN_SITE_DOWNLOAD_FEEDBACK_POPUP: - UMA_HISTOGRAM_BOOLEAN( - "SafeBrowsing.Pref.Scout.SetPref.SBER1Pref.DownloadPopup", - pref_value); - break; - case safe_browsing::SBER_OPTIN_SITE_SECURITY_INTERSTITIAL: - UMA_HISTOGRAM_BOOLEAN( - "SafeBrowsing.Pref.Scout.SetPref.SBER1Pref.SecurityInterstitial", - pref_value); - break; - default: - NOTREACHED(); - } + switch (location) { + case safe_browsing::SBER_OPTIN_SITE_CHROME_SETTINGS: + UMA_HISTOGRAM_BOOLEAN( + "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.ChromeSettings", + pref_value); + break; + case safe_browsing::SBER_OPTIN_SITE_ANDROID_SETTINGS: + UMA_HISTOGRAM_BOOLEAN( + "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.AndroidSettings", + pref_value); + break; + case safe_browsing::SBER_OPTIN_SITE_DOWNLOAD_FEEDBACK_POPUP: + UMA_HISTOGRAM_BOOLEAN( + "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.DownloadPopup", + pref_value); + break; + case safe_browsing::SBER_OPTIN_SITE_SECURITY_INTERSTITIAL: + UMA_HISTOGRAM_BOOLEAN( + "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.SecurityInterstitial", + pref_value); + break; + default: + NOTREACHED(); } } @@ -199,13 +172,15 @@ const PrefService& prefs, const std::string& extended_reporting_pref, const std::string& scout_pref) { - return IsScout(prefs) ? scout_pref : extended_reporting_pref; + // TODO(lpz): Delete this method and update callers + return scout_pref; } int ChooseOptInTextResource(const PrefService& prefs, int extended_reporting_resource, int scout_resource) { - return IsScout(prefs) ? scout_resource : extended_reporting_resource; + // TODO(lpz): Delete this method and update callers + return scout_resource; } bool ExtendedReportingPrefExists(const PrefService& prefs) { @@ -213,15 +188,12 @@ } ExtendedReportingLevel GetExtendedReportingLevel(const PrefService& prefs) { - if (!IsExtendedReportingEnabled(prefs)) { - return SBER_LEVEL_OFF; - } else { - return IsScout(prefs) ? SBER_LEVEL_SCOUT : SBER_LEVEL_LEGACY; - } + return IsExtendedReportingEnabled(prefs) ? SBER_LEVEL_SCOUT : SBER_LEVEL_OFF; } const char* GetExtendedReportingPrefName(const PrefService& prefs) { - return prefs::kSafeBrowsingScoutReportingEnabled; + // TODO(lpz): Remove this method, use the pref directly in calling code. + return prefs::kSafeBrowsingScoutReportingEnabled; } bool IsExtendedReportingOptInAllowed(const PrefService& prefs) { @@ -236,11 +208,6 @@ return prefs.IsManagedPreference(GetExtendedReportingPrefName(prefs)); } -bool IsScout(const PrefService& prefs) { - return GetExtendedReportingPrefName(prefs) == - prefs::kSafeBrowsingScoutReportingEnabled; -} - void RecordExtendedReportingMetrics(const PrefService& prefs) { // This metric tracks the extended browsing opt-in based on whichever setting // the user is currently seeing. It tells us whether extended reporting is @@ -321,8 +288,6 @@ void UpdateMetricsAfterSecurityInterstitial(const PrefService& prefs, bool on_show_pref_existed, bool on_show_pref_value) { - const ActiveExtendedReportingPref active_pref = - IsScout(prefs) ? SBER2_PREF : SBER1_PREF; const bool cur_pref_value = IsExtendedReportingEnabled(prefs); if (!on_show_pref_existed) { @@ -330,7 +295,7 @@ // User seeing pref for the first time, didn't touch the checkbox (left it // unchecked). UMA_HISTOGRAM_ENUMERATION( - "SafeBrowsing.Pref.Scout.Decision.First_LeftUnchecked", active_pref, + "SafeBrowsing.Pref.Scout.Decision.First_LeftUnchecked", SBER2_PREF, MAX_SBER_PREF); return; } @@ -339,7 +304,7 @@ if (cur_pref_value) { // User turned the pref on. UMA_HISTOGRAM_ENUMERATION( - "SafeBrowsing.Pref.Scout.Decision.First_Enabled", active_pref, + "SafeBrowsing.Pref.Scout.Decision.First_Enabled", SBER2_PREF, MAX_SBER_PREF); return; } @@ -348,7 +313,7 @@ // the interstitial was first shown, they must have turned it on and then // off before the interstitial was closed. UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.Pref.Scout.Decision.First_Disabled", - active_pref, MAX_SBER_PREF); + SBER2_PREF, MAX_SBER_PREF); return; } @@ -358,24 +323,24 @@ if (on_show_pref_value && cur_pref_value) { // User left the pref on. UMA_HISTOGRAM_ENUMERATION( - "SafeBrowsing.Pref.Scout.Decision.Repeat_LeftEnabled", active_pref, + "SafeBrowsing.Pref.Scout.Decision.Repeat_LeftEnabled", SBER2_PREF, MAX_SBER_PREF); return; } else if (on_show_pref_value && !cur_pref_value) { // User turned the pref off. UMA_HISTOGRAM_ENUMERATION( - "SafeBrowsing.Pref.Scout.Decision.Repeat_Disabled", active_pref, + "SafeBrowsing.Pref.Scout.Decision.Repeat_Disabled", SBER2_PREF, MAX_SBER_PREF); return; } else if (!on_show_pref_value && cur_pref_value) { // User turned the pref on. UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.Pref.Scout.Decision.Repeat_Enabled", - active_pref, MAX_SBER_PREF); + SBER2_PREF, MAX_SBER_PREF); return; } else { // Both on_show and cur values are false - user left the pref off. UMA_HISTOGRAM_ENUMERATION( - "SafeBrowsing.Pref.Scout.Decision.Repeat_LeftDisabled", active_pref, + "SafeBrowsing.Pref.Scout.Decision.Repeat_LeftDisabled", SBER2_PREF, MAX_SBER_PREF); return; } @@ -393,10 +358,7 @@ } // Remember that this user saw an interstitial with the current opt-in text. - prefs->SetBoolean(IsScout(*prefs) - ? prefs::kSafeBrowsingSawInterstitialScoutReporting - : prefs::kSafeBrowsingSawInterstitialExtendedReporting, - true); + prefs->SetBoolean(prefs::kSafeBrowsingSawInterstitialScoutReporting, true); } base::ListValue GetSafeBrowsingPreferencesList(PrefService* prefs) {
diff --git a/components/safe_browsing/common/safe_browsing_prefs.h b/components/safe_browsing/common/safe_browsing_prefs.h index 54c4feed..51bb80e2 100644 --- a/components/safe_browsing/common/safe_browsing_prefs.h +++ b/components/safe_browsing/common/safe_browsing_prefs.h
@@ -183,9 +183,6 @@ // enterprise policy, meaning the user can't change it. bool IsExtendedReportingPolicyManaged(const PrefService& prefs); -// Returns whether the currently-active Extended Reporting pref is Scout. -bool IsScout(const PrefService& prefs); - // Updates UMA metrics about Safe Browsing Extended Reporting states. void RecordExtendedReportingMetrics(const PrefService& prefs);
diff --git a/components/safe_browsing/db/database_manager.cc b/components/safe_browsing/db/database_manager.cc index fb15ad4..53ec1b8c 100644 --- a/components/safe_browsing/db/database_manager.cc +++ b/components/safe_browsing/db/database_manager.cc
@@ -32,7 +32,7 @@ bool SafeBrowsingDatabaseManager::CancelApiCheck(Client* client) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - ApiCheckSet::iterator it = FindClientApiCheck(client); + auto it = FindClientApiCheck(client); if (it != api_checks_.end()) { api_checks_.erase(it); return true; @@ -74,8 +74,7 @@ SafeBrowsingDatabaseManager::ApiCheckSet::iterator SafeBrowsingDatabaseManager::FindClientApiCheck(Client* client) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - for (ApiCheckSet::iterator it = api_checks_.begin(); it != api_checks_.end(); - ++it) { + for (auto it = api_checks_.begin(); it != api_checks_.end(); ++it) { if ((*it)->client() == client) { return it; } @@ -107,7 +106,7 @@ // If the check is not in |api_checks_| then the request was cancelled by the // client. - ApiCheckSet::iterator it = api_checks_.find(check.get()); + auto it = api_checks_.find(check.get()); if (it == api_checks_.end()) return;
diff --git a/components/safe_browsing/db/v4_get_hash_protocol_manager.cc b/components/safe_browsing/db/v4_get_hash_protocol_manager.cc index da067cbd..2484294 100644 --- a/components/safe_browsing/db/v4_get_hash_protocol_manager.cc +++ b/components/safe_browsing/db/v4_get_hash_protocol_manager.cc
@@ -789,7 +789,7 @@ int net_error, int response_code, const std::string& data) { - PendingHashRequests::iterator it = pending_hash_requests_.find(url_loader); + auto it = pending_hash_requests_.find(url_loader); DCHECK(it != pending_hash_requests_.end()) << "Request not found"; V4ProtocolManagerUtil::RecordHttpResponseOrErrorCode( "SafeBrowsing.V4GetHash.Network.Result", net_error, response_code);
diff --git a/components/safe_browsing/triggers/trigger_manager.cc b/components/safe_browsing/triggers/trigger_manager.cc index 5403853..43be3c1 100644 --- a/components/safe_browsing/triggers/trigger_manager.cc +++ b/components/safe_browsing/triggers/trigger_manager.cc
@@ -104,7 +104,7 @@ web_contents.GetBrowserContext()->IsOffTheRecord(), /*is_unified_consent_enabled=*/false, IsExtendedReportingEnabled(pref_service), - IsScout(pref_service), + /*is_scout_reporting_enabled=*/true, IsExtendedReportingPolicyManaged(pref_service), /*is_proceed_anyway_disabled=*/false, /*should_open_links_in_new_tab=*/false,
diff --git a/components/search_engines/BUILD.gn b/components/search_engines/BUILD.gn index ce07960..5bde3ac 100644 --- a/components/search_engines/BUILD.gn +++ b/components/search_engines/BUILD.gn
@@ -65,23 +65,18 @@ ":prepopulated_engines", "//base:i18n", "//components/history/core/browser", - "//third_party/metrics_proto", - - # The search_engines target is in an include cycle with - # components/omnibox/browser. The cycle is whitelisted in the - # omnibox/browser target, but should ideally be fixed, then this - # dependency added: - #"//components/omnibox/browser", "//components/infobars/core", "//components/pref_registry", "//components/rappor", "//components/strings", "//components/url_formatter", + "//components/variations", "//google_apis", "//net", "//services/network/public/cpp", "//sql", "//third_party/libxml", + "//third_party/metrics_proto", "//ui/base", "//ui/gfx", "//ui/gfx/geometry",
diff --git a/components/search_engines/DEPS b/components/search_engines/DEPS index 5f550b12..4d290b9d 100644 --- a/components/search_engines/DEPS +++ b/components/search_engines/DEPS
@@ -3,8 +3,6 @@ "+components/history/core", "+components/infobars/core", "+components/keyed_service/core", - # TODO(mpearson): for experiment; remove after crbug.com/488901 is launched. - "+components/omnibox/browser/omnibox_field_trial.h", "+components/policy", "+components/pref_registry", "+components/prefs", @@ -13,6 +11,7 @@ "+components/sync", "+components/sync_preferences/testing_pref_service_syncable.h", "+components/url_formatter", + "+components/variations", "+components/webdata", "+google_apis", "+libxml",
diff --git a/components/search_engines/keyword_table.cc b/components/search_engines/keyword_table.cc index 8a67ac85..a5d9922 100644 --- a/components/search_engines/keyword_table.cc +++ b/components/search_engines/keyword_table.cc
@@ -238,8 +238,7 @@ if (!transaction.Begin()) return false; - for (Operations::const_iterator i(operations.begin()); i != operations.end(); - ++i) { + for (auto i(operations.begin()); i != operations.end(); ++i) { switch (i->first) { case ADD: if (!AddKeyword(i->second)) @@ -275,8 +274,7 @@ } } bool succeeded = s.Succeeded(); - for (std::set<TemplateURLID>::const_iterator i(bad_entries.begin()); - i != bad_entries.end(); ++i) + for (auto i(bad_entries.begin()); i != bad_entries.end(); ++i) succeeded &= RemoveKeyword(*i); return succeeded; }
diff --git a/components/search_engines/search_host_to_urls_map.cc b/components/search_engines/search_host_to_urls_map.cc index fd28f185..5c6e99b 100644 --- a/components/search_engines/search_host_to_urls_map.cc +++ b/components/search_engines/search_host_to_urls_map.cc
@@ -66,7 +66,7 @@ base::StringPiece host) { DCHECK(initialized_); - HostToURLsMap::iterator urls_for_host = host_to_urls_map_.find(host); + auto urls_for_host = host_to_urls_map_.find(host); if (urls_for_host == host_to_urls_map_.end() || urls_for_host->second.empty()) return nullptr; return &urls_for_host->second;
diff --git a/components/search_engines/search_host_to_urls_map_unittest.cc b/components/search_engines/search_host_to_urls_map_unittest.cc index 301a89b..61168749 100644 --- a/components/search_engines/search_host_to_urls_map_unittest.cc +++ b/components/search_engines/search_host_to_urls_map_unittest.cc
@@ -64,7 +64,7 @@ ASSERT_TRUE(urls != nullptr); int url_count = 0; - for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) { + for (auto i(urls->begin()); i != urls->end(); ++i) { url_count++; ASSERT_EQ(template_urls_[1].get(), *i); }
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc index dde995cc..d0dfdbf 100644 --- a/components/search_engines/template_url.cc +++ b/components/search_engines/template_url.cc
@@ -952,8 +952,7 @@ // replacements_ is ordered in ascending order, as such we need to iterate // from the back. - for (Replacements::reverse_iterator i = replacements_.rbegin(); - i != replacements_.rend(); ++i) { + for (auto i = replacements_.rbegin(); i != replacements_.rend(); ++i) { switch (i->type) { case ENCODING: HandleReplacement(std::string(), input_encoding, *i, &url);
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc index d365237..2f84d32 100644 --- a/components/search_engines/template_url_service.cc +++ b/components/search_engines/template_url_service.cc
@@ -15,7 +15,6 @@ #include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" -#include "components/omnibox/browser/omnibox_field_trial.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/rappor/rappor_service_impl.h" @@ -30,6 +29,7 @@ #include "components/sync/protocol/search_engine_specifics.pb.h" #include "components/sync/protocol/sync.pb.h" #include "components/url_formatter/url_fixer.h" +#include "components/variations/variations_associated_data.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/gurl.h" @@ -116,8 +116,7 @@ void LogDuplicatesHistogram( const TemplateURLService::TemplateURLVector& template_urls) { std::map<base::string16, int> duplicates; - for (TemplateURLService::TemplateURLVector::const_iterator it = - template_urls.begin(); it != template_urls.end(); ++it) { + for (auto it = template_urls.begin(); it != template_urls.end(); ++it) { base::string16 keyword = (*it)->keyword(); base::TrimString(keyword, base::ASCIIToUTF16("_"), &keyword); duplicates[keyword]++; @@ -151,12 +150,31 @@ net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)); } +// For keywords that look like hostnames, returns whether KeywordProvider +// should require users to type a prefix of the hostname to match against +// them, rather than just the domain name portion. In other words, returns +// whether the prefix before the domain name should be considered important +// for matching purposes. Returns true if the experiment isn't active. +bool OmniboxFieldTrialKeywordRequiresRegistry() { + // This would normally be + // bool OmniboxFieldTrial::KeywordRequiresRegistry() + // but that would create a dependency cycle since omnibox depends on + // search_engines (and search -> search_engines) + constexpr char kBundledExperimentFieldTrialName[] = + "OmniboxBundledExperimentV1"; + constexpr char kKeywordRequiresRegistryRule[] = "KeywordRequiresRegistry"; + const std::string value = variations::GetVariationParamValue( + kBundledExperimentFieldTrialName, kKeywordRequiresRegistryRule); + return value.empty() || (value == "true"); +} + // Returns the length of the important part of the |keyword|, assumed to be // associated with the TemplateURL. For instance, for the keyword // google.co.uk, this can return 6 (the length of "google"). size_t GetMeaningfulKeywordLength(const base::string16& keyword, const TemplateURL* turl) { - if (OmniboxFieldTrial::KeywordRequiresRegistry()) + // Using Omnibox from here is a layer violation and should be fixed. + if (OmniboxFieldTrialKeywordRequiresRegistry()) return keyword.length(); const size_t registry_length = GetRegistryLength(keyword); if (registry_length == std::string::npos) @@ -369,8 +387,7 @@ const TemplateURL* TemplateURLService::GetTemplateURLForKeyword( const base::string16& keyword) const { - KeywordToTURLAndMeaningfulLength::const_iterator elem( - keyword_to_turl_and_length_.find(keyword)); + auto elem(keyword_to_turl_and_length_.find(keyword)); if (elem != keyword_to_turl_and_length_.end()) return elem->second.first; return (!loaded_ && initial_default_search_provider_ && @@ -388,7 +405,7 @@ const TemplateURL* TemplateURLService::GetTemplateURLForGUID( const std::string& sync_guid) const { - GUIDToTURL::const_iterator elem(guid_to_turl_.find(sync_guid)); + auto elem(guid_to_turl_.find(sync_guid)); if (elem != guid_to_turl_.end()) return elem->second; return (!loaded_ && initial_default_search_provider_ && @@ -686,13 +703,13 @@ &prepopulated_urls, template_urls_, default_search_provider_)); // Remove items. - for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); + for (auto i = actions.removed_engines.begin(); i < actions.removed_engines.end(); ++i) Remove(*i); // Edit items. - for (EditedEngines::iterator i(actions.edited_engines.begin()); - i < actions.edited_engines.end(); ++i) { + for (auto i(actions.edited_engines.begin()); i < actions.edited_engines.end(); + ++i) { TemplateURL new_values(i->second); Update(i->first, new_values); } @@ -911,8 +928,7 @@ syncer::SyncChangeList new_changes; syncer::SyncError error; - for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); - iter != change_list.end(); ++iter) { + for (auto iter = change_list.begin(); iter != change_list.end(); ++iter) { DCHECK_EQ(syncer::SEARCH_ENGINES, iter->sync_data().GetDataType()); std::string guid = @@ -1333,9 +1349,7 @@ SyncDataMap TemplateURLService::CreateGUIDToSyncDataMap( const syncer::SyncDataList& sync_data) { SyncDataMap data_map; - for (syncer::SyncDataList::const_iterator i(sync_data.begin()); - i != sync_data.end(); - ++i) + for (auto i(sync_data.begin()); i != sync_data.end(); ++i) data_map[i->GetSpecifics().search_engine().sync_guid()] = *i; return data_map; } @@ -1706,8 +1720,7 @@ return; TemplateURL* visited_url = nullptr; - for (TemplateURLSet::const_iterator i = urls_for_host->begin(); - i != urls_for_host->end(); ++i) { + for (auto i = urls_for_host->begin(); i != urls_for_host->end(); ++i) { base::string16 search_terms; if ((*i)->ExtractSearchTermsFromURL(details.url, search_terms_data(), &search_terms) &&
diff --git a/components/search_engines/template_url_unittest.cc b/components/search_engines/template_url_unittest.cc index a17768a3..fd7c635 100644 --- a/components/search_engines/template_url_unittest.cc +++ b/components/search_engines/template_url_unittest.cc
@@ -221,9 +221,8 @@ const TemplateURLRef::PostParams& post_params = url.image_url_ref().post_params_; EXPECT_EQ(7U, post_params.size()); - for (TemplateURLRef::PostParams::const_iterator i = post_params.begin(); - i != post_params.end(); ++i) { - TemplateURLRef::Replacements::const_iterator j = replacements.begin(); + for (auto i = post_params.begin(); i != post_params.end(); ++i) { + auto j = replacements.begin(); for (; j != replacements.end(); ++j) { if (j->is_post_param && j->index == static_cast<size_t>(i - post_params.begin())) {
diff --git a/components/search_engines/util.cc b/components/search_engines/util.cc index 99e4b04..324409b 100644 --- a/components/search_engines/util.cc +++ b/components/search_engines/util.cc
@@ -137,8 +137,7 @@ TemplateURL* GetTemplateURLByID( const TemplateURLService::TemplateURLVector& template_urls, int64_t id) { - for (TemplateURLService::TemplateURLVector::const_iterator i( - template_urls.begin()); i != template_urls.end(); ++i) { + for (auto i(template_urls.begin()); i != template_urls.end(); ++i) { if ((*i)->id() == id) { return *i; } @@ -149,8 +148,7 @@ TemplateURL* FindURLByPrepopulateID( const TemplateURLService::TemplateURLVector& template_urls, int prepopulate_id) { - for (std::vector<TemplateURL*>::const_iterator i = template_urls.begin(); - i < template_urls.end(); ++i) { + for (auto i = template_urls.begin(); i < template_urls.end(); ++i) { if ((*i)->prepopulate_id() == prepopulate_id) return *i; }
diff --git a/components/security_interstitials/core/base_safe_browsing_error_ui.h b/components/security_interstitials/core/base_safe_browsing_error_ui.h index 8cf0575..73581241 100644 --- a/components/security_interstitials/core/base_safe_browsing_error_ui.h +++ b/components/security_interstitials/core/base_safe_browsing_error_ui.h
@@ -64,6 +64,7 @@ // setting. This does NOT indicate whether the user is opted-in to extended // reporting, just the level of reporting that's available to the user. Use // |is_extended_reporting_enabled| to see if the user is opted-in. + // TODO(lpz/scout): Remove this field, scout is the only setting now. bool is_scout_reporting_enabled; // Whether the SBER pref is being managed by enterprise policy, meaning the
diff --git a/components/sessions/core/persistent_tab_restore_service.cc b/components/sessions/core/persistent_tab_restore_service.cc index 7c14b49..07950eb 100644 --- a/components/sessions/core/persistent_tab_restore_service.cc +++ b/components/sessions/core/persistent_tab_restore_service.cc
@@ -499,7 +499,7 @@ // Write the to_write_count most recently added entries out. The most // recently added entry is at the front, so we use a reverse iterator to // write in the order the entries were added. - Entries::const_reverse_iterator i = entries.rbegin(); + auto i = entries.rbegin(); DCHECK(static_cast<size_t>(to_write_count) <= entries.size()); std::advance(i, entries.size() - static_cast<int>(to_write_count)); for (; i != entries.rend(); ++i) { @@ -526,7 +526,7 @@ void PersistentTabRestoreService::Delegate::OnClearEntries() { // Mark all the tabs as closed so that we don't attempt to restore them. const Entries& entries = tab_restore_service_helper_->entries(); - for (Entries::const_iterator i = entries.begin(); i != entries.end(); ++i) + for (auto i = entries.begin(); i != entries.end(); ++i) base_session_service_->ScheduleCommand( CreateRestoredEntryCommand((*i)->id)); @@ -557,9 +557,9 @@ Entries::const_iterator entry_iterator) { size_t index = 0; const Entries& entries = tab_restore_service_helper_->entries(); - for (Entries::const_iterator j = entries.begin(); - j != entry_iterator && j != entries.end(); - ++j, ++index) {} + for (auto j = entries.begin(); j != entry_iterator && j != entries.end(); + ++j, ++index) { + } if (static_cast<int>(index) < entries_to_write_) entries_to_write_--;
diff --git a/components/sessions/core/tab_restore_service_helper.cc b/components/sessions/core/tab_restore_service_helper.cc index 3a142b4d..c934202 100644 --- a/components/sessions/core/tab_restore_service_helper.cc +++ b/components/sessions/core/tab_restore_service_helper.cc
@@ -259,7 +259,7 @@ LiveTabContext* context, SessionID id, WindowOpenDisposition disposition) { - Entries::iterator entry_iterator = GetEntryIteratorById(id); + auto entry_iterator = GetEntryIteratorById(id); if (entry_iterator == entries_.end()) { // Don't hoark here, we allow an invalid id. return std::vector<LiveTab*>(); @@ -423,7 +423,7 @@ TabRestoreService::Entries::iterator TabRestoreServiceHelper::GetEntryIteratorById(SessionID id) { - for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) { + for (auto i = entries_.begin(); i != entries_.end(); ++i) { if ((*i)->id == id) return i;
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc index 012abd6..dee77ac 100644 --- a/components/signin/core/browser/about_signin_internals.cc +++ b/components/signin/core/browser/about_signin_internals.cc
@@ -459,9 +459,7 @@ token_info->SetString("service", consumer_id); std::string scopes_str; - for (OAuth2TokenService::ScopeSet::const_iterator it = scopes.begin(); - it != scopes.end(); - ++it) { + for (auto it = scopes.begin(); it != scopes.end(); ++it) { scopes_str += *it + "<br/>"; } token_info->SetString("scopes", scopes_str);
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc index 6d1b77e2..becde9e9 100644 --- a/components/signin/core/browser/account_reconcilor.cc +++ b/components/signin/core/browser/account_reconcilor.cc
@@ -125,12 +125,15 @@ AccountReconcilor::ScopedSyncedDataDeletion::ScopedSyncedDataDeletion( AccountReconcilor* reconcilor) - : reconcilor_(reconcilor) { + : reconcilor_(reconcilor->weak_factory_.GetWeakPtr()) { DCHECK(reconcilor_); ++reconcilor_->synced_data_deletion_in_progress_count_; } AccountReconcilor::ScopedSyncedDataDeletion::~ScopedSyncedDataDeletion() { + if (!reconcilor_) + return; // The reconcilor was destroyed. + DCHECK_GT(reconcilor_->synced_data_deletion_in_progress_count_, 0); --reconcilor_->synced_data_deletion_in_progress_count_; } @@ -156,7 +159,8 @@ chrome_accounts_changed_(false), account_reconcilor_lock_count_(0), reconcile_on_unblock_(false), - timer_(new base::OneShotTimer) { + timer_(new base::OneShotTimer), + weak_factory_(this) { VLOG(1) << "AccountReconcilor::AccountReconcilor"; DCHECK(delegate_); delegate_->set_reconcilor(this); @@ -718,9 +722,7 @@ // Remove the account from the list that is being merged. bool AccountReconcilor::MarkAccountAsAddedToCookie( const std::string& account_id) { - for (std::vector<std::string>::iterator i = add_to_cookie_.begin(); - i != add_to_cookie_.end(); - ++i) { + for (auto i = add_to_cookie_.begin(); i != add_to_cookie_.end(); ++i) { if (account_id == *i) { add_to_cookie_.erase(i); return true;
diff --git a/components/signin/core/browser/account_reconcilor.h b/components/signin/core/browser/account_reconcilor.h index 6e8cd30..dad2ab6 100644 --- a/components/signin/core/browser/account_reconcilor.h +++ b/components/signin/core/browser/account_reconcilor.h
@@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/threading/thread_checker.h" #include "base/time/time.h" @@ -66,7 +67,7 @@ private: friend class AccountReconcilor; explicit ScopedSyncedDataDeletion(AccountReconcilor* reconcilor); - AccountReconcilor* reconcilor_; + base::WeakPtr<AccountReconcilor> reconcilor_; DISALLOW_COPY_AND_ASSIGN(ScopedSyncedDataDeletion); }; @@ -357,6 +358,8 @@ // not invalidate the primary token while this is happening. int synced_data_deletion_in_progress_count_ = 0; + base::WeakPtrFactory<AccountReconcilor> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(AccountReconcilor); };
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc index d88aed1..a8311c3 100644 --- a/components/signin/core/browser/account_reconcilor_unittest.cc +++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -271,6 +271,8 @@ PrefService* pref_service() { return &pref_service_; } + void DeleteReconcilor() { mock_reconcilor_.reset(); } + private: base::MessageLoop loop; signin::AccountConsistencyMethod account_consistency_; @@ -869,8 +871,8 @@ std::string cookie(1, GetParam().gaia_api_calls[i]); EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(cookie)).Times(1); // MergeSession fixes an existing cookie or appends it at the end. - std::vector<Cookie>::iterator it = std::find( - cookies.begin(), cookies.end(), Cookie{cookie, false /* is_valid */}); + auto it = std::find(cookies.begin(), cookies.end(), + Cookie{cookie, false /* is_valid */}); if (it == cookies.end()) cookies.push_back({cookie, true}); else @@ -2453,3 +2455,11 @@ EXPECT_EQ(1, spy_delegate->num_reconcile_finished_calls_); EXPECT_FALSE(reconcilor->is_reconcile_started_); } + +TEST_F(AccountReconcilorTest, ScopedSyncedDataDeletionDestructionOrder) { + AccountReconcilor* reconcilor = GetMockReconcilor(); + std::unique_ptr<AccountReconcilor::ScopedSyncedDataDeletion> data_deletion = + reconcilor->GetScopedSyncDataDeletion(); + DeleteReconcilor(); + // data_deletion is destroyed after the reconcilor, this should not crash. +}
diff --git a/components/signin/core/browser/child_account_info_fetcher_impl.cc b/components/signin/core/browser/child_account_info_fetcher_impl.cc index 0a034e5..0a1696c 100644 --- a/components/signin/core/browser/child_account_info_fetcher_impl.cc +++ b/components/signin/core/browser/child_account_info_fetcher_impl.cc
@@ -123,7 +123,7 @@ void ChildAccountInfoFetcherImpl::OnGetUserInfoSuccess( const UserInfoMap& data) { - UserInfoMap::const_iterator services_iter = data.find("allServices"); + auto services_iter = data.find("allServices"); if (services_iter != data.end()) { std::vector<std::string> service_flags = base::SplitString( services_iter->second, ",", base::TRIM_WHITESPACE,
diff --git a/components/signin/core/browser/fake_profile_oauth2_token_service.cc b/components/signin/core/browser/fake_profile_oauth2_token_service.cc index 3696b80..b53c3ad 100644 --- a/components/signin/core/browser/fake_profile_oauth2_token_service.cc +++ b/components/signin/core/browser/fake_profile_oauth2_token_service.cc
@@ -127,8 +127,7 @@ GetPendingRequests(); // Walk the requests and notify the callbacks. - for (std::vector<PendingRequest>::iterator it = requests.begin(); - it != requests.end(); ++it) { + for (auto it = requests.begin(); it != requests.end(); ++it) { DCHECK(it->request); bool scope_matches = all_scopes || it->scopes == scope; @@ -145,8 +144,8 @@ std::vector<FakeProfileOAuth2TokenService::PendingRequest> FakeProfileOAuth2TokenService::GetPendingRequests() { std::vector<PendingRequest> valid_requests; - for (std::vector<PendingRequest>::iterator it = pending_requests_.begin(); - it != pending_requests_.end(); ++it) { + for (auto it = pending_requests_.begin(); it != pending_requests_.end(); + ++it) { if (it->request) valid_requests.push_back(*it); }
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc index c2d2b53..19662652 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service.cc +++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -292,7 +292,7 @@ return; } - LoaderToToken::iterator it = loaders_.find(source); + auto it = loaders_.find(source); if (it == loaders_.end()) return;
diff --git a/components/signin/core/browser/signin_error_controller.cc b/components/signin/core/browser/signin_error_controller.cc index 3120377..305228d 100644 --- a/components/signin/core/browser/signin_error_controller.cc +++ b/components/signin/core/browser/signin_error_controller.cc
@@ -37,7 +37,7 @@ } void SigninErrorController::RemoveProvider(const AuthStatusProvider* provider) { - AuthStatusProviderSet::iterator iter = provider_set_.find(provider); + auto iter = provider_set_.find(provider); DCHECK(iter != provider_set_.end()) << "Removing provider that was never added"; provider_set_.erase(iter); @@ -53,8 +53,7 @@ // actionable error state and some provider exposes a similar error and // account id, use that error. Otherwise, just take the first actionable // error we find. - for (AuthStatusProviderSet::const_iterator it = provider_set_.begin(); - it != provider_set_.end(); ++it) { + for (auto it = provider_set_.begin(); it != provider_set_.end(); ++it) { std::string account_id = (*it)->GetAccountId(); // In PRIMARY_ACCOUNT mode, ignore all secondary accounts.
diff --git a/components/storage_monitor/media_storage_util.cc b/components/storage_monitor/media_storage_util.cc index 229141d..466bf19 100644 --- a/components/storage_monitor/media_storage_util.cc +++ b/components/storage_monitor/media_storage_util.cc
@@ -47,9 +47,7 @@ base::AssertBlockingAllowed(); MediaStorageUtil::DeviceIdSet missing_devices; - for (MediaStorageUtil::DeviceIdSet::const_iterator it = devices->begin(); - it != devices->end(); - ++it) { + for (auto it = devices->begin(); it != devices->end(); ++it) { StorageInfo::Type type; std::string unique_id; if (!StorageInfo::CrackDeviceId(*it, &type, &unique_id)) { @@ -67,10 +65,7 @@ missing_devices.insert(*it); } - for (MediaStorageUtil::DeviceIdSet::const_iterator it = - missing_devices.begin(); - it != missing_devices.end(); - ++it) { + for (auto it = missing_devices.begin(); it != missing_devices.end(); ++it) { devices->erase(*it); } }
diff --git a/components/storage_monitor/storage_monitor.cc b/components/storage_monitor/storage_monitor.cc index 6f3871ce..5b58360 100644 --- a/components/storage_monitor/storage_monitor.cc +++ b/components/storage_monitor/storage_monitor.cc
@@ -83,9 +83,7 @@ std::vector<StorageInfo> results; base::AutoLock lock(storage_lock_); - for (StorageMap::const_iterator it = storage_map_.begin(); - it != storage_map_.end(); - ++it) { + for (auto it = storage_map_.begin(); it != storage_map_.end(); ++it) { results.push_back(it->second); } return results; @@ -159,8 +157,7 @@ void StorageMonitor::MarkInitialized() { initialized_ = true; - for (std::vector<base::Closure>::iterator iter = - on_initialize_callbacks_.begin(); + for (auto iter = on_initialize_callbacks_.begin(); iter != on_initialize_callbacks_.end(); ++iter) { iter->Run(); } @@ -189,7 +186,7 @@ StorageInfo info; { base::AutoLock lock(storage_lock_); - StorageMap::iterator it = storage_map_.find(id); + auto it = storage_map_.find(id); if (it == storage_map_.end()) return; info = it->second;
diff --git a/components/storage_monitor/storage_monitor_linux.cc b/components/storage_monitor/storage_monitor_linux.cc index 1f07f9a..93f55f16 100644 --- a/components/storage_monitor/storage_monitor_linux.cc +++ b/components/storage_monitor/storage_monitor_linux.cc
@@ -280,7 +280,7 @@ current != current.DirName()) current = current.DirName(); - MountMap::const_iterator mount_info = mount_info_map_.find(current); + auto mount_info = mount_info_map_.find(current); if (mount_info == mount_info_map_.end()) return false; *device_info = mount_info->second.storage_info; @@ -308,7 +308,7 @@ // Find the mount point for the given device ID. base::FilePath path; base::FilePath device; - for (MountMap::iterator mount_info = mount_info_map_.begin(); + for (auto mount_info = mount_info_map_.begin(); mount_info != mount_info_map_.end(); ++mount_info) { if (mount_info->second.storage_info.device_id() == device_id) { path = mount_info->first; @@ -345,12 +345,11 @@ old_iter != mount_info_map_.end(); ++old_iter) { const base::FilePath& mount_point = old_iter->first; const base::FilePath& mount_device = old_iter->second.mount_device; - MountPointDeviceMap::const_iterator new_iter = new_mtab.find(mount_point); + auto new_iter = new_mtab.find(mount_point); // |mount_point| not in |new_mtab| or |mount_device| is no longer mounted at // |mount_point|. if (new_iter == new_mtab.end() || (new_iter->second != mount_device)) { - MountPriorityMap::iterator priority = - mount_priority_map_.find(mount_device); + auto priority = mount_priority_map_.find(mount_device); DCHECK(priority != mount_priority_map_.end()); ReferencedMountPoint::const_iterator has_priority = priority->second.find(mount_point); @@ -387,8 +386,7 @@ multiple_mounted_devices_needing_reattachment.begin(); it != multiple_mounted_devices_needing_reattachment.end(); ++it) { - ReferencedMountPoint::iterator first_mount_point_info = - mount_priority_map_.find(*it)->second.begin(); + auto first_mount_point_info = mount_priority_map_.find(*it)->second.begin(); const base::FilePath& mount_point = first_mount_point_info->first; first_mount_point_info->second = true; @@ -402,11 +400,11 @@ scoped_refptr<base::SequencedTaskRunner> mounting_task_runner = base::CreateSequencedTaskRunnerWithTraits( {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); - for (MountPointDeviceMap::const_iterator new_iter = new_mtab.begin(); - new_iter != new_mtab.end(); ++new_iter) { + for (auto new_iter = new_mtab.begin(); new_iter != new_mtab.end(); + ++new_iter) { const base::FilePath& mount_point = new_iter->first; const base::FilePath& mount_device = new_iter->second; - MountMap::iterator old_iter = mount_info_map_.find(mount_point); + auto old_iter = mount_info_map_.find(mount_point); if (old_iter == mount_info_map_.end() || old_iter->second.mount_device != mount_device) { // New mount point found or an existing mount point found with a new @@ -447,7 +445,7 @@ const base::FilePath& mount_point) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - MountPriorityMap::iterator priority = mount_priority_map_.find(mount_device); + auto priority = mount_priority_map_.find(mount_device); DCHECK(priority != mount_priority_map_.end()); const base::FilePath& other_mount_point = priority->second.begin()->first; priority->second[mount_point] = false;
diff --git a/components/storage_monitor/transient_device_ids.cc b/components/storage_monitor/transient_device_ids.cc index fdbcecf..e65b60a 100644 --- a/components/storage_monitor/transient_device_ids.cc +++ b/components/storage_monitor/transient_device_ids.cc
@@ -36,7 +36,7 @@ std::string TransientDeviceIds::DeviceIdFromTransientId( const std::string& transient_id) const { - IdMap::const_iterator it = transient_id_map_.find(transient_id); + auto it = transient_id_map_.find(transient_id); if (it == transient_id_map_.end()) return std::string(); return it->second;
diff --git a/components/suggestions/blacklist_store.cc b/components/suggestions/blacklist_store.cc index a7d08b1a..2d0c284 100644 --- a/components/suggestions/blacklist_store.cc +++ b/components/suggestions/blacklist_store.cc
@@ -33,8 +33,7 @@ void PopulateBlacklistProto(const std::set<std::string>& blacklist_set, SuggestionsBlacklist* blacklist_proto) { blacklist_proto->Clear(); - for (std::set<std::string>::const_iterator it = blacklist_set.begin(); - it != blacklist_set.end(); ++it) { + for (auto it = blacklist_set.begin(); it != blacklist_set.end(); ++it) { blacklist_proto->add_urls(*it); } }
diff --git a/components/suggestions/blacklist_store_unittest.cc b/components/suggestions/blacklist_store_unittest.cc index 850d1b6..c1474e2 100644 --- a/components/suggestions/blacklist_store_unittest.cc +++ b/components/suggestions/blacklist_store_unittest.cc
@@ -27,8 +27,7 @@ SuggestionsProfile CreateSuggestions(std::set<std::string> urls) { SuggestionsProfile suggestions; - for (std::set<std::string>::iterator it = urls.begin(); it != urls.end(); - ++it) { + for (auto it = urls.begin(); it != urls.end(); ++it) { ChromeSuggestion* suggestion = suggestions.add_suggestions(); suggestion->set_url(*it); }
diff --git a/components/suggestions/image_manager.cc b/components/suggestions/image_manager.cc index 2466524..0e55d46c 100644 --- a/components/suggestions/image_manager.cc +++ b/components/suggestions/image_manager.cc
@@ -146,7 +146,7 @@ bool ImageManager::GetImageURL(const GURL& url, GURL* image_url) { DCHECK(image_url); - std::map<GURL, GURL>::iterator it = image_url_map_.find(url); + auto it = image_url_map_.find(url); if (it == image_url_map_.end()) return false; // Not found. *image_url = it->second; @@ -157,7 +157,7 @@ const GURL& image_url, ImageCallback callback) { // To be served when the database has loaded. - ImageCacheRequestMap::iterator it = pending_cache_requests_.find(url); + auto it = pending_cache_requests_.find(url); if (it != pending_cache_requests_.end()) { // Request already queued for this url. it->second.callbacks.push_back(callback); @@ -188,7 +188,7 @@ scoped_refptr<base::RefCountedMemory> ImageManager::GetEncodedImageFromCache( const GURL& url) { - ImageMap::iterator image_iter = image_map_.find(url.spec()); + auto image_iter = image_map_.find(url.spec()); if (image_iter != image_map_.end()) { return image_iter->second; } @@ -280,8 +280,7 @@ void ImageManager::LoadEntriesInCache( std::unique_ptr<ImageDataVector> entries) { - for (ImageDataVector::iterator it = entries->begin(); it != entries->end(); - ++it) { + for (auto it = entries->begin(); it != entries->end(); ++it) { std::vector<unsigned char> encoded_data(it->data().begin(), it->data().end()); @@ -291,10 +290,10 @@ } void ImageManager::ServePendingCacheRequests() { - for (ImageCacheRequestMap::iterator it = pending_cache_requests_.begin(); + for (auto it = pending_cache_requests_.begin(); it != pending_cache_requests_.end(); ++it) { const ImageCacheRequest& request = it->second; - for (CallbackVector::const_iterator callback_it = request.callbacks.begin(); + for (auto callback_it = request.callbacks.begin(); callback_it != request.callbacks.end(); ++callback_it) { ServeFromCacheOrNetwork(request.url, request.image_url, *callback_it); }
diff --git a/components/suggestions/webui/suggestions_source.cc b/components/suggestions/webui/suggestions_source.cc index c2e34512..898682e 100644 --- a/components/suggestions/webui/suggestions_source.cc +++ b/components/suggestions/webui/suggestions_source.cc
@@ -66,8 +66,7 @@ line += net::EscapeForHTML(suggestion.url()); line += "\" target=\"_blank\">"; line += net::EscapeForHTML(suggestion.title()); - std::map<GURL, std::string>::const_iterator it = - base64_encoded_pngs.find(GURL(suggestion.url())); + auto it = base64_encoded_pngs.find(GURL(suggestion.url())); if (it != base64_encoded_pngs.end()) { line += "<br><img src='"; line += it->second;
diff --git a/components/sync/protocol/app_list_specifics.proto b/components/sync/protocol/app_list_specifics.proto index 48659c22..2c273c3 100644 --- a/components/sync/protocol/app_list_specifics.proto +++ b/components/sync/protocol/app_list_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for the app list (aka app launcher). -// Update proto_{value,enum}_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/app_notification_specifics.proto b/components/sync/protocol/app_notification_specifics.proto index 288e769c..753e6ac 100644 --- a/components/sync/protocol/app_notification_specifics.proto +++ b/components/sync/protocol/app_notification_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for app notifications. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/app_setting_specifics.proto b/components/sync/protocol/app_setting_specifics.proto index 8eb2fda..60504115 100644 --- a/components/sync/protocol/app_setting_specifics.proto +++ b/components/sync/protocol/app_setting_specifics.proto
@@ -6,8 +6,8 @@ // This is the same as for an extension setting, but uses a separate datatype // in order to control syncability separately. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/app_specifics.proto b/components/sync/protocol/app_specifics.proto index 0b19d21c..7ab0385 100644 --- a/components/sync/protocol/app_specifics.proto +++ b/components/sync/protocol/app_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for apps. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/arc_package_specifics.proto b/components/sync/protocol/arc_package_specifics.proto index b5d5dab4..a5d9609 100644 --- a/components/sync/protocol/arc_package_specifics.proto +++ b/components/sync/protocol/arc_package_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for ARC pakcages. -// Update proto_{value,enum}_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/article_specifics.proto b/components/sync/protocol/article_specifics.proto index 9d381be..7afef35 100644 --- a/components/sync/protocol/article_specifics.proto +++ b/components/sync/protocol/article_specifics.proto
@@ -4,6 +4,9 @@ // // Sync protocol datatype extension for the article. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/autofill_specifics.proto b/components/sync/protocol/autofill_specifics.proto index cc6a769..5e88a828 100644 --- a/components/sync/protocol/autofill_specifics.proto +++ b/components/sync/protocol/autofill_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for autofill. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/bookmark_specifics.proto b/components/sync/protocol/bookmark_specifics.proto index 48f6faa6..1a37208 100644 --- a/components/sync/protocol/bookmark_specifics.proto +++ b/components/sync/protocol/bookmark_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for bookmarks. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/client_commands.proto b/components/sync/protocol/client_commands.proto index 0108e214..dd428f5 100644 --- a/components/sync/protocol/client_commands.proto +++ b/components/sync/protocol/client_commands.proto
@@ -4,8 +4,8 @@ // // Sync protocol for communication between sync client and server. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/client_debug_info.proto b/components/sync/protocol/client_debug_info.proto index 0da8a9e8..2954091 100644 --- a/components/sync/protocol/client_debug_info.proto +++ b/components/sync/protocol/client_debug_info.proto
@@ -4,6 +4,9 @@ // // Sync protocol for debug info clients can send to the sync server. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/device_info_specifics.proto b/components/sync/protocol/device_info_specifics.proto index c39cfa9..8f74c7d 100644 --- a/components/sync/protocol/device_info_specifics.proto +++ b/components/sync/protocol/device_info_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for nigori keys. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/dictionary_specifics.proto b/components/sync/protocol/dictionary_specifics.proto index 6f166e761..63a5d98 100644 --- a/components/sync/protocol/dictionary_specifics.proto +++ b/components/sync/protocol/dictionary_specifics.proto
@@ -4,6 +4,9 @@ // // Sync protocol datatype extension for the dictionary. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/encryption.proto b/components/sync/protocol/encryption.proto index 67cb377..3b4040b 100644 --- a/components/sync/protocol/encryption.proto +++ b/components/sync/protocol/encryption.proto
@@ -4,8 +4,8 @@ // // Common sync protocol for encrypted data. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/entity_metadata.proto b/components/sync/protocol/entity_metadata.proto index d96fdbd3..409d30e4 100644 --- a/components/sync/protocol/entity_metadata.proto +++ b/components/sync/protocol/entity_metadata.proto
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/experiments_specifics.proto b/components/sync/protocol/experiments_specifics.proto index d97e696..c71c5eb 100644 --- a/components/sync/protocol/experiments_specifics.proto +++ b/components/sync/protocol/experiments_specifics.proto
@@ -4,6 +4,9 @@ // // Sync protocol datatype extension for experimental feature flags. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/extension_setting_specifics.proto b/components/sync/protocol/extension_setting_specifics.proto index ddb9434..40ffb8c 100644 --- a/components/sync/protocol/extension_setting_specifics.proto +++ b/components/sync/protocol/extension_setting_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for an extension setting. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/extension_specifics.proto b/components/sync/protocol/extension_specifics.proto index e560995..585418d0 100644 --- a/components/sync/protocol/extension_specifics.proto +++ b/components/sync/protocol/extension_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for extensions. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/favicon_image_specifics.proto b/components/sync/protocol/favicon_image_specifics.proto index dc815d2..b47b0ff0 100644 --- a/components/sync/protocol/favicon_image_specifics.proto +++ b/components/sync/protocol/favicon_image_specifics.proto
@@ -4,6 +4,9 @@ // // Sync protocol datatype extension for the favicon image specifics. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/favicon_tracking_specifics.proto b/components/sync/protocol/favicon_tracking_specifics.proto index ed2fad29..809f524 100644 --- a/components/sync/protocol/favicon_tracking_specifics.proto +++ b/components/sync/protocol/favicon_tracking_specifics.proto
@@ -4,6 +4,9 @@ // // Sync protocol datatype extension for the favicon tracking type. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/get_updates_caller_info.proto b/components/sync/protocol/get_updates_caller_info.proto index c737a96..790577f 100644 --- a/components/sync/protocol/get_updates_caller_info.proto +++ b/components/sync/protocol/get_updates_caller_info.proto
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/history_delete_directive_specifics.proto b/components/sync/protocol/history_delete_directive_specifics.proto index f983031..cc907d6 100644 --- a/components/sync/protocol/history_delete_directive_specifics.proto +++ b/components/sync/protocol/history_delete_directive_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for history delete directives. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/managed_user_setting_specifics.proto b/components/sync/protocol/managed_user_setting_specifics.proto index 4a87bf9..bdaeea1 100644 --- a/components/sync/protocol/managed_user_setting_specifics.proto +++ b/components/sync/protocol/managed_user_setting_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for managed user settings. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/managed_user_shared_setting_specifics.proto b/components/sync/protocol/managed_user_shared_setting_specifics.proto index 3c53807..24c0931 100644 --- a/components/sync/protocol/managed_user_shared_setting_specifics.proto +++ b/components/sync/protocol/managed_user_shared_setting_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for managed user shared settings. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/managed_user_specifics.proto b/components/sync/protocol/managed_user_specifics.proto index 49949d8..a0e6538 100644 --- a/components/sync/protocol/managed_user_specifics.proto +++ b/components/sync/protocol/managed_user_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for managed user settings. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/managed_user_whitelist_specifics.proto b/components/sync/protocol/managed_user_whitelist_specifics.proto index 890a5ce..ec1affd8 100644 --- a/components/sync/protocol/managed_user_whitelist_specifics.proto +++ b/components/sync/protocol/managed_user_whitelist_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for supervised user whitelists. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/model_type_state.proto b/components/sync/protocol/model_type_state.proto index fb24429..47e3de0 100644 --- a/components/sync/protocol/model_type_state.proto +++ b/components/sync/protocol/model_type_state.proto
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/mountain_share_specifics.proto b/components/sync/protocol/mountain_share_specifics.proto index c0c330c..0266817 100644 --- a/components/sync/protocol/mountain_share_specifics.proto +++ b/components/sync/protocol/mountain_share_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for shares of Mountain project. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/nigori_specifics.proto b/components/sync/protocol/nigori_specifics.proto index d1f6222..b20895c 100644 --- a/components/sync/protocol/nigori_specifics.proto +++ b/components/sync/protocol/nigori_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for nigori keys. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/password_specifics.proto b/components/sync/protocol/password_specifics.proto index 8f17fbc..b98fa1e 100644 --- a/components/sync/protocol/password_specifics.proto +++ b/components/sync/protocol/password_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for password data. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/preference_specifics.proto b/components/sync/protocol/preference_specifics.proto index 6ec641e..ebaf0a2 100644 --- a/components/sync/protocol/preference_specifics.proto +++ b/components/sync/protocol/preference_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for preferences. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/printer_specifics.proto b/components/sync/protocol/printer_specifics.proto index b9ada32..b4fb9b5 100644 --- a/components/sync/protocol/printer_specifics.proto +++ b/components/sync/protocol/printer_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for printer data. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/priority_preference_specifics.proto b/components/sync/protocol/priority_preference_specifics.proto index 8de60702..574ae4c 100644 --- a/components/sync/protocol/priority_preference_specifics.proto +++ b/components/sync/protocol/priority_preference_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for priority preferences. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/reading_list_specifics.proto b/components/sync/protocol/reading_list_specifics.proto index c47f8dab..93684d2 100644 --- a/components/sync/protocol/reading_list_specifics.proto +++ b/components/sync/protocol/reading_list_specifics.proto
@@ -4,6 +4,9 @@ // // Sync protocol datatype extension for the reading list items. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + syntax = "proto2"; option optimize_for = LITE_RUNTIME;
diff --git a/components/sync/protocol/search_engine_specifics.proto b/components/sync/protocol/search_engine_specifics.proto index 7637995..82fcc155 100644 --- a/components/sync/protocol/search_engine_specifics.proto +++ b/components/sync/protocol/search_engine_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for custom search engines. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. // Fields that are not used anymore should be marked [deprecated = true].
diff --git a/components/sync/protocol/session_specifics.proto b/components/sync/protocol/session_specifics.proto index ced390a..fdae362 100644 --- a/components/sync/protocol/session_specifics.proto +++ b/components/sync/protocol/session_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for sessions. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/sync.proto b/components/sync/protocol/sync.proto index b9ef5b8..c2eb185f 100644 --- a/components/sync/protocol/sync.proto +++ b/components/sync/protocol/sync.proto
@@ -4,8 +4,9 @@ // // Sync protocol for communication between sync client and server. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. If you add new Specifics proto, +// also update proto_value_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/sync_enums.proto b/components/sync/protocol/sync_enums.proto index dba03328..80e5cb1a 100644 --- a/components/sync/protocol/sync_enums.proto +++ b/components/sync/protocol/sync_enums.proto
@@ -4,8 +4,8 @@ // // Sync protocol for communication between sync client and server. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any enums in this file, update +// proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/theme_specifics.proto b/components/sync/protocol/theme_specifics.proto index f3d34346..241f5f81 100644 --- a/components/sync/protocol/theme_specifics.proto +++ b/components/sync/protocol/theme_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for themes. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/typed_url_specifics.proto b/components/sync/protocol/typed_url_specifics.proto index 3af8d16..f2a5cee 100644 --- a/components/sync/protocol/typed_url_specifics.proto +++ b/components/sync/protocol/typed_url_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for typed urls. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/unique_position.proto b/components/sync/protocol/unique_position.proto index 067794b..c5352c7 100644 --- a/components/sync/protocol/unique_position.proto +++ b/components/sync/protocol/unique_position.proto
@@ -4,8 +4,8 @@ // // Protobuf representation of the UniquePosition class. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/user_event_specifics.proto b/components/sync/protocol/user_event_specifics.proto index dc889c6b..c931f88 100644 --- a/components/sync/protocol/user_event_specifics.proto +++ b/components/sync/protocol/user_event_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for user events. -// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync/protocol/wifi_credential_specifics.proto b/components/sync/protocol/wifi_credential_specifics.proto index c5ddfe91..67fef9f 100644 --- a/components/sync/protocol/wifi_credential_specifics.proto +++ b/components/sync/protocol/wifi_credential_specifics.proto
@@ -4,8 +4,8 @@ // // Sync protocol datatype extension for WiFi credentials. -// Update proto_{value,enum}_conversions{.h,.cc,_unittest.cc} if you change -// any fields in this file. +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. syntax = "proto2";
diff --git a/components/sync_bookmarks/bookmark_change_processor.cc b/components/sync_bookmarks/bookmark_change_processor.cc index e9306bd..32cbf98 100644 --- a/components/sync_bookmarks/bookmark_change_processor.cc +++ b/components/sync_bookmarks/bookmark_change_processor.cc
@@ -730,8 +730,7 @@ // When we added or updated bookmarks in the previous loop, we placed them to // the far right position. Now we iterate over all these modified items in // sync order, left to right, moving them into their proper positions. - for (std::multimap<int, const BookmarkNode*>::iterator it = - to_reposition.begin(); it != to_reposition.end(); ++it) { + for (auto it = to_reposition.begin(); it != to_reposition.end(); ++it) { const BookmarkNode* parent = it->second->parent(); model->Move(it->second, parent, it->first); } @@ -892,8 +891,7 @@ size_t index = 0; for (; index < size; index++) { const sync_pb::MetaInfo& meta_info = specifics.meta_info(index); - BookmarkNode::MetaInfoMap::const_iterator it = - meta_info_map->find(meta_info.key()); + auto it = meta_info_map->find(meta_info.key()); if (it == meta_info_map->end() || it->second != meta_info.value()) { // One of original meta info entries is missing in |meta_info_map| or // different. @@ -910,8 +908,7 @@ // Clear and reset meta info in bookmark specifics. specifics.clear_meta_info(); if (meta_info_map) { - for (BookmarkNode::MetaInfoMap::const_iterator it = meta_info_map->begin(); - it != meta_info_map->end(); ++it) { + for (auto it = meta_info_map->begin(); it != meta_info_map->end(); ++it) { sync_pb::MetaInfo* meta_info = specifics.add_meta_info(); meta_info->set_key(it->first); meta_info->set_value(it->second);
diff --git a/components/sync_bookmarks/bookmark_model_associator.cc b/components/sync_bookmarks/bookmark_model_associator.cc index 69cff2e..7508dd7 100644 --- a/components/sync_bookmarks/bookmark_model_associator.cc +++ b/components/sync_bookmarks/bookmark_model_associator.cc
@@ -149,10 +149,8 @@ std::string adjusted_title; ConvertTitleToSyncInternalFormat(title, &adjusted_title); BookmarkNodeRange range = child_nodes_.equal_range(adjusted_title); - BookmarkNodeMap::iterator match_iter = range.second; - for (BookmarkNodeMap::iterator iter = range.first; - iter != range.second; - ++iter) { + auto match_iter = range.second; + for (auto iter = range.first; iter != range.second; ++iter) { // Then within the range match the node by the folder bit // and the url. const BookmarkNode* node = iter->second; @@ -375,7 +373,7 @@ void BookmarkModelAssociator::Disassociate(int64_t sync_id) { DCHECK(thread_checker_.CalledOnValidThread()); - SyncIdToBookmarkNodeMap::iterator iter = id_map_inverse_.find(sync_id); + auto iter = id_map_inverse_.find(sync_id); if (iter == id_map_inverse_.end()) return; id_map_.erase(iter->second->id()); @@ -660,8 +658,7 @@ BookmarkNodeFinder node_finder(parent_node); int index = 0; - for (std::vector<int64_t>::const_iterator it = sync_ids.begin(); - it != sync_ids.end(); ++it) { + for (auto it = sync_ids.begin(); it != sync_ids.end(); ++it) { int64_t sync_child_id = *it; syncer::ReadNode sync_child_node(trans); if (sync_child_node.InitByIdLookup(sync_child_id) != @@ -800,7 +797,7 @@ // Check bookmark model from top to bottom. BookmarkStack dfs_stack; - for (BookmarkList::const_iterator it = context->bookmark_roots().begin(); + for (auto it = context->bookmark_roots().begin(); it != context->bookmark_roots().end(); ++it) { dfs_stack.push(*it); } @@ -865,8 +862,7 @@ std::set<int64_t> journals_to_purge; // Remove empty folders from bottom to top. - for (FolderInfoList::reverse_iterator it = folders_matched.rbegin(); - it != folders_matched.rend(); ++it) { + for (auto it = folders_matched.rbegin(); it != folders_matched.rend(); ++it) { if (it->folder->child_count() == 0) { bookmark_model_->Remove(it->folder); context->IncrementLocalItemsDeleted();
diff --git a/components/sync_preferences/pref_model_associator.cc b/components/sync_preferences/pref_model_associator.cc index d7b18ba9..b06e1ca 100644 --- a/components/sync_preferences/pref_model_associator.cc +++ b/components/sync_preferences/pref_model_associator.cc
@@ -188,8 +188,7 @@ // Go through and check for all preferences we care about that sync already // knows about. - for (syncer::SyncDataList::const_iterator sync_iter = - initial_sync_data.begin(); + for (auto sync_iter = initial_sync_data.begin(); sync_iter != initial_sync_data.end(); ++sync_iter) { DCHECK_EQ(type_, sync_iter->GetDataType()); @@ -200,8 +199,7 @@ } // Go through and build sync data for any remaining preferences. - for (std::set<std::string>::iterator pref_name_iter = - remaining_preferences.begin(); + for (auto pref_name_iter = remaining_preferences.begin(); pref_name_iter != remaining_preferences.end(); ++pref_name_iter) { InitPrefAndAssociate(syncer::SyncData(), *pref_name_iter, &new_changes); } @@ -333,7 +331,7 @@ syncer::ModelType type) const { DCHECK_EQ(type_, type); syncer::SyncDataList current_data; - for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); + for (auto iter = synced_preferences_.begin(); iter != synced_preferences_.end(); ++iter) { std::string name = *iter; if (pref_accessor_->GetPreferenceState(type_, name).registration_state !=
diff --git a/components/sync_preferences/pref_service_syncable_unittest.cc b/components/sync_preferences/pref_service_syncable_unittest.cc index b9de7bc..a8f25533 100644 --- a/components/sync_preferences/pref_service_syncable_unittest.cc +++ b/components/sync_preferences/pref_service_syncable_unittest.cc
@@ -164,7 +164,7 @@ std::unique_ptr<base::Value> FindValue(const std::string& name, const syncer::SyncChangeList& list) { - syncer::SyncChangeList::const_iterator it = list.begin(); + auto it = list.begin(); for (; it != list.end(); ++it) { if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) { return base::JSONReader::Read( @@ -408,7 +408,7 @@ std::unique_ptr<base::Value> FindValue(const std::string& name, const syncer::SyncChangeList& list) { - syncer::SyncChangeList::const_iterator it = list.begin(); + auto it = list.begin(); for (; it != list.end(); ++it) { if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) { return base::JSONReader::Read(
diff --git a/components/sync_preferences/synced_pref_change_registrar.cc b/components/sync_preferences/synced_pref_change_registrar.cc index 5e2682ea..a900600 100644 --- a/components/sync_preferences/synced_pref_change_registrar.cc +++ b/components/sync_preferences/synced_pref_change_registrar.cc
@@ -46,8 +46,7 @@ } void SyncedPrefChangeRegistrar::RemoveAll() { - for (ObserverMap::iterator iter = observers_.begin(); - iter != observers_.end(); ++iter) { + for (auto iter = observers_.begin(); iter != observers_.end(); ++iter) { pref_service_->RemoveSyncedPrefObserver(iter->first, this); } observers_.clear();
diff --git a/components/sync_sessions/favicon_cache.cc b/components/sync_sessions/favicon_cache.cc index 446b061..9a75025a 100644 --- a/components/sync_sessions/favicon_cache.cc +++ b/components/sync_sessions/favicon_cache.cc
@@ -255,8 +255,8 @@ } syncer::SyncChangeList local_changes; - for (syncer::SyncDataList::const_iterator iter = initial_sync_data.begin(); - iter != initial_sync_data.end(); ++iter) { + for (auto iter = initial_sync_data.begin(); iter != initial_sync_data.end(); + ++iter) { GURL remote_url = GetFaviconURLFromSpecifics(iter->GetSpecifics()); GURL favicon_url = GetLocalFaviconFromSyncedData(*iter); if (favicon_url.is_valid()) { @@ -276,7 +276,7 @@ // they'll be re-added and the appropriate synced favicons will be evicted. // TODO(zea): implement a smarter ordering of the which favicons to drop. int available_favicons = max_sync_favicon_limit_ - initial_sync_data.size(); - for (std::set<GURL>::const_iterator iter = unsynced_favicon_urls.begin(); + for (auto iter = unsynced_favicon_urls.begin(); iter != unsynced_favicon_urls.end(); ++iter) { if (available_favicons > 0) { local_changes.push_back( @@ -285,7 +285,7 @@ CreateSyncDataFromLocalFavicon(type, *iter))); available_favicons--; } else { - FaviconMap::iterator favicon_iter = synced_favicons_.find(*iter); + auto favicon_iter = synced_favicons_.find(*iter); DVLOG(1) << "Dropping local favicon " << favicon_iter->second->favicon_url.spec(); DropPartialFavicon(favicon_iter, type); @@ -314,8 +314,8 @@ syncer::SyncDataList FaviconCache::GetAllSyncData(syncer::ModelType type) const { syncer::SyncDataList data_list; - for (FaviconMap::const_iterator iter = synced_favicons_.begin(); - iter != synced_favicons_.end(); ++iter) { + for (auto iter = synced_favicons_.begin(); iter != synced_favicons_.end(); + ++iter) { if ((type == syncer::FAVICON_IMAGES && FaviconInfoHasImages(*iter->second)) || (type == syncer::FAVICON_TRACKING && @@ -340,8 +340,7 @@ syncer::SyncChangeList new_changes; syncer::SyncError error; syncer::ModelType type = syncer::UNSPECIFIED; - for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); - iter != change_list.end(); ++iter) { + for (auto iter = change_list.begin(); iter != change_list.end(); ++iter) { type = iter->sync_data().GetDataType(); DCHECK(type == syncer::FAVICON_IMAGES || type == syncer::FAVICON_TRACKING); GURL favicon_url = @@ -350,7 +349,7 @@ error.Reset(FROM_HERE, "Received invalid favicon url.", type); break; } - FaviconMap::iterator favicon_iter = synced_favicons_.find(favicon_url); + auto favicon_iter = synced_favicons_.find(favicon_url); if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { if (favicon_iter == synced_favicons_.end()) { // Two clients might wind up deleting different parts of the same @@ -474,7 +473,7 @@ scoped_refptr<base::RefCountedMemory>* favicon_png) const { if (!favicon_url.is_valid()) return false; - FaviconMap::const_iterator iter = synced_favicons_.find(favicon_url); + auto iter = synced_favicons_.find(favicon_url); UMA_HISTOGRAM_BOOLEAN("Sync.FaviconCacheLookupSucceeded", iter != synced_favicons_.end()); @@ -494,7 +493,7 @@ scoped_refptr<base::RefCountedMemory>* favicon_png) const { if (!page_url.is_valid()) return false; - PageFaviconMap::const_iterator iter = page_favicon_map_.find(page_url); + auto iter = page_favicon_map_.find(page_url); if (iter == page_favicon_map_.end()) return false; @@ -531,7 +530,7 @@ base::Time FaviconCache::GetLastVisitTimeForTest( const GURL& favicon_url) const { - FaviconMap::const_iterator iter = synced_favicons_.find(favicon_url); + auto iter = synced_favicons_.find(favicon_url); DCHECK(iter != synced_favicons_.end()); return iter->second->last_visit_time; } @@ -551,7 +550,7 @@ const GURL& page_url, base::Time mtime, const std::vector<favicon_base::FaviconRawBitmapResult>& bitmap_results) { - PageTaskMap::iterator page_iter = page_task_map_.find(page_url); + auto page_iter = page_task_map_.find(page_url); if (page_iter == page_task_map_.end()) return; page_task_map_.erase(page_iter); @@ -698,8 +697,8 @@ recent_favicons_.insert(iter->second); if (VLOG_IS_ON(2)) { - for (RecencySet::const_iterator iter = recent_favicons_.begin(); - iter != recent_favicons_.end(); ++iter) { + for (auto iter = recent_favicons_.begin(); iter != recent_favicons_.end(); + ++iter) { DVLOG(2) << "Favicon " << iter->get()->favicon_url.spec() << ": " << syncer::GetTimeDebugString(iter->get()->last_visit_time); } @@ -865,7 +864,7 @@ const GURL& favicon_url) const { DCHECK(type == syncer::FAVICON_IMAGES || type == syncer::FAVICON_TRACKING); DCHECK(favicon_url.is_valid()); - FaviconMap::const_iterator iter = synced_favicons_.find(favicon_url); + auto iter = synced_favicons_.find(favicon_url); DCHECK(iter != synced_favicons_.end()); SyncedFaviconInfo* favicon_info = iter->second.get(); @@ -888,9 +887,8 @@ void FaviconCache::DeleteSyncedFavicons(const std::set<GURL>& favicon_urls) { syncer::SyncChangeList image_deletions, tracking_deletions; - for (std::set<GURL>::const_iterator iter = favicon_urls.begin(); - iter != favicon_urls.end(); ++iter) { - FaviconMap::iterator favicon_iter = synced_favicons_.find(*iter); + for (auto iter = favicon_urls.begin(); iter != favicon_urls.end(); ++iter) { + auto favicon_iter = synced_favicons_.find(*iter); if (favicon_iter == synced_favicons_.end()) continue; DeleteSyncedFavicon(favicon_iter,
diff --git a/components/sync_sessions/favicon_cache_unittest.cc b/components/sync_sessions/favicon_cache_unittest.cc index 247888d58..9357e63 100644 --- a/components/sync_sessions/favicon_cache_unittest.cc +++ b/components/sync_sessions/favicon_cache_unittest.cc
@@ -99,8 +99,7 @@ change_list.begin(), change_list.end()); change_map_.erase(change_map_.begin(), change_map_.end()); - for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); - iter != change_list.end(); ++iter) { + for (auto iter = change_list.begin(); iter != change_list.end(); ++iter) { change_map_[iter->sync_data().GetTitle()] = *iter; } return syncer::SyncError();
diff --git a/components/sync_sessions/session_store.cc b/components/sync_sessions/session_store.cc index 2e8dfc2..ea9ce26 100644 --- a/components/sync_sessions/session_store.cc +++ b/components/sync_sessions/session_store.cc
@@ -398,8 +398,7 @@ // Metadata should be available if data is available. If not, it means // the local store is corrupt, because we delete all data and metadata // at the same time (e.g. sync is disabled). - syncer::EntityMetadataMap::const_iterator metadata_it = - initial_metadata.find(storage_key); + auto metadata_it = initial_metadata.find(storage_key); if (metadata_it == initial_metadata.end()) { continue; }
diff --git a/components/sync_sessions/sessions_sync_manager.cc b/components/sync_sessions/sessions_sync_manager.cc index 19e726d..ec83a8fe 100644 --- a/components/sync_sessions/sessions_sync_manager.cc +++ b/components/sync_sessions/sessions_sync_manager.cc
@@ -73,8 +73,7 @@ void AppendDeletionsForTabNodes(const std::set<int>& tab_node_ids, const std::string& machine_tag, syncer::SyncChangeList* change_output) { - for (std::set<int>::const_iterator it = tab_node_ids.begin(); - it != tab_node_ids.end(); ++it) { + for (auto it = tab_node_ids.begin(); it != tab_node_ids.end(); ++it) { change_output->push_back(syncer::SyncChange( FROM_HERE, SyncChange::ACTION_DELETE, SyncData::CreateLocalDelete(TabNodeIdToTag(machine_tag, *it), @@ -330,8 +329,7 @@ return error; } - for (syncer::SyncChangeList::const_iterator it = change_list.begin(); - it != change_list.end(); ++it) { + for (auto it = change_list.begin(); it != change_list.end(); ++it) { DCHECK(it->IsValid()); DCHECK(it->sync_data().GetSpecifics().has_session()); const sync_pb::SessionSpecifics& session = @@ -412,8 +410,7 @@ syncer::SyncChangeList* new_changes) { bool found_current_header = false; int bad_foreign_hash_count = 0; - for (syncer::SyncDataList::const_iterator it = sync_data.begin(); - it != sync_data.end(); ++it) { + for (auto it = sync_data.begin(); it != sync_data.end(); ++it) { const syncer::SyncData& data = *it; DCHECK(data.GetSpecifics().has_session()); syncer::SyncDataRemote remote(data);
diff --git a/components/sync_sessions/sessions_sync_manager_unittest.cc b/components/sync_sessions/sessions_sync_manager_unittest.cc index 2b473e5..50ea15e 100644 --- a/components/sync_sessions/sessions_sync_manager_unittest.cc +++ b/components/sync_sessions/sessions_sync_manager_unittest.cc
@@ -267,7 +267,7 @@ } SyncChangeList* FilterOutLocalHeaderChanges(SyncChangeList* list) { - SyncChangeList::iterator it = list->begin(); + auto it = list->begin(); bool found = false; while (it != list->end()) { if (it->sync_data().IsLocal() && @@ -701,8 +701,7 @@ meta1_reference[0].pop_back(); sync_pb::SessionWindow* win = meta1.mutable_header()->mutable_window(0); win->clear_tab(); - for (std::vector<SessionID>::const_iterator iter = kTabIds1.begin(); - iter + 1 != kTabIds1.end(); ++iter) { + for (auto iter = kTabIds1.begin(); iter + 1 != kTabIds1.end(); ++iter) { win->add_tab(iter->id()); } SyncChangeList removal; @@ -740,8 +739,7 @@ // Update associator with the session's meta node, window, and tabs. UpdateTrackerWithSpecifics(meta, base::Time(), &manager()->session_tracker_); - for (std::vector<sync_pb::SessionSpecifics>::iterator iter = tabs.begin(); - iter != tabs.end(); ++iter) { + for (auto iter = tabs.begin(); iter != tabs.end(); ++iter) { UpdateTrackerWithSpecifics(*iter, base::Time(), &manager()->session_tracker_); }
diff --git a/components/sync_sessions/synced_session_tracker.cc b/components/sync_sessions/synced_session_tracker.cc index 0655362f..1529dd0 100644 --- a/components/sync_sessions/synced_session_tracker.cc +++ b/components/sync_sessions/synced_session_tracker.cc
@@ -279,15 +279,13 @@ const SyncedSessionTracker::TrackedSession* SyncedSessionTracker::LookupTrackedSession( const std::string& session_tag) const { - std::map<std::string, TrackedSession>::const_iterator it = - session_map_.find(session_tag); + auto it = session_map_.find(session_tag); return it == session_map_.end() ? nullptr : &it->second; } SyncedSessionTracker::TrackedSession* SyncedSessionTracker::LookupTrackedSession(const std::string& session_tag) { - std::map<std::string, TrackedSession>::iterator it = - session_map_.find(session_tag); + auto it = session_map_.find(session_tag); return it == session_map_.end() ? nullptr : &it->second; }
diff --git a/components/sync_sessions/tab_node_pool.cc b/components/sync_sessions/tab_node_pool.cc index a11146c0..0b7b8cc 100644 --- a/components/sync_sessions/tab_node_pool.cc +++ b/components/sync_sessions/tab_node_pool.cc
@@ -18,6 +18,9 @@ const size_t TabNodePool::kFreeNodesLowWatermark = 25; const size_t TabNodePool::kFreeNodesHighWatermark = 100; +const base::Feature kTabNodePoolImmediateDeletion{ + "TabNodePoolImmediateDeletion", base::FEATURE_DISABLED_BY_DEFAULT}; + TabNodePool::TabNodePool() : max_used_tab_node_id_(kInvalidTabNodeID) {} // static @@ -41,7 +44,7 @@ // This is a new node association, the sync node should be free. // Remove node from free node pool and then associate it with the tab. - std::set<int>::iterator it = free_nodes_pool_.find(tab_node_id); + auto it = free_nodes_pool_.find(tab_node_id); DCHECK(it != free_nodes_pool_.end()); free_nodes_pool_.erase(it); @@ -53,7 +56,7 @@ } int TabNodePool::GetTabNodeIdFromTabId(SessionID tab_id) const { - TabIDToTabNodeIDMap::const_iterator it = tabid_nodeid_map_.find(tab_id); + auto it = tabid_nodeid_map_.find(tab_id); if (it != tabid_nodeid_map_.end()) { return it->second; } @@ -62,7 +65,7 @@ void TabNodePool::FreeTab(SessionID tab_id) { DCHECK(tab_id.is_valid()); - TabIDToTabNodeIDMap::iterator it = tabid_nodeid_map_.find(tab_id); + auto it = tabid_nodeid_map_.find(tab_id); if (it == tabid_nodeid_map_.end()) { return; // Already freed. } @@ -89,10 +92,12 @@ // were never associated before (but are within 0..max_used_tab_node_id_). if (!free_nodes_pool_.empty()) { tab_node_id = *free_nodes_pool_.begin(); + DCHECK_LE(tab_node_id, max_used_tab_node_id_); } if (!missing_nodes_pool_.empty() && *missing_nodes_pool_.begin() < tab_node_id) { tab_node_id = *missing_nodes_pool_.begin(); + DCHECK_LE(tab_node_id, max_used_tab_node_id_); AddTabNode(tab_node_id); } } @@ -134,7 +139,7 @@ } SessionID TabNodePool::GetTabIdFromTabNodeId(int tab_node_id) const { - TabNodeIDToTabIDMap::const_iterator it = nodeid_tabid_map_.find(tab_node_id); + auto it = nodeid_tabid_map_.find(tab_node_id); if (it != nodeid_tabid_map_.end()) { return it->second; } @@ -142,6 +147,27 @@ } void TabNodePool::CleanupTabNodes(std::set<int>* deleted_node_ids) { + if (base::FeatureList::IsEnabled(kTabNodePoolImmediateDeletion)) { + // Convert all free nodes into missing nodes, each representing a deletion. + deleted_node_ids->insert(free_nodes_pool_.begin(), free_nodes_pool_.end()); + missing_nodes_pool_.insert(free_nodes_pool_.begin(), + free_nodes_pool_.end()); + free_nodes_pool_.clear(); + + // As an optimization to save memory, update |max_used_tab_node_id_| and + // shrink |missing_nodes_pool_| appropriately. + if (nodeid_tabid_map_.empty()) { + max_used_tab_node_id_ = kInvalidTabNodeID; + } else { + max_used_tab_node_id_ = nodeid_tabid_map_.rbegin()->first; + } + + missing_nodes_pool_.erase( + missing_nodes_pool_.upper_bound(max_used_tab_node_id_), + missing_nodes_pool_.end()); + return; + } + // If number of free nodes exceed kFreeNodesHighWatermark, // delete sync nodes till number reaches kFreeNodesLowWatermark. // Note: This logic is to mitigate temporary disassociation issues with old @@ -160,7 +186,7 @@ } void TabNodePool::DeleteTabNode(int tab_node_id) { - TabNodeIDToTabIDMap::iterator it = nodeid_tabid_map_.find(tab_node_id); + auto it = nodeid_tabid_map_.find(tab_node_id); if (it == nodeid_tabid_map_.end()) { free_nodes_pool_.erase(tab_node_id); return; @@ -182,4 +208,8 @@ return tab_node_ids; } +int TabNodePool::GetMaxUsedTabNodeIdForTest() const { + return max_used_tab_node_id_; +} + } // namespace sync_sessions
diff --git a/components/sync_sessions/tab_node_pool.h b/components/sync_sessions/tab_node_pool.h index ce79b63..2728e19 100644 --- a/components/sync_sessions/tab_node_pool.h +++ b/components/sync_sessions/tab_node_pool.h
@@ -11,6 +11,7 @@ #include <set> #include <string> +#include "base/feature_list.h" #include "base/macros.h" #include "components/sessions/core/session_id.h" @@ -28,6 +29,8 @@ // 1. Associated : Sync node is used and associated with a tab. // 2. Free : Sync node is unused. +extern const base::Feature kTabNodePoolImmediateDeletion; + class TabNodePool { public: TabNodePool(); @@ -76,8 +79,9 @@ // Returns tab node IDs for all known (used or free) tab nodes. std::set<int> GetAllTabNodeIds() const; + int GetMaxUsedTabNodeIdForTest() const; + private: - friend class SyncTabNodePoolTest; using TabNodeIDToTabIDMap = std::map<int, SessionID>; using TabIDToTabNodeIDMap = std::map<SessionID, int>;
diff --git a/components/sync_sessions/tab_node_pool_unittest.cc b/components/sync_sessions/tab_node_pool_unittest.cc index dba46c3..8b37113b 100644 --- a/components/sync_sessions/tab_node_pool_unittest.cc +++ b/components/sync_sessions/tab_node_pool_unittest.cc
@@ -6,26 +6,11 @@ #include <vector> +#include "base/test/scoped_feature_list.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace sync_sessions { - -class SyncTabNodePoolTest : public testing::Test { - protected: - SyncTabNodePoolTest() {} - - int GetMaxUsedTabNodeId() const { return pool_.max_used_tab_node_id_; } - - void AddFreeTabNodes(const std::vector<int>& node_ids) { - for (int node_id : node_ids) { - pool_.free_nodes_pool_.insert(node_id); - } - } - - TabNodePool pool_; -}; - namespace { using testing::UnorderedElementsAre; @@ -38,6 +23,24 @@ const SessionID kTabId3 = SessionID::FromSerializedValue(1030); const SessionID kTabId4 = SessionID::FromSerializedValue(1040); const SessionID kTabId5 = SessionID::FromSerializedValue(1050); +const SessionID kTabId6 = SessionID::FromSerializedValue(1060); + +class SyncTabNodePoolTest : public testing::Test { + protected: + SyncTabNodePoolTest() {} + + int GetMaxUsedTabNodeId() const { return pool_.GetMaxUsedTabNodeIdForTest(); } + + void AddFreeTabNodes(const std::vector<int>& node_ids) { + const SessionID kTmpTabId = SessionID::FromSerializedValue(123); + for (int node_id : node_ids) { + pool_.ReassociateTabNode(node_id, kTmpTabId); + pool_.FreeTab(kTmpTabId); + } + } + + TabNodePool pool_; +}; TEST_F(SyncTabNodePoolTest, TabNodeIdIncreases) { std::set<int> deleted_node_ids; @@ -123,18 +126,6 @@ EXPECT_EQ(2, pool_.AssociateWithFreeTabNode(kTabId5)); } -TEST_F(SyncTabNodePoolTest, AddGet) { - AddFreeTabNodes({5, 10}); - - ASSERT_EQ(TabNodePool::kInvalidTabNodeID, - pool_.GetTabNodeIdFromTabId(kTabId1)); - EXPECT_EQ(5, pool_.AssociateWithFreeTabNode(kTabId1)); - ASSERT_EQ(TabNodePool::kInvalidTabNodeID, - pool_.GetTabNodeIdFromTabId(kTabId2)); - // 5 is now used, should return 10. - EXPECT_EQ(10, pool_.AssociateWithFreeTabNode(kTabId2)); -} - TEST_F(SyncTabNodePoolTest, AssociateWithFreeTabNode) { ASSERT_EQ(TabNodePool::kInvalidTabNodeID, pool_.GetTabNodeIdFromTabId(kTabId1)); @@ -208,6 +199,80 @@ EXPECT_EQ(2, pool_.AssociateWithFreeTabNode(kTabId5)); } +TEST_F(SyncTabNodePoolTest, AggressiveCleanupTabNodesMiddle) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(kTabNodePoolImmediateDeletion); + + pool_.ReassociateTabNode(/*tab_node_id=*/0, kTabId1); + pool_.ReassociateTabNode(/*tab_node_id=*/1, kTabId2); + pool_.ReassociateTabNode(/*tab_node_id=*/2, kTabId3); + + pool_.FreeTab(kTabId2); + + std::set<int> deleted_node_ids; + pool_.CleanupTabNodes(&deleted_node_ids); + + EXPECT_THAT(deleted_node_ids, UnorderedElementsAre(1)); + EXPECT_EQ(2, GetMaxUsedTabNodeId()); + EXPECT_EQ(1, pool_.AssociateWithFreeTabNode(kTabId4)); + EXPECT_EQ(3, pool_.AssociateWithFreeTabNode(kTabId5)); +} + +TEST_F(SyncTabNodePoolTest, AggressiveCleanupTabNodesMax) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(kTabNodePoolImmediateDeletion); + + pool_.ReassociateTabNode(/*tab_node_id=*/0, kTabId1); + pool_.ReassociateTabNode(/*tab_node_id=*/1, kTabId2); + pool_.ReassociateTabNode(/*tab_node_id=*/2, kTabId3); + + pool_.FreeTab(kTabId3); + + std::set<int> deleted_node_ids; + pool_.CleanupTabNodes(&deleted_node_ids); + + EXPECT_THAT(deleted_node_ids, UnorderedElementsAre(2)); + EXPECT_EQ(1, GetMaxUsedTabNodeId()); + EXPECT_EQ(2, pool_.AssociateWithFreeTabNode(kTabId4)); + EXPECT_EQ(3, pool_.AssociateWithFreeTabNode(kTabId5)); +} + +TEST_F(SyncTabNodePoolTest, AggressiveCleanupTabNodesMultiple) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(kTabNodePoolImmediateDeletion); + + pool_.ReassociateTabNode(/*tab_node_id=*/0, kTabId1); + pool_.ReassociateTabNode(/*tab_node_id=*/1, kTabId2); + pool_.ReassociateTabNode(/*tab_node_id=*/2, kTabId3); + + pool_.FreeTab(kTabId1); + pool_.FreeTab(kTabId2); + + std::set<int> deleted_node_ids; + pool_.CleanupTabNodes(&deleted_node_ids); + + EXPECT_THAT(deleted_node_ids, UnorderedElementsAre(0, 1)); + EXPECT_EQ(2, GetMaxUsedTabNodeId()); + EXPECT_EQ(0, pool_.AssociateWithFreeTabNode(kTabId4)); + EXPECT_EQ(1, pool_.AssociateWithFreeTabNode(kTabId5)); + EXPECT_EQ(3, pool_.AssociateWithFreeTabNode(kTabId6)); +} + +TEST_F(SyncTabNodePoolTest, AggressiveCleanupTabNodesAll) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(kTabNodePoolImmediateDeletion); + + pool_.ReassociateTabNode(/*tab_node_id=*/0, kTabId1); + + pool_.FreeTab(kTabId1); + + std::set<int> deleted_node_ids; + pool_.CleanupTabNodes(&deleted_node_ids); + EXPECT_THAT(deleted_node_ids, UnorderedElementsAre(0)); + EXPECT_EQ(-1, GetMaxUsedTabNodeId()); + EXPECT_EQ(0, pool_.AssociateWithFreeTabNode(kTabId4)); +} + } // namespace } // namespace sync_sessions
diff --git a/components/translate/core/browser/translate_language_list.cc b/components/translate/core/browser/translate_language_list.cc index 1fdd0c4..e6016ab 100644 --- a/components/translate/core/browser/translate_language_list.cc +++ b/components/translate/core/browser/translate_language_list.cc
@@ -173,7 +173,7 @@ bool translate_allowed, std::vector<std::string>* languages) { DCHECK(languages && languages->empty()); - std::set<std::string>::const_iterator iter = supported_languages_.begin(); + auto iter = supported_languages_.begin(); for (; iter != supported_languages_.end(); ++iter) languages->push_back(*iter);
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc index f76a5d9..c3c82ca 100644 --- a/components/translate/core/browser/translate_prefs.cc +++ b/components/translate/core/browser/translate_prefs.cc
@@ -395,9 +395,9 @@ b = std::min(length, b); if (r > a && r < b) { // All cases can be achieved with a single rotation. - std::vector<std::string>::iterator first = languages.begin() + a; - std::vector<std::string>::iterator it = languages.begin() + r; - std::vector<std::string>::iterator last = languages.begin() + b; + auto first = languages.begin() + a; + auto it = languages.begin() + r; + auto last = languages.begin() + b; std::rotate(first, it, last); UpdateLanguageList(languages);
diff --git a/components/translate/core/browser/translate_script.cc b/components/translate/core/browser/translate_script.cc index 1225ba6c..3e77a36e 100644 --- a/components/translate/core/browser/translate_script.cc +++ b/components/translate/core/browser/translate_script.cc
@@ -189,9 +189,7 @@ expiration_delay_); } - for (RequestCallbackList::iterator it = callback_list_.begin(); - it != callback_list_.end(); - ++it) { + for (auto it = callback_list_.begin(); it != callback_list_.end(); ++it) { it->Run(success, data); } callback_list_.clear();
diff --git a/components/ui_devtools/devtools_server.cc b/components/ui_devtools/devtools_server.cc index f7808b0..ba5d9f3 100644 --- a/components/ui_devtools/devtools_server.cc +++ b/components/ui_devtools/devtools_server.cc
@@ -187,7 +187,7 @@ void UiDevToolsServer::OnWebSocketMessage(int connection_id, const std::string& data) { DCHECK_CALLED_ON_VALID_SEQUENCE(devtools_server_sequence_); - ConnectionsMap::iterator it = connections_.find(connection_id); + auto it = connections_.find(connection_id); DCHECK(it != connections_.end()); UiDevToolsClient* client = it->second; client->Dispatch(data); @@ -195,7 +195,7 @@ void UiDevToolsServer::OnClose(int connection_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(devtools_server_sequence_); - ConnectionsMap::iterator it = connections_.find(connection_id); + auto it = connections_.find(connection_id); if (it == connections_.end()) return; UiDevToolsClient* client = it->second;
diff --git a/components/unified_consent/unified_consent_metrics.h b/components/unified_consent/unified_consent_metrics.h index 7ff8735..777b7c7 100644 --- a/components/unified_consent/unified_consent_metrics.h +++ b/components/unified_consent/unified_consent_metrics.h
@@ -51,8 +51,10 @@ // The user was eligible for seeing the consent bump, but turned an // on-by-default privacy setting off. kUserTurnedPrivacySettingOff, + // The user has a custom passphrase tied to their sync account. + kCustomPassphrase, - kMaxValue = kUserTurnedPrivacySettingOff + kMaxValue = kCustomPassphrase }; // Google services that can be toggled in user settings.
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc index 97fbe7d..0d60b09 100644 --- a/components/unified_consent/unified_consent_service.cc +++ b/components/unified_consent/unified_consent_service.cc
@@ -228,6 +228,7 @@ case metrics::ConsentBumpSuppressReason::kUserSignedOut: case metrics::ConsentBumpSuppressReason::kUserTurnedSyncDatatypeOff: case metrics::ConsentBumpSuppressReason::kUserTurnedPrivacySettingOff: + case metrics::ConsentBumpSuppressReason::kCustomPassphrase: pref_service_->SetBoolean(prefs::kShouldShowUnifiedConsentBump, false); break; case metrics::ConsentBumpSuppressReason::kSyncPaused: @@ -294,25 +295,24 @@ if (GetMigrationState() == MigrationState::kInProgressWaitForSyncInit) UpdateSettingsForMigration(); - if (sync_service_->IsUsingSecondaryPassphrase() && IsUnifiedConsentGiven()) { - // Force off unified consent given when the user sets a custom passphrase. - SetUnifiedConsentGiven(false); - RecordUnifiedConsentRevoked( - metrics::UnifiedConsentRevokeReason::kCustomPassphrase); + if (sync_service_->IsUsingSecondaryPassphrase()) { + if (ShouldShowConsentBump()) { + // Do not show the consent bump when the user has a custom passphrase. + RecordConsentBumpSuppressReason( + metrics::ConsentBumpSuppressReason::kCustomPassphrase); + } + if (IsUnifiedConsentGiven()) { + // Force off unified consent given when the user sets a custom passphrase. + SetUnifiedConsentGiven(false); + RecordUnifiedConsentRevoked( + metrics::UnifiedConsentRevokeReason::kCustomPassphrase); + } } syncer::SyncPrefs sync_prefs(pref_service_); if (IsUnifiedConsentGiven() != sync_prefs.HasKeepEverythingSynced()) { - // |OnStateChanged| is called after every update in the sync service, - // therefore only allow to update the sync settings when the transport - // state is ACTIVE. - // Note: This is a safety measure. Theoretically this can be done when - // the sync engine is initialized. - if (sync_service_->GetTransportState() == - syncer::SyncService::TransportState::ACTIVE) { - // Make sync-everything consistent with the |kUnifiedConsentGiven| pref. - PostTaskToUpdateSyncSettings(/*sync_everything=*/IsUnifiedConsentGiven()); - } + // Make sync-everything consistent with the |kUnifiedConsentGiven| pref. + PostTaskToUpdateSyncSettings(/*sync_everything=*/IsUnifiedConsentGiven()); } } @@ -444,8 +444,7 @@ } void UnifiedConsentService::UpdateSettingsForMigration() { - if (sync_service_->GetTransportState() != - syncer::SyncService::TransportState::ACTIVE) { + if (!sync_service_->IsEngineInitialized()) { SetMigrationState(MigrationState::kInProgressWaitForSyncInit); return; }
diff --git a/components/unified_consent/unified_consent_service_unittest.cc b/components/unified_consent/unified_consent_service_unittest.cc index b5ae38b..aff23de 100644 --- a/components/unified_consent/unified_consent_service_unittest.cc +++ b/components/unified_consent/unified_consent_service_unittest.cc
@@ -384,7 +384,7 @@ EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced()); EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); sync_service_.SetTransportState( - syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION); + syncer::SyncService::TransportState::INITIALIZING); EXPECT_FALSE(sync_service_.IsSyncFeatureActive()); CreateConsentService(true /* client_services_on_by_default */); @@ -781,4 +781,35 @@ metrics::ConsentBumpSuppressReason::kUserTurnedPrivacySettingOff, 1); } +TEST_F(UnifiedConsentServiceTest, ConsentBump_SuppressedWithCustomPassphrase) { + base::HistogramTester histogram_tester; + + // Setup sync account with custom passphrase, such that it would be eligible + // for the consent bump without custom passphrase. + identity_test_environment_.SetPrimaryAccount("testaccount"); + sync_service_.OnUserChoseDatatypes(true, syncer::UserSelectableTypes()); + sync_service_.SetIsUsingPassphrase(true); + syncer::SyncPrefs sync_prefs(&pref_service_); + EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced()); + sync_service_.SetTransportState( + syncer::SyncService::TransportState::INITIALIZING); + EXPECT_FALSE(sync_service_.IsEngineInitialized()); + + // Before sync is initialized, the user is eligible for seeing the consent + // bump. + CreateConsentService(true /* client_services_on_by_default */); + EXPECT_TRUE(AreAllNonPersonalizedServicesEnabled()); + EXPECT_TRUE(consent_service_->ShouldShowConsentBump()); + + // When sync is initialized, it fires the observer in the consent service. + // This will suppress the consent bump. + sync_service_.SetTransportState(syncer::SyncService::TransportState::ACTIVE); + EXPECT_TRUE(sync_service_.IsEngineInitialized()); + sync_service_.FireStateChanged(); + EXPECT_FALSE(consent_service_->ShouldShowConsentBump()); + histogram_tester.ExpectUniqueSample( + "UnifiedConsent.ConsentBump.SuppressReason", + metrics::ConsentBumpSuppressReason::kCustomPassphrase, 1); +} + } // namespace unified_consent
diff --git a/components/url_formatter/url_formatter.cc b/components/url_formatter/url_formatter.cc index 8f5f5e1..2f0bbb6 100644 --- a/components/url_formatter/url_formatter.cc +++ b/components/url_formatter/url_formatter.cc
@@ -152,8 +152,7 @@ // Shift all the adjustments made for this component so the offsets are // valid for the original string and add them to |adjustments|. - for (base::OffsetAdjuster::Adjustments::iterator comp_iter = - component_transform_adjustments.begin(); + for (auto comp_iter = component_transform_adjustments.begin(); comp_iter != component_transform_adjustments.end(); ++comp_iter) comp_iter->original_offset += original_component_begin; if (adjustments) { @@ -215,8 +214,7 @@ prefix_end, adjustments)); // Revise |adjustments| by shifting to the offsets to prefix that the above // call to FormatUrl didn't get to see. - for (base::OffsetAdjuster::Adjustments::iterator it = adjustments->begin(); - it != adjustments->end(); ++it) + for (auto it = adjustments->begin(); it != adjustments->end(); ++it) it->original_offset += kViewSourceLength; // Adjust positions of the parsed components.
diff --git a/components/url_matcher/regex_set_matcher.cc b/components/url_matcher/regex_set_matcher.cc index 3ba2d03e..a15e96b 100644 --- a/components/url_matcher/regex_set_matcher.cc +++ b/components/url_matcher/regex_set_matcher.cc
@@ -79,7 +79,7 @@ if (regexes_.empty()) return; - for (RegexMap::iterator it = regexes_.begin(); it != regexes_.end(); ++it) { + for (auto it = regexes_.begin(); it != regexes_.end(); ++it) { RE2ID re2_id; RE2::ErrorCode error = filtered_re2_->Add( it->second->pattern(), RE2::DefaultOptions, &re2_id);
diff --git a/components/url_matcher/substring_set_matcher.cc b/components/url_matcher/substring_set_matcher.cc index 902c5dd3..713182b 100644 --- a/components/url_matcher/substring_set_matcher.cc +++ b/components/url_matcher/substring_set_matcher.cc
@@ -29,8 +29,8 @@ if (patterns.empty()) return result; - std::vector<const StringPattern*>::const_iterator last = patterns.begin(); - std::vector<const StringPattern*>::const_iterator current = last + 1; + auto last = patterns.begin(); + auto current = last + 1; // For the first pattern, each letter is a label of an edge to a new node. result += (*last)->pattern().size(); @@ -80,15 +80,13 @@ const std::vector<const StringPattern*>& to_register, const std::vector<const StringPattern*>& to_unregister) { // Register patterns. - for (std::vector<const StringPattern*>::const_iterator i = - to_register.begin(); i != to_register.end(); ++i) { + for (auto i = to_register.begin(); i != to_register.end(); ++i) { DCHECK(patterns_.find((*i)->id()) == patterns_.end()); patterns_[(*i)->id()] = *i; } // Unregister patterns - for (std::vector<const StringPattern*>::const_iterator i = - to_unregister.begin(); i != to_unregister.end(); ++i) { + for (auto i = to_unregister.begin(); i != to_unregister.end(); ++i) { patterns_.erase((*i)->id()); } @@ -151,9 +149,7 @@ tree_.push_back(root); // Insert all patterns. - for (SubstringPatternVector::const_iterator i = sorted_patterns.begin(); - i != sorted_patterns.end(); - ++i) { + for (auto i = sorted_patterns.begin(); i != sorted_patterns.end(); ++i) { InsertPatternIntoAhoCorasickTree(*i); } @@ -198,8 +194,7 @@ AhoCorasickNode& root = tree_[0]; root.set_failure(0); const Edges& root_edges = root.edges(); - for (Edges::const_iterator e = root_edges.begin(); e != root_edges.end(); - ++e) { + for (auto e = root_edges.begin(); e != root_edges.end(); ++e) { const uint32_t& leads_to = e->second; tree_[leads_to].set_failure(0); queue.push(leads_to); @@ -208,8 +203,8 @@ while (!queue.empty()) { AhoCorasickNode& current_node = tree_[queue.front()]; queue.pop(); - for (Edges::const_iterator e = current_node.edges().begin(); - e != current_node.edges().end(); ++e) { + for (auto e = current_node.edges().begin(); e != current_node.edges().end(); + ++e) { const char& edge_label = e->first; const uint32_t& leads_to = e->second; queue.push(leads_to); @@ -254,7 +249,7 @@ } uint32_t SubstringSetMatcher::AhoCorasickNode::GetEdge(char c) const { - Edges::const_iterator i = edges_.find(c); + auto i = edges_.find(c); return i == edges_.end() ? kNoSuchEdge : i->second; }
diff --git a/components/url_matcher/url_matcher.cc b/components/url_matcher/url_matcher.cc index 12c6cc57..207739ed 100644 --- a/components/url_matcher/url_matcher.cc +++ b/components/url_matcher/url_matcher.cc
@@ -697,8 +697,7 @@ bool URLMatcherPortFilter::IsMatch(const GURL& url) const { int port = url.EffectiveIntPort(); - for (std::vector<Range>::const_iterator i = ranges_.begin(); - i != ranges_.end(); ++i) { + for (auto i = ranges_.begin(); i != ranges_.end(); ++i) { if (i->first <= port && port <= i->second) return true; } @@ -760,8 +759,7 @@ const std::set<StringPattern::ID>& matching_patterns, const GURL& url, const std::string& url_for_component_searches) const { - for (Conditions::const_iterator i = conditions_.begin(); - i != conditions_.end(); ++i) { + for (auto i = conditions_.begin(); i != conditions_.end(); ++i) { if (!i->IsMatch(matching_patterns, url)) return false; } @@ -774,15 +772,11 @@ // The loop is duplicated below for performance reasons. If not all query // elements are found, no need to verify match that is expected to take more // cycles. - for (QueryConditions::const_iterator i = query_conditions_.begin(); - i != query_conditions_.end(); - ++i) { + for (auto i = query_conditions_.begin(); i != query_conditions_.end(); ++i) { if (!base::ContainsKey(matching_patterns, i->string_pattern()->id())) return false; } - for (QueryConditions::const_iterator i = query_conditions_.begin(); - i != query_conditions_.end(); - ++i) { + for (auto i = query_conditions_.begin(); i != query_conditions_.end(); ++i) { if (!i->IsMatch(url_for_component_searches)) return false; } @@ -799,8 +793,7 @@ void URLMatcher::AddConditionSets( const URLMatcherConditionSet::Vector& condition_sets) { - for (URLMatcherConditionSet::Vector::const_iterator i = - condition_sets.begin(); i != condition_sets.end(); ++i) { + for (auto i = condition_sets.begin(); i != condition_sets.end(); ++i) { DCHECK(url_matcher_condition_sets_.find((*i)->id()) == url_matcher_condition_sets_.end()); url_matcher_condition_sets_[(*i)->id()] = *i; @@ -810,8 +803,7 @@ void URLMatcher::RemoveConditionSets( const std::vector<URLMatcherConditionSet::ID>& condition_set_ids) { - for (std::vector<URLMatcherConditionSet::ID>::const_iterator i = - condition_set_ids.begin(); i != condition_set_ids.end(); ++i) { + for (auto i = condition_set_ids.begin(); i != condition_set_ids.end(); ++i) { DCHECK(url_matcher_condition_sets_.find(*i) != url_matcher_condition_sets_.end()); url_matcher_condition_sets_.erase(*i); @@ -853,22 +845,18 @@ // Calculate all URLMatcherConditionSets for which all URLMatcherConditions // were fulfilled. std::set<URLMatcherConditionSet::ID> result; - for (std::set<StringPattern::ID>::const_iterator i = matches.begin(); - i != matches.end(); ++i) { + for (auto i = matches.begin(); i != matches.end(); ++i) { // For each URLMatcherConditionSet there is exactly one condition // registered in substring_match_triggers_. This means that the following // logic tests each URLMatcherConditionSet exactly once if it can be // completely fulfilled. - StringPatternTriggers::const_iterator triggered_condition_sets_iter = - substring_match_triggers_.find(*i); + auto triggered_condition_sets_iter = substring_match_triggers_.find(*i); if (triggered_condition_sets_iter == substring_match_triggers_.end()) continue; // Not all substring matches are triggers for a condition set. const std::set<URLMatcherConditionSet::ID>& condition_sets = triggered_condition_sets_iter->second; - for (std::set<URLMatcherConditionSet::ID>::const_iterator j = - condition_sets.begin(); j != condition_sets.end(); ++j) { - URLMatcherConditionSets::const_iterator condition_set_iter = - url_matcher_condition_sets_.find(*j); + for (auto j = condition_sets.begin(); j != condition_sets.end(); ++j) { + auto condition_set_iter = url_matcher_condition_sets_.find(*j); DCHECK(condition_set_iter != url_matcher_condition_sets_.end()); if (condition_set_iter->second->IsMatch( matches, url, url_for_component_searches)) @@ -905,9 +893,8 @@ ++condition_set_iter) { const URLMatcherConditionSet::Conditions& conditions = condition_set_iter->second->conditions(); - for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = - conditions.begin(); condition_iter != conditions.end(); - ++condition_iter) { + for (auto condition_iter = conditions.begin(); + condition_iter != conditions.end(); ++condition_iter) { // If we are called to process Full URL searches, ignore others, and // vice versa. (Regex conditions are updated in UpdateRegexSetMatcher.) if (!condition_iter->IsRegexCondition() && @@ -921,8 +908,7 @@ const URLMatcherConditionSet::QueryConditions& query_conditions = condition_set_iter->second->query_conditions(); - for (URLMatcherConditionSet::QueryConditions::const_iterator - query_condition_iter = query_conditions.begin(); + for (auto query_condition_iter = query_conditions.begin(); query_condition_iter != query_conditions.end(); ++query_condition_iter) { new_patterns.insert(query_condition_iter->string_pattern()); @@ -967,9 +953,8 @@ ++condition_set_iter) { const URLMatcherConditionSet::Conditions& conditions = condition_set_iter->second->conditions(); - for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = - conditions.begin(); condition_iter != conditions.end(); - ++condition_iter) { + for (auto condition_iter = conditions.begin(); + condition_iter != conditions.end(); ++condition_iter) { if (condition_iter->IsRegexCondition()) { new_patterns.push_back(condition_iter->string_pattern()); } else if (condition_iter->IsOriginAndPathRegexCondition()) { @@ -996,17 +981,15 @@ ++condition_set_iter) { const URLMatcherConditionSet::Conditions& conditions = condition_set_iter->second->conditions(); - for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = - conditions.begin(); condition_iter != conditions.end(); - ++condition_iter) { + for (auto condition_iter = conditions.begin(); + condition_iter != conditions.end(); ++condition_iter) { const StringPattern* pattern = condition_iter->string_pattern(); substring_pattern_frequencies[pattern->id()]++; } const URLMatcherConditionSet::QueryConditions& query_conditions = condition_set_iter->second->query_conditions(); - for (URLMatcherConditionSet::QueryConditions::const_iterator - query_condition_iter = query_conditions.begin(); + for (auto query_condition_iter = query_conditions.begin(); query_condition_iter != query_conditions.end(); ++query_condition_iter) { const StringPattern* pattern = query_condition_iter->string_pattern(); @@ -1030,8 +1013,7 @@ condition_set_iter->second->conditions(); if (conditions.empty()) continue; - URLMatcherConditionSet::Conditions::const_iterator condition_iter = - conditions.begin(); + auto condition_iter = conditions.begin(); StringPattern::ID trigger = condition_iter->string_pattern()->id(); // We skip the first element in the following loop. ++condition_iter; @@ -1046,8 +1028,7 @@ const URLMatcherConditionSet::QueryConditions& query_conditions = condition_set_iter->second->query_conditions(); - for (URLMatcherConditionSet::QueryConditions::const_iterator - query_condition_iter = query_conditions.begin(); + for (auto query_condition_iter = query_conditions.begin(); query_condition_iter != query_conditions.end(); ++query_condition_iter) { StringPattern::ID current_id = @@ -1070,15 +1051,13 @@ ++condition_set_iter) { const URLMatcherConditionSet::Conditions& conditions = condition_set_iter->second->conditions(); - for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = - conditions.begin(); condition_iter != conditions.end(); - ++condition_iter) { + for (auto condition_iter = conditions.begin(); + condition_iter != conditions.end(); ++condition_iter) { used_patterns.insert(condition_iter->string_pattern()->id()); } const URLMatcherConditionSet::QueryConditions& query_conditions = condition_set_iter->second->query_conditions(); - for (URLMatcherConditionSet::QueryConditions::const_iterator - query_condition_iter = query_conditions.begin(); + for (auto query_condition_iter = query_conditions.begin(); query_condition_iter != query_conditions.end(); ++query_condition_iter) { used_patterns.insert(query_condition_iter->string_pattern()->id());
diff --git a/components/url_matcher/url_matcher_factory.cc b/components/url_matcher/url_matcher_factory.cc index 50c85e71..fe676dd3 100644 --- a/components/url_matcher/url_matcher_factory.cc +++ b/components/url_matcher/url_matcher_factory.cc
@@ -81,7 +81,7 @@ URLMatcherConditionFactory* url_matcher_condition_factory, const std::string& pattern_type, const std::string& pattern_value) const { - FactoryMethods::const_iterator i = factory_methods_.find(pattern_type); + auto i = factory_methods_.find(pattern_type); CHECK(i != factory_methods_.end()); const FactoryMethod& method = i->second; return (url_matcher_condition_factory->*method)(pattern_value);
diff --git a/components/variations/active_field_trials_unittest.cc b/components/variations/active_field_trials_unittest.cc index b934517..b646bc30 100644 --- a/components/variations/active_field_trials_unittest.cc +++ b/components/variations/active_field_trials_unittest.cc
@@ -44,8 +44,7 @@ &active_group_ids); EXPECT_EQ(2U, active_group_ids.size()); for (size_t i = 0; i < active_group_ids.size(); ++i) { - ActiveGroupIdSet::iterator expected_group = - expected_groups.find(active_group_ids[i]); + auto expected_group = expected_groups.find(active_group_ids[i]); EXPECT_FALSE(expected_group == expected_groups.end()); expected_groups.erase(expected_group); }
diff --git a/components/variations/variations_seed_processor_unittest.cc b/components/variations/variations_seed_processor_unittest.cc index f042b84f..fcc5fb1 100644 --- a/components/variations/variations_seed_processor_unittest.cc +++ b/components/variations/variations_seed_processor_unittest.cc
@@ -331,8 +331,7 @@ EXPECT_TRUE(CreateTrialFromStudy(study)); EXPECT_EQ(1u, overrides.size()); - TestOverrideStringCallback::OverrideMap::const_iterator it = - overrides.find(1234); + auto it = overrides.find(1234); EXPECT_EQ(base::ASCIIToUTF16("test"), it->second); } @@ -354,8 +353,7 @@ const TestOverrideStringCallback::OverrideMap& overrides = override_callback_.overrides(); EXPECT_EQ(1u, overrides.size()); - TestOverrideStringCallback::OverrideMap::const_iterator it = - overrides.find(1234); + auto it = overrides.find(1234); EXPECT_EQ(base::ASCIIToUTF16("test"), it->second); }
diff --git a/components/visitedlink/browser/visitedlink_event_listener.cc b/components/visitedlink/browser/visitedlink_event_listener.cc index 75621da..10b3aac 100644 --- a/components/visitedlink/browser/visitedlink_event_listener.cc +++ b/components/visitedlink/browser/visitedlink_event_listener.cc
@@ -141,7 +141,7 @@ return; // Send to all RenderProcessHosts. - for (Updaters::iterator i = updaters_.begin(); i != updaters_.end(); ++i) { + for (auto i = updaters_.begin(); i != updaters_.end(); ++i) { // Make sure to not send to incognito renderers. content::RenderProcessHost* process = content::RenderProcessHost::FromID(i->first); @@ -167,7 +167,7 @@ pending_visited_links_.clear(); coalesce_timer_->Stop(); - for (Updaters::iterator i = updaters_.begin(); i != updaters_.end(); ++i) { + for (auto i = updaters_.begin(); i != updaters_.end(); ++i) { i->second->AddReset(invalidate_hashes); i->second->Update(); } @@ -180,7 +180,7 @@ void VisitedLinkEventListener::CommitVisitedLinks() { // Send to all RenderProcessHosts. - for (Updaters::iterator i = updaters_.begin(); i != updaters_.end(); ++i) { + for (auto i = updaters_.begin(); i != updaters_.end(); ++i) { i->second->AddLinks(pending_visited_links_); i->second->Update(); }
diff --git a/components/visitedlink/browser/visitedlink_master.cc b/components/visitedlink/browser/visitedlink_master.cc index e1f367e..b41cde5 100644 --- a/components/visitedlink/browser/visitedlink_master.cc +++ b/components/visitedlink/browser/visitedlink_master.cc
@@ -480,8 +480,7 @@ bool bulk_write = (fingerprints.size() > kBigDeleteThreshold); // Delete the URLs from the table. - for (std::set<Fingerprint>::const_iterator i = fingerprints.begin(); - i != fingerprints.end(); ++i) + for (auto i = fingerprints.begin(); i != fingerprints.end(); ++i) DeleteFingerprint(*i, !bulk_write); // These deleted fingerprints may make us shrink the table.
diff --git a/components/viz/client/frame_eviction_manager.cc b/components/viz/client/frame_eviction_manager.cc index 1531d8c..e56358b 100644 --- a/components/viz/client/frame_eviction_manager.cc +++ b/components/viz/client/frame_eviction_manager.cc
@@ -39,15 +39,14 @@ } void FrameEvictionManager::RemoveFrame(FrameEvictionManagerClient* frame) { - std::map<FrameEvictionManagerClient*, size_t>::iterator locked_iter = - locked_frames_.find(frame); + auto locked_iter = locked_frames_.find(frame); if (locked_iter != locked_frames_.end()) locked_frames_.erase(locked_iter); unlocked_frames_.remove(frame); } void FrameEvictionManager::LockFrame(FrameEvictionManagerClient* frame) { - std::list<FrameEvictionManagerClient*>::iterator unlocked_iter = + auto unlocked_iter = std::find(unlocked_frames_.begin(), unlocked_frames_.end(), frame); if (unlocked_iter != unlocked_frames_.end()) { DCHECK(locked_frames_.find(frame) == locked_frames_.end());
diff --git a/components/viz/service/display/display_resource_provider.cc b/components/viz/service/display/display_resource_provider.cc index 73e5787..0b3fa95cbd 100644 --- a/components/viz/service/display/display_resource_provider.cc +++ b/components/viz/service/display/display_resource_provider.cc
@@ -289,8 +289,7 @@ CHECK(child_it != children_.end()); Child& child_info = child_it->second; DCHECK(!child_info.marked_for_deletion); - for (std::vector<TransferableResource>::const_iterator it = resources.begin(); - it != resources.end(); ++it) { + for (auto it = resources.begin(); it != resources.end(); ++it) { auto resource_in_map_it = child_info.child_to_parent_map.find(it->id); if (resource_in_map_it != child_info.child_to_parent_map.end()) { ChildResource* resource = GetResource(resource_in_map_it->second); @@ -349,7 +348,7 @@ const std::unordered_map<ResourceId, ResourceId>& DisplayResourceProvider::GetChildToParentMap(int child) const { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - ChildMap::const_iterator it = children_.find(child); + auto it = children_.find(child); DCHECK(it != children_.end()); DCHECK(!it->second.marked_for_deletion); return it->second.child_to_parent_map;
diff --git a/components/viz/service/frame_sinks/surface_resource_holder.cc b/components/viz/service/frame_sinks/surface_resource_holder.cc index 6a742f4c..9cb78884 100644 --- a/components/viz/service/frame_sinks/surface_resource_holder.cc +++ b/components/viz/service/frame_sinks/surface_resource_holder.cc
@@ -34,8 +34,7 @@ void SurfaceResourceHolder::RefResources( const std::vector<TransferableResource>& resources) { for (const auto& resource : resources) { - ResourceIdInfoMap::iterator count_it = - resource_id_info_map_.find(resource.id); + auto count_it = resource_id_info_map_.find(resource.id); DCHECK(count_it != resource_id_info_map_.end()); count_it->second.refs_holding_resource_alive++; } @@ -46,8 +45,7 @@ std::vector<ReturnedResource> resources_available_to_return; for (const auto& resource : resources) { - ResourceIdInfoMap::iterator count_it = - resource_id_info_map_.find(resource.id); + auto count_it = resource_id_info_map_.find(resource.id); if (count_it == resource_id_info_map_.end()) continue; ResourceRefs& ref = count_it->second;
diff --git a/components/viz/test/ordered_texture_map.cc b/components/viz/test/ordered_texture_map.cc index 409a85e..eefc91c1 100644 --- a/components/viz/test/ordered_texture_map.cc +++ b/components/viz/test/ordered_texture_map.cc
@@ -33,14 +33,14 @@ } void OrderedTextureMap::Remove(GLuint id) { - TextureMap::iterator map_it = textures_.find(id); + auto map_it = textures_.find(id); // for some test we generate dummy tex id, which are not registered, // nothing to remove in that case. if (map_it == textures_.end()) return; textures_.erase(map_it); - TextureList::iterator list_it = + auto list_it = std::find(ordered_textures_.begin(), ordered_textures_.end(), id); DCHECK(list_it != ordered_textures_.end()); ordered_textures_.erase(list_it);
diff --git a/components/viz/test/test_gles2_interface.cc b/components/viz/test/test_gles2_interface.cc index 36dc930..b6c094dd 100644 --- a/components/viz/test/test_gles2_interface.cc +++ b/components/viz/test/test_gles2_interface.cc
@@ -882,15 +882,14 @@ base::AutoLock lock_for_texture_access(namespace_->lock); scoped_refptr<TestTexture> texture = BoundTexture(target); DCHECK(texture->IsValidParameter(pname)); - TestTexture::TextureParametersMap::iterator it = texture->params.find(pname); + auto it = texture->params.find(pname); if (it != texture->params.end()) *value = it->second; } void TestGLES2Interface::TextureTargets::UnbindTexture(GLuint id) { // Bind zero to any targets that the id is bound to. - for (TargetTextureMap::iterator it = bound_textures_.begin(); - it != bound_textures_.end(); it++) { + for (auto it = bound_textures_.begin(); it != bound_textures_.end(); it++) { if (it->second == id) it->second = 0; }
diff --git a/components/web_cache/browser/web_cache_manager.cc b/components/web_cache/browser/web_cache_manager.cc index 2f730197..2e33597 100644 --- a/components/web_cache/browser/web_cache_manager.cc +++ b/components/web_cache/browser/web_cache_manager.cc
@@ -108,12 +108,12 @@ } void WebCacheManager::ObserveActivity(int renderer_id) { - StatsMap::iterator item = stats_.find(renderer_id); + auto item = stats_.find(renderer_id); if (item == stats_.end()) return; // We might see stats for a renderer that has been destroyed. - std::set<int>::iterator active_elmt = active_renderers_.find(renderer_id); - std::set<int>::iterator inactive_elmt = inactive_renderers_.find(renderer_id); + auto active_elmt = active_renderers_.find(renderer_id); + auto inactive_elmt = inactive_renderers_.find(renderer_id); // Record activity, but only if we already received the notification that the // render process host exist. We might have stats from a destroyed renderer @@ -138,7 +138,7 @@ void WebCacheManager::ObserveStats(int renderer_id, uint64_t capacity, uint64_t size) { - StatsMap::iterator entry = stats_.find(renderer_id); + auto entry = stats_.find(renderer_id); if (entry == stats_.end()) return; // We might see stats for a renderer that has been destroyed. @@ -198,9 +198,9 @@ uint64_t* size) { *capacity = *size = 0; - std::set<int>::const_iterator iter = renderers.begin(); + auto iter = renderers.begin(); while (iter != renderers.end()) { - StatsMap::iterator elmt = stats_.find(*iter); + auto elmt = stats_.find(*iter); if (elmt != stats_.end()) { *capacity += elmt->second.capacity; *size += elmt->second.size; @@ -281,12 +281,12 @@ // Divide the extra memory evenly among the renderers. uint64_t extra_each = extra_bytes_to_allocate / renderers.size(); - std::set<int>::const_iterator iter = renderers.begin(); + auto iter = renderers.begin(); while (iter != renderers.end()) { uint64_t cache_size = extra_each; // Add in the space required to implement |tactic|. - StatsMap::iterator elmt = stats_.find(*iter); + auto elmt = stats_.find(*iter); if (elmt != stats_.end()) { cache_size += GetSize(tactic, elmt->second.size); } @@ -299,7 +299,7 @@ void WebCacheManager::EnactStrategy(const AllocationStrategy& strategy) { // Inform each render process of its cache allocation. - AllocationStrategy::const_iterator allocation = strategy.begin(); + auto allocation = strategy.begin(); while (allocation != strategy.end()) { content::RenderProcessHost* host = content::RenderProcessHost::FromID(allocation->first); @@ -327,7 +327,7 @@ void WebCacheManager::ClearRendererCache( const std::set<int>& renderers, WebCacheManager::ClearCacheOccasion occasion) { - std::set<int>::const_iterator iter = renderers.begin(); + auto iter = renderers.begin(); for (; iter != renderers.end(); ++iter) { content::RenderProcessHost* host = content::RenderProcessHost::FromID(*iter); @@ -414,9 +414,9 @@ } void WebCacheManager::FindInactiveRenderers() { - std::set<int>::const_iterator iter = active_renderers_.begin(); + auto iter = active_renderers_.begin(); while (iter != active_renderers_.end()) { - StatsMap::iterator elmt = stats_.find(*iter); + auto elmt = stats_.find(*iter); DCHECK(elmt != stats_.end()); TimeDelta idle = Time::Now() - elmt->second.access; if (idle >= TimeDelta::FromMinutes(kRendererInactiveThresholdMinutes)) {
diff --git a/components/web_cache/browser/web_cache_manager_unittest.cc b/components/web_cache/browser/web_cache_manager_unittest.cc index b8f5025..131fe00 100644 --- a/components/web_cache/browser/web_cache_manager_unittest.cc +++ b/components/web_cache/browser/web_cache_manager_unittest.cc
@@ -226,7 +226,7 @@ kStats2, &strategy)); EXPECT_EQ(2U, strategy.size()); - AllocationStrategy::iterator iter = strategy.begin(); + auto iter = strategy.begin(); while (iter != strategy.end()) { if (iter->first == kRendererID) EXPECT_LE(kStats.size, iter->second); @@ -264,7 +264,7 @@ EXPECT_EQ(2U, strategy.size()); uint64_t total_bytes = 0; - AllocationStrategy::iterator iter = strategy.begin(); + auto iter = strategy.begin(); while (iter != strategy.end()) { total_bytes += iter->second;
diff --git a/components/webcrypto/algorithms/sha_unittest.cc b/components/webcrypto/algorithms/sha_unittest.cc index d2cc70c..8518ffc 100644 --- a/components/webcrypto/algorithms/sha_unittest.cc +++ b/components/webcrypto/algorithms/sha_unittest.cc
@@ -65,7 +65,7 @@ size_t length = test_input.size(); std::unique_ptr<blink::WebCryptoDigestor> digestor( CreateDigestor(test_algorithm.Id())); - std::vector<uint8_t>::iterator begin = test_input.begin(); + auto begin = test_input.begin(); size_t chunk_index = 0; while (begin != test_input.end()) { size_t chunk_length = std::min(kChunkSizeBytes, length - chunk_index);
diff --git a/components/webdata/common/web_database.cc b/components/webdata/common/web_database.cc index a6b6b14..76fd1406 100644 --- a/components/webdata/common/web_database.cc +++ b/components/webdata/common/web_database.cc
@@ -117,7 +117,7 @@ } // Initialize the tables. - for (TableMap::iterator it = tables_.begin(); it != tables_.end(); ++it) { + for (auto it = tables_.begin(); it != tables_.end(); ++it) { it->second->Init(&db_, &meta_table_); } @@ -132,7 +132,7 @@ // It's important that this happen *after* the migration code runs. // Otherwise, the migration code would have to explicitly check for empty // tables created in the new format, and skip the migration in that case. - for (TableMap::iterator it = tables_.begin(); it != tables_.end(); ++it) { + for (auto it = tables_.begin(); it != tables_.end(); ++it) { if (!it->second->CreateTablesIfNecessary()) { LOG(WARNING) << "Unable to initialize the web database."; return sql::INIT_FAILURE; @@ -163,7 +163,7 @@ ChangeVersion(&meta_table_, next_version, update_compatible_version); // Give each table a chance to migrate to this version. - for (TableMap::iterator it = tables_.begin(); it != tables_.end(); ++it) { + for (auto it = tables_.begin(); it != tables_.end(); ++it) { // Any of the tables may set this to true, but by default it is false. update_compatible_version = false; if (!it->second->MigrateToVersion(next_version,
diff --git a/components/zoom/page_zoom.cc b/components/zoom/page_zoom.cc index 98dea1e..d683926 100644 --- a/components/zoom/page_zoom.cc +++ b/components/zoom/page_zoom.cc
@@ -97,8 +97,7 @@ if (zoom == content::PAGE_ZOOM_OUT) { // Iterate through the zoom levels in reverse order to find the next // lower level based on the current zoom level for this page. - for (std::vector<double>::reverse_iterator i = zoom_levels.rbegin(); - i != zoom_levels.rend(); ++i) { + for (auto i = zoom_levels.rbegin(); i != zoom_levels.rend(); ++i) { double zoom_level = *i; if (content::ZoomValuesEqual(zoom_level, current_zoom_level)) continue;
diff --git a/content/browser/appcache/appcache_job.cc b/content/browser/appcache/appcache_job.cc index 20fcaed..e5575b2 100644 --- a/content/browser/appcache/appcache_job.cc +++ b/content/browser/appcache/appcache_job.cc
@@ -20,26 +20,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } -bool AppCacheJob::IsWaiting() const { - return delivery_type_ == AWAITING_DELIVERY_ORDERS; -} - -bool AppCacheJob::IsDeliveringAppCacheResponse() const { - return delivery_type_ == APPCACHED_DELIVERY; -} - -bool AppCacheJob::IsDeliveringNetworkResponse() const { - return delivery_type_ == NETWORK_DELIVERY; -} - -bool AppCacheJob::IsDeliveringErrorResponse() const { - return delivery_type_ == ERROR_DELIVERY; -} - -bool AppCacheJob::IsCacheEntryNotFound() const { - return cache_entry_not_found_; -} - AppCacheURLRequestJob* AppCacheJob::AsURLRequestJob() { return nullptr; } @@ -49,7 +29,8 @@ } AppCacheJob::AppCacheJob() - : cache_entry_not_found_(false), delivery_type_(AWAITING_DELIVERY_ORDERS) {} + : cache_entry_not_found_(false), + delivery_type_(DeliveryType::kAwaitingDeliverCall) {} void AppCacheJob::InitializeRangeRequestInfo( const net::HttpRequestHeaders& headers) {
diff --git a/content/browser/appcache/appcache_job.h b/content/browser/appcache/appcache_job.h index 47d8037..cf18a72 100644 --- a/content/browser/appcache/appcache_job.h +++ b/content/browser/appcache/appcache_job.h
@@ -36,32 +36,40 @@ // of the AppCache code. class CONTENT_EXPORT AppCacheJob { public: - enum DeliveryType { - AWAITING_DELIVERY_ORDERS, - APPCACHED_DELIVERY, - NETWORK_DELIVERY, - ERROR_DELIVERY + enum class DeliveryType { + kAwaitingDeliverCall, + kAppCached, + kNetwork, + kError, }; virtual ~AppCacheJob(); - // Returns true if the job was started. + // True if the job was started. virtual bool IsStarted() const = 0; - // Returns true if the job is waiting for instructions. - virtual bool IsWaiting() const; + // True if the job is waiting for instructions. + bool IsWaiting() const { + return delivery_type_ == DeliveryType::kAwaitingDeliverCall; + } - // Returns true if the job is delivering a response from the cache. - virtual bool IsDeliveringAppCacheResponse() const; + // True if the job is delivering a response from the cache. + bool IsDeliveringAppCacheResponse() const { + return delivery_type_ == DeliveryType::kAppCached; + } // Returns true if the job is delivering a response from the network. - virtual bool IsDeliveringNetworkResponse() const; + bool IsDeliveringNetworkResponse() const { + return delivery_type_ == DeliveryType::kNetwork; + } // Returns true if the job is delivering an error response. - virtual bool IsDeliveringErrorResponse() const; + bool IsDeliveringErrorResponse() const { + return delivery_type_ == DeliveryType::kError; + } // Returns true if the cache entry was not found in the cache. - virtual bool IsCacheEntryNotFound() const; + bool IsCacheEntryNotFound() const { return cache_entry_not_found_; } // Informs the job of what response it should deliver. Only one of these // methods should be called, and only once per job. A job will sit idle and
diff --git a/content/browser/appcache/appcache_update_job_unittest.cc b/content/browser/appcache/appcache_update_job_unittest.cc index 6b0d9d72..14224cf 100644 --- a/content/browser/appcache/appcache_update_job_unittest.cc +++ b/content/browser/appcache/appcache_update_job_unittest.cc
@@ -754,7 +754,7 @@ } void StartCacheAttemptTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"), @@ -789,7 +789,7 @@ } void StartUpgradeAttemptTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); { MakeService(); @@ -855,7 +855,7 @@ } void CacheAttemptFetchManifestFailTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"), @@ -879,7 +879,7 @@ } void UpgradeFetchManifestFailTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), @@ -920,7 +920,7 @@ } void ManifestRedirectTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); if (request_handler_type_ == URLREQUEST) { net::URLRequestJobFactoryImpl* new_factory( @@ -952,7 +952,7 @@ } void ManifestMissingMimeTypeTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -992,7 +992,7 @@ } void ManifestNotFoundTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1028,7 +1028,7 @@ } void ManifestGoneTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1053,7 +1053,7 @@ } void CacheAttemptNotModifiedTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1078,7 +1078,7 @@ } void UpgradeNotModifiedTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1122,7 +1122,7 @@ } void UpgradeManifestDataUnchangedTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1173,7 +1173,7 @@ // See http://code.google.com/p/chromium/issues/detail?id=95101 void Bug95101Test() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1217,7 +1217,7 @@ } void BasicCacheAttemptSuccessTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); GURL manifest_url = MockHttpServer::GetMockUrl("files/manifest1"); @@ -1248,7 +1248,7 @@ void DownloadInterceptEntriesTest() { // Ensures we download intercept entries too. - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); GURL manifest_url = MockHttpServer::GetMockUrl("files/manifest-with-intercept"); MakeService(); @@ -1275,7 +1275,7 @@ } void BasicUpgradeSuccessTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1344,7 +1344,7 @@ } void UpgradeLoadFromNewestCacheTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1412,7 +1412,7 @@ } void UpgradeNoLoadFromNewestCacheTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1478,7 +1478,7 @@ } void UpgradeLoadFromNewestCacheVaryHeaderTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1544,7 +1544,7 @@ } void UpgradeLoadFromNewestCacheReuseVaryHeaderTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), @@ -1614,7 +1614,7 @@ } void UpgradeSuccessMergedTypesTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), @@ -1672,7 +1672,7 @@ } void CacheAttemptFailUrlFetchTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), @@ -1697,7 +1697,7 @@ } void UpgradeFailUrlFetchTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), @@ -1742,7 +1742,7 @@ } void UpgradeFailMasterUrlFetchTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); tested_manifest_path_override_ = "files/manifest1-with-notmodified"; @@ -1855,7 +1855,7 @@ } void EmptyManifestTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -1904,7 +1904,7 @@ } void EmptyFileTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), @@ -1941,7 +1941,7 @@ } void RetryRequestTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); // Set some large number of times to return retry. // Expect 1 manifest fetch and 3 retries. @@ -1978,7 +1978,7 @@ } void RetryNoRetryAfterTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); // Set some large number of times to return retry. // Expect 1 manifest fetch and 0 retries. @@ -2015,7 +2015,7 @@ } void RetryNonzeroRetryAfterTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); // Set some large number of times to return retry. // Expect 1 request and 0 retry attempts. @@ -2053,7 +2053,7 @@ } void RetrySuccessTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); // Set 2 as the retry limit (does not exceed the max). // Expect 1 manifest fetch, 2 retries, 1 url fetch, 1 manifest refetch. @@ -2090,7 +2090,7 @@ } void RetryUrlTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); // Set 1 as the retry limit (does not exceed the max). // Expect 1 manifest fetch, 1 url fetch, 1 url retry, 1 manifest refetch. @@ -2127,7 +2127,7 @@ } void FailStoreNewestCacheTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); MockAppCacheStorage* storage = @@ -2156,7 +2156,7 @@ } void UpgradeFailStoreNewestCacheTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); MockAppCacheStorage* storage = @@ -2204,7 +2204,7 @@ } void MasterEntryFailStoreNewestCacheTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); MockAppCacheStorage* storage = @@ -2254,7 +2254,7 @@ } void UpgradeFailMakeGroupObsoleteTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); MockAppCacheStorage* storage = @@ -2294,7 +2294,7 @@ } void MasterEntryFetchManifestFailTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"), 111); @@ -2319,7 +2319,7 @@ } void MasterEntryBadManifestTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), @@ -2345,7 +2345,7 @@ } void MasterEntryManifestNotFoundTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -2374,7 +2374,7 @@ } void MasterEntryFailUrlFetchTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), @@ -2405,7 +2405,7 @@ } void MasterEntryAllFailTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -2449,7 +2449,7 @@ } void UpgradeMasterEntryAllFailTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -2509,7 +2509,7 @@ } void MasterEntrySomeFailTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -2560,7 +2560,7 @@ } void UpgradeMasterEntrySomeFailTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -2627,7 +2627,7 @@ } void MasterEntryNoUpdateTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup(service_->storage(), @@ -2683,7 +2683,7 @@ } void StartUpdateMidCacheAttemptTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -2778,7 +2778,7 @@ } void StartUpdateMidNoUpdateTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -2863,7 +2863,7 @@ } void StartUpdateMidDownloadTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -2962,7 +2962,7 @@ } void QueueMasterEntryTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); MakeService(); group_ = new AppCacheGroup( @@ -3020,7 +3020,7 @@ } void IfModifiedSinceTestCache() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); if (request_handler_type_ == URLREQUEST) { net::URLRequestJobFactoryImpl* new_factory( @@ -3061,7 +3061,7 @@ } void IfModifiedTestRefetch() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); if (request_handler_type_ == URLREQUEST) { net::URLRequestJobFactoryImpl* new_factory( @@ -3112,7 +3112,7 @@ } void IfModifiedTestLastModified() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); if (request_handler_type_ == URLREQUEST) { net::URLRequestJobFactoryImpl* new_factory( @@ -3164,7 +3164,7 @@ } void IfModifiedSinceUpgradeTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); HttpHeadersRequestTestJob::Initialize("Sat, 29 Oct 1994 19:43:31 GMT", std::string()); @@ -3238,7 +3238,7 @@ } void IfNoneMatchUpgradeTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); HttpHeadersRequestTestJob::Initialize(std::string(), "\"LadeDade\""); @@ -3311,7 +3311,7 @@ } void IfNoneMatchRefetchTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); HttpHeadersRequestTestJob::Initialize(std::string(), "\"LadeDade\""); @@ -3362,7 +3362,7 @@ } void MultipleHeadersRefetchTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); // Verify that code is correct when building multiple extra headers. HttpHeadersRequestTestJob::Initialize( @@ -3416,7 +3416,7 @@ } void CrossOriginHttpsSuccessTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); GURL manifest_url = MockHttpServer::GetMockHttpsUrl( "files/valid_cross_origin_https_manifest"); @@ -3445,7 +3445,7 @@ } void CrossOriginHttpsDeniedTest() { - ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); + ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet()); GURL manifest_url = MockHttpServer::GetMockHttpsUrl( "files/invalid_cross_origin_https_manifest");
diff --git a/content/browser/appcache/appcache_url_loader_job.cc b/content/browser/appcache/appcache_url_loader_job.cc index 559ea899..c4f12132 100644 --- a/content/browser/appcache/appcache_url_loader_job.cc +++ b/content/browser/appcache/appcache_url_loader_job.cc
@@ -22,8 +22,8 @@ } bool AppCacheURLLoaderJob::IsStarted() const { - return delivery_type_ != AWAITING_DELIVERY_ORDERS && - delivery_type_ != NETWORK_DELIVERY; + return delivery_type_ != DeliveryType::kAwaitingDeliverCall && + delivery_type_ != DeliveryType::kNetwork; } void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url, @@ -35,7 +35,7 @@ return; } - delivery_type_ = APPCACHED_DELIVERY; + delivery_type_ = DeliveryType::kAppCached; // In tests we only care about the delivery_type_ state. if (AppCacheRequestHandler::IsRunningInTests()) @@ -62,7 +62,7 @@ } void AppCacheURLLoaderJob::DeliverNetworkResponse() { - delivery_type_ = NETWORK_DELIVERY; + delivery_type_ = DeliveryType::kNetwork; // In tests we only care about the delivery_type_ state. if (AppCacheRequestHandler::IsRunningInTests()) @@ -76,7 +76,7 @@ } void AppCacheURLLoaderJob::DeliverErrorResponse() { - delivery_type_ = ERROR_DELIVERY; + delivery_type_ = DeliveryType::kError; // In tests we only care about the delivery_type_ state. if (AppCacheRequestHandler::IsRunningInTests()) @@ -342,7 +342,7 @@ } client_->OnComplete(status); - if (delivery_type_ == APPCACHED_DELIVERY) { + if (delivery_type_ == DeliveryType::kAppCached) { AppCacheHistograms::CountResponseRetrieval( error_code == 0, is_main_resource_load_, url::Origin::Create(manifest_url_));
diff --git a/content/browser/appcache/appcache_url_request_job.cc b/content/browser/appcache/appcache_url_request_job.cc index 261303f..cd1ab22e 100644 --- a/content/browser/appcache/appcache_url_request_job.cc +++ b/content/browser/appcache/appcache_url_request_job.cc
@@ -65,7 +65,7 @@ bool is_fallback) { DCHECK(!has_delivery_orders()); DCHECK(entry.has_response_id()); - delivery_type_ = APPCACHED_DELIVERY; + delivery_type_ = DeliveryType::kAppCached; manifest_url_ = manifest_url; cache_id_ = cache_id; entry_ = entry; @@ -75,14 +75,14 @@ void AppCacheURLRequestJob::DeliverNetworkResponse() { DCHECK(!has_delivery_orders()); - delivery_type_ = NETWORK_DELIVERY; + delivery_type_ = DeliveryType::kNetwork; storage_ = nullptr; // not needed MaybeBeginDelivery(); } void AppCacheURLRequestJob::DeliverErrorResponse() { DCHECK(!has_delivery_orders()); - delivery_type_ = ERROR_DELIVERY; + delivery_type_ = DeliveryType::kError; storage_ = nullptr; // not needed MaybeBeginDelivery(); } @@ -137,7 +137,7 @@ return; switch (delivery_type_) { - case NETWORK_DELIVERY: + case DeliveryType::kNetwork: // To fallthru to the network, we restart the request which will // cause a new job to be created to retrieve the resource from the // network. Our caller is responsible for arranging to not re-intercept @@ -145,14 +145,14 @@ NotifyRestartRequired(); break; - case ERROR_DELIVERY: + case DeliveryType::kError: request()->net_log().AddEvent( net::NetLogEventType::APPCACHE_DELIVERING_ERROR_RESPONSE); NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); break; - case APPCACHED_DELIVERY: + case DeliveryType::kAppCached: request()->net_log().AddEvent( is_fallback_ ? net::NetLogEventType::APPCACHE_DELIVERING_FALLBACK_RESPONSE @@ -170,7 +170,7 @@ if (host_) host_->frontend()->OnLogMessage(host_->host_id(), APPCACHE_LOG_ERROR, message); - delivery_type_ = ERROR_DELIVERY; + delivery_type_ = DeliveryType::kError; storage_ = nullptr; BeginDelivery(); } @@ -249,7 +249,7 @@ return net::LOAD_STATE_IDLE; if (!has_delivery_orders()) return net::LOAD_STATE_WAITING_FOR_APPCACHE; - if (delivery_type_ != APPCACHED_DELIVERY) + if (delivery_type_ != DeliveryType::kAppCached) return net::LOAD_STATE_IDLE; if (!info_.get()) return net::LOAD_STATE_WAITING_FOR_APPCACHE;
diff --git a/content/browser/background_fetch/background_fetch_context.cc b/content/browser/background_fetch/background_fetch_context.cc index e95ff15..eb08b1d 100644 --- a/content/browser/background_fetch/background_fetch_context.cc +++ b/content/browser/background_fetch/background_fetch_context.cc
@@ -404,6 +404,14 @@ blink::mojom::BackgroundFetchService::AbortCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + auto controllers_iter = job_controllers_.find(registration_id.unique_id()); + if (controllers_iter == job_controllers_.end()) { + std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_ID); + return; + } + + controllers_iter->second->Abort(FailureReason::CANCELLED_BY_DEVELOPER); + DidFinishJob(std::move(callback), registration_id, FailureReason::CANCELLED_BY_DEVELOPER); } @@ -411,21 +419,21 @@ void BackgroundFetchContext::DidFinishJob( base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback, const BackgroundFetchRegistrationId& registration_id, - FailureReason reason_to_abort) { + FailureReason failure_reason) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - // If |aborted| is true, this will also propagate the event to any active - // JobController for the registration, to terminate in-progress requests. + // If the registration was aborted, this will also propagate the event to any + // active JobController, to terminate in-progress requests. data_manager_->MarkRegistrationForDeletion( registration_id, base::BindOnce(&BackgroundFetchContext::DidMarkForDeletion, weak_factory_.GetWeakPtr(), registration_id, - reason_to_abort, std::move(callback))); + failure_reason, std::move(callback))); } void BackgroundFetchContext::DidMarkForDeletion( const BackgroundFetchRegistrationId& registration_id, - FailureReason reason_to_abort, + FailureReason failure_reason, base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback, blink::mojom::BackgroundFetchError error) { DCHECK(callback); @@ -434,51 +442,30 @@ // It's normal to get INVALID_ID errors here - it means the registration was // already inactive (marked for deletion). This happens when an abort (from // developer or from user) races with the download completing/failing, or even - // when two aborts race. TODO(johnme): Log STORAGE_ERRORs to UMA though. + // when two aborts race. if (error != blink::mojom::BackgroundFetchError::NONE) return; - auto controllers_iter = job_controllers_.find(registration_id.unique_id()); - - if (reason_to_abort == FailureReason::CANCELLED_BY_DEVELOPER) { - DCHECK(controllers_iter != job_controllers_.end()); - controllers_iter->second->Abort(reason_to_abort); + if (failure_reason == FailureReason::NONE) { + // As far as we know the fetch was successful, go over the entries in the + // cache and make sure all the responses are there and successful. + data_manager_->GetSettledFetchesForRegistration( + registration_id, std::make_unique<BackgroundFetchRequestMatchParams>(), + base::BindOnce(&BackgroundFetchContext::DidGetSettledFetches, + weak_factory_.GetWeakPtr(), registration_id)); + return; } + + // The fetch failed, dispatch an appropriate event. + auto controllers_iter = job_controllers_.find(registration_id.unique_id()); + DCHECK(controllers_iter != job_controllers_.end()); auto registration = controllers_iter->second->NewRegistration( blink::mojom::BackgroundFetchResult::FAILURE); - - switch (reason_to_abort) { - case FailureReason::CANCELLED_BY_DEVELOPER: - case FailureReason::CANCELLED_FROM_UI: - CleanupRegistration(registration_id, {}, - blink::mojom::BackgroundFetchResult::FAILURE); - event_dispatcher_.DispatchBackgroundFetchAbortEvent( - registration_id, std::move(registration), base::DoNothing()); - return; - case FailureReason::TOTAL_DOWNLOAD_SIZE_EXCEEDED: - case FailureReason::SERVICE_WORKER_UNAVAILABLE: - case FailureReason::QUOTA_EXCEEDED: - case FailureReason::BAD_STATUS: - case FailureReason::FETCH_ERROR: - case FailureReason::NONE: - // This will send a BackgroundFetchFetched or BackgroundFetchFail event. - // We still need this to figure out which event to send. - // TODO(crbug.com/699957, crbug.com/874092): Add a method to only return - // the information needed to dispatch these events, instead of settled - // fetches. - data_manager_->GetSettledFetchesForRegistration( - registration_id, - std::make_unique<BackgroundFetchRequestMatchParams>(), - base::BindOnce(&BackgroundFetchContext::DidGetSettledFetches, - weak_factory_.GetWeakPtr(), registration_id, - std::move(registration))); - return; - } + DispatchCompletionEvent(registration_id, std::move(registration)); } void BackgroundFetchContext::DidGetSettledFetches( const BackgroundFetchRegistrationId& registration_id, - std::unique_ptr<BackgroundFetchRegistration> registration, blink::mojom::BackgroundFetchError error, FailureReason failure_reason, std::vector<BackgroundFetchSettledFetch> settled_fetches, @@ -489,55 +476,53 @@ failure_reason == FailureReason::SERVICE_WORKER_UNAVAILABLE || failure_reason == FailureReason::BAD_STATUS); - if (error != blink::mojom::BackgroundFetchError::NONE) { - CleanupRegistration(registration_id, {} /* fetches */, - blink::mojom::BackgroundFetchResult::FAILURE, - true /* preserve_info_to_dispatch_click_event */); - return; - } + auto controllers_iter = job_controllers_.find(registration_id.unique_id()); + DCHECK(controllers_iter != job_controllers_.end()); + failure_reason = controllers_iter->second->MergeFailureReason(failure_reason); - DCHECK(job_controllers_.count(registration_id.unique_id())); + blink::mojom::BackgroundFetchResult result = + failure_reason == FailureReason::NONE + ? blink::mojom::BackgroundFetchResult::SUCCESS + : blink::mojom::BackgroundFetchResult::FAILURE; - // The `backgroundfetchsuccess` event will be invoked when all requests in the - // registration have completed successfully. In all other cases, the - // `backgroundfetchfail` event will be invoked instead. - if (registration->failure_reason == FailureReason::NONE && - failure_reason != FailureReason::NONE) { - registration->failure_reason = failure_reason; - } + auto registration = controllers_iter->second->NewRegistration(result); + DispatchCompletionEvent(registration_id, std::move(registration)); +} + +void BackgroundFetchContext::DispatchCompletionEvent( + const BackgroundFetchRegistrationId& registration_id, + std::unique_ptr<BackgroundFetchRegistration> registration) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); switch (registration->failure_reason) { case FailureReason::NONE: - registration->result = blink::mojom::BackgroundFetchResult::SUCCESS; event_dispatcher_.DispatchBackgroundFetchSuccessEvent( registration_id, std::move(registration), base::BindOnce( &BackgroundFetchContext::CleanupRegistration, weak_factory_.GetWeakPtr(), registration_id, - // The blob uuid is sent as part of |settled_fetches|. Bind - // |blob_data_handles| to the callback to keep them alive - // until the waitUntil event is resolved. - std::move(blob_data_handles), blink::mojom::BackgroundFetchResult::SUCCESS, true /* preserve_info_to_dispatch_click_event */)); return; case FailureReason::CANCELLED_FROM_UI: case FailureReason::CANCELLED_BY_DEVELOPER: + event_dispatcher_.DispatchBackgroundFetchAbortEvent( + registration_id, std::move(registration), + base::BindOnce(&BackgroundFetchContext::CleanupRegistration, + weak_factory_.GetWeakPtr(), registration_id, + blink::mojom::BackgroundFetchResult::FAILURE, + false /* preserve_info_to_dispatch_click_event */)); + return; case FailureReason::BAD_STATUS: case FailureReason::FETCH_ERROR: case FailureReason::SERVICE_WORKER_UNAVAILABLE: case FailureReason::QUOTA_EXCEEDED: case FailureReason::TOTAL_DOWNLOAD_SIZE_EXCEEDED: - registration->result = blink::mojom::BackgroundFetchResult::FAILURE; event_dispatcher_.DispatchBackgroundFetchFailEvent( registration_id, std::move(registration), base::BindOnce( &BackgroundFetchContext::CleanupRegistration, weak_factory_.GetWeakPtr(), registration_id, - // The blob uuid is sent as part of |settled_fetches|. Bind - // |blob_data_handles| to the callback to keep them alive - // until the waitUntil event is resolved. - std::move(blob_data_handles), blink::mojom::BackgroundFetchResult::FAILURE, true /* preserve_info_to_dispatch_click_event */)); return; @@ -546,7 +531,6 @@ void BackgroundFetchContext::CleanupRegistration( const BackgroundFetchRegistrationId& registration_id, - const std::vector<std::unique_ptr<storage::BlobDataHandle>>& blob_handles, blink::mojom::BackgroundFetchResult background_fetch_result, bool preserve_info_to_dispatch_click_event) { DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/content/browser/background_fetch/background_fetch_context.h b/content/browser/background_fetch/background_fetch_context.h index 7dea305..10e0327 100644 --- a/content/browser/background_fetch/background_fetch_context.h +++ b/content/browser/background_fetch/background_fetch_context.h
@@ -201,12 +201,12 @@ void DidFinishJob( base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback, const BackgroundFetchRegistrationId& registration_id, - blink::mojom::BackgroundFetchFailureReason reason_to_abort); + blink::mojom::BackgroundFetchFailureReason failure_reason); // Called when the data manager finishes marking a registration as deleted. void DidMarkForDeletion( const BackgroundFetchRegistrationId& registration_id, - blink::mojom::BackgroundFetchFailureReason reason_to_abort, + blink::mojom::BackgroundFetchFailureReason failure_reason, base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback, blink::mojom::BackgroundFetchError error); @@ -214,7 +214,6 @@ // retrieved from storage, and the Service Worker event can be invoked. void DidGetSettledFetches( const BackgroundFetchRegistrationId& registration_id, - std::unique_ptr<BackgroundFetchRegistration> registration, blink::mojom::BackgroundFetchError error, blink::mojom::BackgroundFetchFailureReason failure_reason, std::vector<BackgroundFetchSettledFetch> settled_fetches, @@ -230,6 +229,11 @@ std::vector<BackgroundFetchSettledFetch> settled_fetches, std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles); + // Dispatches an appropriate event (success, fail, abort). + void DispatchCompletionEvent( + const BackgroundFetchRegistrationId& registration_id, + std::unique_ptr<BackgroundFetchRegistration> registration); + // Called when the notification UI for the background fetch job associated // with |unique_id| is activated. void DispatchClickEvent(const std::string& unique_id); @@ -241,16 +245,14 @@ initialization_data); // Called when all processing for the |registration_id| has been finished and - // the job is ready to be deleted. |blob_handles| are unused, but some callers - // use it to keep blobs alive for the right duration. - // |partial cleanup|, when set, preserves the registration ID, and the result - // of Fetch when it completed, in |completed_fetches_|. This is not done when - // fetch is aborted or cancelled. We use this information to propagate - // BackgroundFetchClicked event to the developer, when the user taps the UI. + // the job is ready to be deleted. + // |preserve_info_to_dispatch_click_event|, when set, preserves the + // registration ID, and the result of the Fetch when it completed, in + // |completed_fetches_|. This is not done when fetch is aborted or cancelled. + // We use this information to propagate BackgroundFetchClicked event to the + // developer, when the user taps the UI. void CleanupRegistration( const BackgroundFetchRegistrationId& registration_id, - const std::vector<std::unique_ptr<storage::BlobDataHandle>>& - blob_data_handles, blink::mojom::BackgroundFetchResult background_fetch_result, bool preserve_info_to_dispatch_click_event = false);
diff --git a/content/browser/background_fetch/background_fetch_job_controller.cc b/content/browser/background_fetch/background_fetch_job_controller.cc index aae90ba..bc43daa 100644 --- a/content/browser/background_fetch/background_fetch_job_controller.cc +++ b/content/browser/background_fetch/background_fetch_job_controller.cc
@@ -13,6 +13,8 @@ namespace content { +using blink::mojom::BackgroundFetchFailureReason; + BackgroundFetchJobController::BackgroundFetchJobController( BackgroundFetchDelegateProxy* delegate_proxy, BackgroundFetchScheduler* scheduler, @@ -197,7 +199,7 @@ return std::make_unique<BackgroundFetchRegistration>( registration_id().developer_id(), registration_id().unique_id(), 0 /* upload_total */, 0 /* uploaded */, total_downloads_size_, - complete_requests_downloaded_bytes_cache_, result, reason_to_abort_); + complete_requests_downloaded_bytes_cache_, result, failure_reason_); } uint64_t BackgroundFetchJobController::GetInProgressDownloadedBytes() { @@ -205,8 +207,8 @@ } void BackgroundFetchJobController::Abort( - blink::mojom::BackgroundFetchFailureReason reason_to_abort) { - reason_to_abort_ = reason_to_abort; + BackgroundFetchFailureReason failure_reason) { + failure_reason_ = failure_reason; // Stop propagating any in-flight events to the scheduler. active_request_finished_callback_.Reset(); @@ -214,7 +216,14 @@ // Cancel any in-flight downloads and UI through the BGFetchDelegate. delegate_proxy_->Abort(registration_id().unique_id()); - Finish(reason_to_abort); + Finish(failure_reason_); +} + +BackgroundFetchFailureReason BackgroundFetchJobController::MergeFailureReason( + BackgroundFetchFailureReason failure_reason) { + if (failure_reason_ == BackgroundFetchFailureReason::NONE) + failure_reason_ = failure_reason; + return failure_reason_; } } // namespace content
diff --git a/content/browser/background_fetch/background_fetch_job_controller.h b/content/browser/background_fetch/background_fetch_job_controller.h index 56d0941..5461744e 100644 --- a/content/browser/background_fetch/background_fetch_job_controller.h +++ b/content/browser/background_fetch/background_fetch_job_controller.h
@@ -94,6 +94,11 @@ // Returns the number of requests that comprise the whole job. int total_downloads() const { return total_downloads_; } + // If |failure_reason_| is none, overwrites it with |failure_reason|, and + // returns the new value. + blink::mojom::BackgroundFetchFailureReason MergeFailureReason( + blink::mojom::BackgroundFetchFailureReason failure_reason); + base::WeakPtr<BackgroundFetchJobController> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } @@ -114,7 +119,7 @@ std::vector<scoped_refptr<BackgroundFetchRequestInfo>> TakeOutstandingRequests() override; void Abort( - blink::mojom::BackgroundFetchFailureReason reason_to_abort) override; + blink::mojom::BackgroundFetchFailureReason failure_reason) override; private: // Performs mixed content checks on the |request| for Background Fetch. @@ -167,7 +172,7 @@ int completed_downloads_ = 0; // The reason background fetch was aborted. - blink::mojom::BackgroundFetchFailureReason reason_to_abort_ = + blink::mojom::BackgroundFetchFailureReason failure_reason_ = blink::mojom::BackgroundFetchFailureReason::NONE; base::WeakPtrFactory<BackgroundFetchJobController> weak_ptr_factory_;
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 2b16f9bc..6009645 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -37,7 +37,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/synchronization/waitable_event.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/task/post_task.h" #include "base/task/task_scheduler/initialization_util.h" #include "base/threading/thread.h" @@ -1577,7 +1577,7 @@ // Android's main message loop is the Java message loop. NOTREACHED(); #else - DCHECK(base::MessageLoopForUI::IsCurrent()); + DCHECK(base::MessageLoopCurrentForUI::IsSet()); if (parameters_.ui_task) { base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, *parameters_.ui_task);
diff --git a/content/browser/byte_stream_unittest.cc b/content/browser/byte_stream_unittest.cc index 4b89fb1..0d617d3 100644 --- a/content/browser/byte_stream_unittest.cc +++ b/content/browser/byte_stream_unittest.cc
@@ -12,9 +12,10 @@ #include "base/callback.h" #include "base/containers/circular_deque.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/test/test_simple_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" #include "net/base/io_buffer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -90,7 +91,7 @@ } protected: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; private: int producing_seed_key_; @@ -108,8 +109,9 @@ TEST_F(ByteStreamTest, ByteStream_PushBack) { std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), - 3 * 1024, &byte_stream_input, &byte_stream_output); + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), 3 * 1024, + &byte_stream_input, &byte_stream_output); // Push a series of IO buffers on; test pushback happening and // that it's advisory. @@ -162,8 +164,9 @@ TEST_F(ByteStreamTest, ByteStream_Flush) { std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), - 1024, &byte_stream_input, &byte_stream_output); + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), 1024, + &byte_stream_input, &byte_stream_output); EXPECT_TRUE(Write(byte_stream_input.get(), 1)); base::RunLoop().RunUntilIdle(); @@ -201,8 +204,9 @@ TEST_F(ByteStreamTest, ByteStream_PushBackSplit) { std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), - 9 * 1024, &byte_stream_input, &byte_stream_output); + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), 9 * 1024, + &byte_stream_input, &byte_stream_output); // Push a series of IO buffers on; test pushback happening and // that it's advisory. @@ -255,8 +259,9 @@ size_t output_length; // Empty stream, non-error case. - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), - 3 * 1024, &byte_stream_input, &byte_stream_output); + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), 3 * 1024, + &byte_stream_input, &byte_stream_output); EXPECT_EQ(ByteStreamReader::STREAM_EMPTY, byte_stream_output->Read(&output_io_buffer, &output_length)); byte_stream_input->Close(0); @@ -266,8 +271,9 @@ EXPECT_EQ(0, byte_stream_output->GetStatus()); // Non-empty stream, non-error case. - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), - 3 * 1024, &byte_stream_input, &byte_stream_output); + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), 3 * 1024, + &byte_stream_input, &byte_stream_output); EXPECT_EQ(ByteStreamReader::STREAM_EMPTY, byte_stream_output->Read(&output_io_buffer, &output_length)); EXPECT_TRUE(Write(byte_stream_input.get(), 1024)); @@ -283,8 +289,9 @@ const int kFakeErrorCode = 22; // Empty stream, error case. - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), - 3 * 1024, &byte_stream_input, &byte_stream_output); + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), 3 * 1024, + &byte_stream_input, &byte_stream_output); EXPECT_EQ(ByteStreamReader::STREAM_EMPTY, byte_stream_output->Read(&output_io_buffer, &output_length)); byte_stream_input->Close(kFakeErrorCode); @@ -294,8 +301,9 @@ EXPECT_EQ(kFakeErrorCode, byte_stream_output->GetStatus()); // Non-empty stream, error case. - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), - 3 * 1024, &byte_stream_input, &byte_stream_output); + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), 3 * 1024, + &byte_stream_input, &byte_stream_output); EXPECT_EQ(ByteStreamReader::STREAM_EMPTY, byte_stream_output->Read(&output_io_buffer, &output_length)); EXPECT_TRUE(Write(byte_stream_input.get(), 1024)); @@ -316,7 +324,7 @@ std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(message_loop_.task_runner(), task_runner, 10000, + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), task_runner, 10000, &byte_stream_input, &byte_stream_output); scoped_refptr<net::IOBuffer> output_io_buffer; @@ -367,7 +375,7 @@ std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(task_runner, message_loop_.task_runner(), 10000, + CreateByteStream(task_runner, base::ThreadTaskRunnerHandle::Get(), 10000, &byte_stream_input, &byte_stream_output); scoped_refptr<net::IOBuffer> output_io_buffer; @@ -428,7 +436,7 @@ std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(message_loop_.task_runner(), task_runner, 10000, + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), task_runner, 10000, &byte_stream_input, &byte_stream_output); scoped_refptr<net::IOBuffer> output_io_buffer; @@ -474,7 +482,7 @@ std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(task_runner, message_loop_.task_runner(), 10000, + CreateByteStream(task_runner, base::ThreadTaskRunnerHandle::Get(), 10000, &byte_stream_input, &byte_stream_output); scoped_refptr<net::IOBuffer> output_io_buffer; @@ -525,7 +533,7 @@ std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(message_loop_.task_runner(), task_runner, 10000, + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), task_runner, 10000, &byte_stream_input, &byte_stream_output); base::Closure intermediate_callback; @@ -544,8 +552,9 @@ TEST_F(ByteStreamTest, ByteStream_CloseWithoutAnyWrite) { std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), - 3 * 1024, &byte_stream_input, &byte_stream_output); + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), 3 * 1024, + &byte_stream_input, &byte_stream_output); byte_stream_input->Close(0); base::RunLoop().RunUntilIdle(); @@ -559,8 +568,9 @@ TEST_F(ByteStreamTest, ByteStream_FlushWithoutAnyWrite) { std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), - 3 * 1024, &byte_stream_input, &byte_stream_output); + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), 3 * 1024, + &byte_stream_input, &byte_stream_output); byte_stream_input->Flush(); base::RunLoop().RunUntilIdle(); @@ -580,7 +590,8 @@ TEST_F(ByteStreamTest, ByteStream_WriteOverflow) { std::unique_ptr<ByteStreamWriter> byte_stream_input; std::unique_ptr<ByteStreamReader> byte_stream_output; - CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(), + CreateByteStream(base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), std::numeric_limits<size_t>::max(), &byte_stream_input, &byte_stream_output);
diff --git a/content/browser/compositor/reflector_impl_unittest.cc b/content/browser/compositor/reflector_impl_unittest.cc index 40a83a8..21319bfc 100644 --- a/content/browser/compositor/reflector_impl_unittest.cc +++ b/content/browser/compositor/reflector_impl_unittest.cc
@@ -6,9 +6,9 @@ #include "base/callback.h" #include "base/feature_list.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" @@ -134,12 +134,11 @@ ui::ContextFactory* context_factory = nullptr; ui::ContextFactoryPrivate* context_factory_private = nullptr; - message_loop_ = std::make_unique<base::MessageLoop>(); ui::InitializeContextFactoryForTests(enable_pixel_output, &context_factory, &context_factory_private); ImageTransportFactory::SetFactory( std::make_unique<TestImageTransportFactory>()); - task_runner_ = message_loop_->task_runner(); + task_runner_ = base::ThreadTaskRunnerHandle::Get(); compositor_task_runner_ = new FakeTaskRunner(); begin_frame_source_ = std::make_unique<viz::DelayBasedBeginFrameSource>( std::make_unique<viz::DelayBasedTimeSource>( @@ -193,7 +192,7 @@ protected: scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; std::unique_ptr<viz::SyntheticBeginFrameSource> begin_frame_source_; - std::unique_ptr<base::MessageLoop> message_loop_; + base::test::ScopedTaskEnvironment task_environment_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; std::unique_ptr<ui::Compositor> compositor_; std::unique_ptr<ui::Layer> root_layer_;
diff --git a/content/browser/devtools/devtools_video_consumer_unittest.cc b/content/browser/devtools/devtools_video_consumer_unittest.cc index 34f4b4b..496a3e8 100644 --- a/content/browser/devtools/devtools_video_consumer_unittest.cc +++ b/content/browser/devtools/devtools_video_consumer_unittest.cc
@@ -6,7 +6,7 @@ #include <vector> #include "base/memory/read_only_shared_memory_region.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/browser/devtools/devtools_video_consumer.h" #include "content/public/test/test_utils.h" #include "media/base/limits.h" @@ -231,7 +231,7 @@ weak_factory_.GetWeakPtr())); } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; base::WeakPtrFactory<DevToolsVideoConsumerTest> weak_factory_; };
diff --git a/content/browser/dom_storage/dom_storage_area_unittest.cc b/content/browser/dom_storage/dom_storage_area_unittest.cc index e4520d7..204d008 100644 --- a/content/browser/dom_storage/dom_storage_area_unittest.cc +++ b/content/browser/dom_storage/dom_storage_area_unittest.cc
@@ -10,10 +10,10 @@ #include "base/files/scoped_temp_dir.h" #include "base/location.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "build/build_config.h" @@ -74,7 +74,7 @@ } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; }; class DOMStorageAreaParamTest : public DOMStorageAreaTest,
diff --git a/content/browser/dom_storage/dom_storage_context_impl_unittest.cc b/content/browser/dom_storage/dom_storage_context_impl_unittest.cc index ffb4fc3..1bdd2867 100644 --- a/content/browser/dom_storage/dom_storage_context_impl_unittest.cc +++ b/content/browser/dom_storage/dom_storage_context_impl_unittest.cc
@@ -7,9 +7,9 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "build/build_config.h" @@ -58,7 +58,7 @@ } protected: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; base::ScopedTempDir temp_dir_; scoped_refptr<MockSpecialStoragePolicy> storage_policy_; scoped_refptr<MockDOMStorageTaskRunner> task_runner_;
diff --git a/content/browser/fileapi/file_system_manager_impl.cc b/content/browser/fileapi/file_system_manager_impl.cc index 9a9d1839..29f1d2d 100644 --- a/content/browser/fileapi/file_system_manager_impl.cc +++ b/content/browser/fileapi/file_system_manager_impl.cc
@@ -123,9 +123,11 @@ FileSystemManagerImpl::FileSystemManagerImpl( int process_id, + int frame_id, storage::FileSystemContext* file_system_context, scoped_refptr<ChromeBlobStorageContext> blob_storage_context) : process_id_(process_id), + frame_id_(frame_id), context_(file_system_context), security_policy_(ChildProcessSecurityPolicyImpl::GetInstance()), blob_storage_context_(blob_storage_context), @@ -590,8 +592,7 @@ std::move(callback).Run(base::File::FILE_OK, std::move(writer)); } -void FileSystemManagerImpl::ChooseEntry(int32_t render_frame_id, - ChooseEntryCallback callback) { +void FileSystemManagerImpl::ChooseEntry(ChooseEntryCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!base::FeatureList::IsEnabled(blink::features::kWritableFilesAPI)) { bindings_.ReportBadMessage("FSMI_WRITABLE_FILES_DISABLED"); @@ -601,7 +602,7 @@ base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, base::BindOnce( - &FileSystemChooser::CreateAndShow, process_id_, render_frame_id, + &FileSystemChooser::CreateAndShow, process_id_, frame_id_, std::move(callback), base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}))); }
diff --git a/content/browser/fileapi/file_system_manager_impl.h b/content/browser/fileapi/file_system_manager_impl.h index f5e4cbf..e92c5e46 100644 --- a/content/browser/fileapi/file_system_manager_impl.h +++ b/content/browser/fileapi/file_system_manager_impl.h
@@ -57,9 +57,12 @@ class CONTENT_EXPORT FileSystemManagerImpl : public blink::mojom::FileSystemManager { public: - // Used by the renderer process host on the UI thread. + // Constructed and held by the render frame host and render process host on + // the UI thread. Used by render frames (via the render frame host), workers + // and pepper (via the render process host). FileSystemManagerImpl( int process_id, + int frame_id, storage::FileSystemContext* file_system_context, scoped_refptr<ChromeBlobStorageContext> blob_storage_context); ~FileSystemManagerImpl() override; @@ -122,8 +125,7 @@ GetPlatformPathCallback callback) override; void CreateWriter(const GURL& file_path, CreateWriterCallback callback) override; - void ChooseEntry(int32_t render_frame_id, - ChooseEntryCallback callback) override; + void ChooseEntry(ChooseEntryCallback callback) override; private: class FileSystemCancellableOperationImpl; @@ -206,6 +208,7 @@ void OnConnectionErrorForOpListeners(OperationListenerID listener_id); const int process_id_; + const int frame_id_; storage::FileSystemContext* const context_; ChildProcessSecurityPolicyImpl* const security_policy_; const scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index f79e26d..46e6a4a 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -40,6 +40,7 @@ #include "content/browser/dom_storage/dom_storage_context_wrapper.h" #include "content/browser/download/mhtml_generation_manager.h" #include "content/browser/file_url_loader_factory.h" +#include "content/browser/fileapi/file_system_manager_impl.h" #include "content/browser/fileapi/file_system_url_loader_factory.h" #include "content/browser/frame_host/cross_process_frame_connector.h" #include "content/browser/frame_host/debug_urls.h" @@ -3753,6 +3754,15 @@ GetProcess()->GetID(), routing_id_), base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})); + file_system_manager_.reset(new FileSystemManagerImpl( + GetProcess()->GetID(), routing_id_, + GetProcess()->GetStoragePartition()->GetFileSystemContext(), + ChromeBlobStorageContext::GetFor(GetProcess()->GetBrowserContext()))); + registry_->AddInterface( + base::BindRepeating(&FileSystemManagerImpl::BindRequest, + base::Unretained(file_system_manager_.get())), + base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})); + if (Portal::IsEnabled()) { registry_->AddInterface(base::BindRepeating(IgnoreResult(&Portal::Create), base::Unretained(this)));
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 9e5d027..00563fa 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1626,6 +1626,10 @@ // Hosts blink::mojom::PresentationService for the RenderFrame. std::unique_ptr<PresentationServiceImpl> presentation_service_; + // Hosts blink::mojom::FileSystemManager for the RenderFrame. + std::unique_ptr<FileSystemManagerImpl, BrowserThread::DeleteOnIOThread> + file_system_manager_; + #if !defined(OS_ANDROID) std::unique_ptr<AuthenticatorImpl> authenticator_impl_; #endif
diff --git a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc index 6a081f3..6dac8e9 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
@@ -6,8 +6,8 @@ #include "base/command_line.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/time/time.h" #include "build/build_config.h" #include "content/browser/gpu/gpu_data_manager_impl_private.h" @@ -103,7 +103,7 @@ void TestBlockingDomainFrom3DAPIs(gpu::DomainGuilt guilt_level); void TestUnblockingDomainFrom3DAPIs(gpu::DomainGuilt guilt_level); - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; }; // We use new method instead of GetInstance() method because we want
diff --git a/content/browser/host_zoom_map_impl_unittest.cc b/content/browser/host_zoom_map_impl_unittest.cc index c66769201..0e0d2fc 100644 --- a/content/browser/host_zoom_map_impl_unittest.cc +++ b/content/browser/host_zoom_map_impl_unittest.cc
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread.h" @@ -18,11 +18,12 @@ class HostZoomMapTest : public testing::Test { public: - HostZoomMapTest() : ui_thread_(BrowserThread::UI, &message_loop_) { - } + HostZoomMapTest() + : ui_thread_(BrowserThread::UI, + task_environment_.GetMainThreadTaskRunner()) {} protected: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; TestBrowserThread ui_thread_; };
diff --git a/content/browser/loader/throttling_resource_handler_unittest.cc b/content/browser/loader/throttling_resource_handler_unittest.cc index 838a6b73..0e6dbf7e4 100644 --- a/content/browser/loader/throttling_resource_handler_unittest.cc +++ b/content/browser/loader/throttling_resource_handler_unittest.cc
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/browser/loader/mock_resource_loader.h" #include "content/browser/loader/resource_request_info_impl.h" #include "content/browser/loader/test_resource_handler.h" @@ -176,7 +176,9 @@ class ThrottlingResourceHandlerTest : public testing::Test { public: ThrottlingResourceHandlerTest() - : never_started_url_request_( + : task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO), + never_started_url_request_( request_context_.CreateRequest(GURL(kInitialUrl), net::DEFAULT_PRIORITY, &never_started_url_request_delegate_, @@ -222,7 +224,7 @@ protected: // Needs to be first, so it's destroyed last. - base::MessageLoopForIO message_loop_; + base::test::ScopedTaskEnvironment task_environment_; // Machinery to construct a URLRequest that's just used as an argument to // methods that expect one, and is never actually started.
diff --git a/content/browser/media/forwarding_audio_stream_factory_unittest.cc b/content/browser/media/forwarding_audio_stream_factory_unittest.cc index 80033c51..0fcc2ce6 100644 --- a/content/browser/media/forwarding_audio_stream_factory_unittest.cc +++ b/content/browser/media/forwarding_audio_stream_factory_unittest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/macros.h" +#include "base/run_loop.h" #include "base/test/mock_callback.h" #include "base/unguessable_token.h" #include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
diff --git a/content/browser/media/midi_host_unittest.cc b/content/browser/media/midi_host_unittest.cc index 869ea97..8840648 100644 --- a/content/browser/media/midi_host_unittest.cc +++ b/content/browser/media/midi_host_unittest.cc
@@ -9,9 +9,9 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/test/scoped_task_environment.h" #include "content/common/media/midi_messages.h" #include "content/public/test/test_browser_thread.h" #include "media/midi/midi_manager.h" @@ -118,7 +118,8 @@ class MidiHostTest : public testing::Test { public: MidiHostTest() - : io_browser_thread_(BrowserThread::IO, &message_loop_), + : io_browser_thread_(BrowserThread::IO, + task_environment_.GetMainThreadTaskRunner()), data_(kNoteOn, kNoteOn + arraysize(kNoteOn)), port_id_(0) { std::unique_ptr<FakeMidiManagerFactory> factory = @@ -173,7 +174,7 @@ } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; TestBrowserThread io_browser_thread_; std::vector<uint8_t> data_;
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc index a1ebb099..c101d5f 100644 --- a/content/browser/navigation_browsertest.cc +++ b/content/browser/navigation_browsertest.cc
@@ -9,7 +9,6 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" -#include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "content/browser/child_process_security_policy_impl.h" @@ -26,7 +25,6 @@ #include "content/public/browser/download_manager_delegate.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_types.h" -#include "content/public/browser/site_isolation_policy.h" #include "content/public/browser/web_contents.h" #include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/content_features.h" @@ -165,29 +163,6 @@ DISALLOW_COPY_AND_ASSIGN(BrowserMessageObserver); }; -// Execute a callback whenever an observed IPC is received -class BrowserMessageCallback : public content::BrowserMessageFilter { - public: - BrowserMessageCallback(uint32_t observed_message_class, - uint32_t observed_message_type, - base::RepeatingClosure callback) - : content::BrowserMessageFilter(observed_message_class), - observed_message_type_(observed_message_type), - callback_(callback) {} - - bool OnMessageReceived(const IPC::Message& message) override { - if (message.type() == observed_message_type_) - callback_.Run(); - return false; - } - - private: - ~BrowserMessageCallback() override {} - uint32_t observed_message_type_; - base::RepeatingClosure callback_; - DISALLOW_COPY_AND_ASSIGN(BrowserMessageCallback); -}; - } // namespace // Test about navigation. @@ -1243,104 +1218,4 @@ EXPECT_FALSE(navigation.was_successful()); } -// Ensure the renderer process doesn't send too much IPC to the browser process -// when history.pushState() and history.back() are called in a loop. -// Failing to do so causes the browser to freeze. -// See https://crbug.com/882238 -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, IPCFlood_GoToEntryAtOffset) { - GURL url(embedded_test_server()->GetURL("/title1.html")); - NavigateToURL(shell(), url); - - // Count the maximum number of GoToEntryAtOffset IPC the renderer process - // autorizes itself to send. - int count_history_back = 0; - auto observer_history_back = base::MakeRefCounted<BrowserMessageCallback>( - ViewMsgStart, ViewHostMsg_GoToEntryAtOffset::ID, - base::BindLambdaForTesting([&]() { ++count_history_back; })); - int count_replace_state = 0; - auto observer_push_state = base::MakeRefCounted<BrowserMessageCallback>( - FrameMsgStart, FrameHostMsg_UpdateState::ID, - base::BindLambdaForTesting([&]() { ++count_replace_state; })); - - RenderProcessHost* process = - static_cast<RenderFrameHostImpl*>(shell()->web_contents()->GetMainFrame()) - ->GetProcess(); - process->AddFilter(observer_push_state.get()); - process->AddFilter(observer_history_back.get()); - - EXPECT_TRUE(ExecuteScript(shell(), R"( - var start = new Date().getTime(); - while(new Date().getTime() < start + 2000) { - history.pushState({},"page 2", "bar.html"); - history.back(); - } - )")); - - // The quota is shared in between history.back() and history.pushState(). - EXPECT_EQ(100, count_history_back); - EXPECT_EQ(100, count_replace_state); -} - -// Ensure the renderer process doesn't send too much IPC to the browser process -// when doing a same-document navigation is requested in a loop. -// Failing to do so causes the browser to freeze. -// See https://crbug.com/882238 -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, IPCFlood_NavigationLocal) { - GURL url(embedded_test_server()->GetURL("/title1.html")); - NavigateToURL(shell(), url); - - NavigationRecorder recorder(shell()->web_contents()); - - EXPECT_TRUE(ExecuteScript(shell(), R"( - var start = new Date().getTime(); - let i = 0; - while(new Date().getTime() < start + 2000) { - location.href = "#" + i; - ++i; - } - )")); - - // For each IPC, DidStartNavigation and DidFinishNavigation are recorded, so - // twice the quota is recorded. - EXPECT_EQ(400u, recorder.records().size()); -} - -// Ensure the renderer process doesn't send too much IPC to the browser process -// when a frame request another one in a different process to navigate. -// Failing to do so causes the browser to freeze. -// See https://crbug.com/882238 -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, IPCFlood_NavigationRemote) { - GURL url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b)")); - GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html")); - NavigateToURL(shell(), url); - - // This test assumes A and B are not sharing the same process. This requires - // site isolation to be enabled. - if (!SiteIsolationPolicy::AreIsolatedOriginsEnabled()) - return; - - // Count the maximum number of GoToEntryAtOffset IPC the renderer process - // autorizes itself to send. - int count = 0; - auto increment_count = - base::BindRepeating([](int* count) { (*count)++; }, &count); - auto observer = base::MakeRefCounted<BrowserMessageCallback>( - FrameMsgStart, FrameHostMsg_OpenURL::ID, increment_count); - static_cast<RenderFrameHostImpl*>(shell()->web_contents()->GetMainFrame()) - ->GetProcess() - ->AddFilter(observer.get()); - - EXPECT_TRUE(ExecuteScript(shell(), R"( - let iframe = document.querySelector("iframe"); - let initial_url = iframe.src; - var start = new Date().getTime(); - while(new Date().getTime() < start + 2000) { - iframe.src = initial_url; - } - )")); - - EXPECT_EQ(200, count); -} - } // namespace content
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc index 02cc5ed..6bd0018 100644 --- a/content/browser/network_service_restart_browsertest.cc +++ b/content/browser/network_service_restart_browsertest.cc
@@ -811,12 +811,8 @@ service_worker_context->RemoveObserver(&observer); } -// Make sure fetch from shared worker context works after crash. -// -// Disabled since shared workers don't support recovery from a NS crash: -// https://crbug.com/848256. -IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, - DISABLED_SharedWorkerFetch) { +// Make sure shared workers terminate after crash. +IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, SharedWorker) { StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( BrowserContext::GetDefaultStoragePartition(browser_context())); @@ -827,19 +823,23 @@ // Navigate to the page and prepare a shared worker. EXPECT_TRUE(NavigateToURL(shell(), page_url)); - // Fetch from the shared worker. + // Fetch from the shared worker to ensure it has started. const std::string script = "fetch_from_shared_worker('" + fetch_url.spec() + "');"; EXPECT_EQ("Echo", EvalJs(shell(), script)); - // Crash the NetworkService process. Existing interfaces should receive error - // notifications at some point. - SimulateNetworkServiceCrash(); - // Flush the interface to make sure the error notification was received. - partition->FlushNetworkInterfaceForTesting(); + // There should be one worker host. We will later wait for it to terminate. + SharedWorkerServiceImpl* service = partition->GetSharedWorkerService(); + EXPECT_EQ(1u, service->worker_hosts_.size()); + base::RunLoop loop; + service->SetWorkerTerminationCallbackForTesting(loop.QuitClosure()); - // Fetch from the shared worker again. - EXPECT_EQ("Echo", EvalJs(shell(), script)); + // Crash the NetworkService process. + SimulateNetworkServiceCrash(); + + // Wait for the worker to detect the crash and self-terminate. + loop.Run(); + EXPECT_TRUE(service->worker_hosts_.empty()); } // Make sure the entry in |NetworkService::GetTotalNetworkUsages()| was cleared
diff --git a/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc b/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc index 71073a5..045779e3 100644 --- a/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc +++ b/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc
@@ -8,8 +8,8 @@ #include <utility> #include <vector> -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/host/host_frame_sink_manager.h" @@ -141,7 +141,7 @@ private: // A MessageLoop is required for mojo bindings which are used to // connect to graphics services. - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; viz::ServerSharedBitmapManager shared_bitmap_manager_; viz::FakeHostFrameSinkClient host_frame_sink_client_; std::unique_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_;
diff --git a/content/browser/renderer_host/input/synthetic_gesture.cc b/content/browser/renderer_host/input/synthetic_gesture.cc index fd09c2a..f5ba649b 100644 --- a/content/browser/renderer_host/input/synthetic_gesture.cc +++ b/content/browser/renderer_host/input/synthetic_gesture.cc
@@ -52,4 +52,8 @@ } } +bool SyntheticGesture::AllowHighFrequencyDispatch() const { + return true; +} + } // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture.h b/content/browser/renderer_host/input/synthetic_gesture.h index 90d4990..6f5d33057 100644 --- a/content/browser/renderer_host/input/synthetic_gesture.h +++ b/content/browser/renderer_host/input/synthetic_gesture.h
@@ -51,6 +51,12 @@ virtual Result ForwardInputEvents( const base::TimeTicks& timestamp, SyntheticGestureTarget* target) = 0; + // Returns whether the gesture events can be dispatched at high frequency + // (e.g. at 120Hz), instead of the regular frequence (at 60Hz). Some gesture + // interact differently depending on how long they take (e.g. the TAP gesture + // generates a click only if its duration is longer than a threshold). + virtual bool AllowHighFrequencyDispatch() const; + protected: DISALLOW_COPY_AND_ASSIGN(SyntheticGesture); };
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller.cc b/content/browser/renderer_host/input/synthetic_gesture_controller.cc index 44308e0..eef8cd0 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_controller.cc +++ b/content/browser/renderer_host/input/synthetic_gesture_controller.cc
@@ -40,11 +40,10 @@ StartGesture(*pending_gesture_queue_.FrontGesture()); } -void SyntheticGestureController::StartTimer() { - // TODO(sad): Change the interval to allow sending multiple events per begin - // frame. +void SyntheticGestureController::StartTimer(bool high_frequency) { dispatch_timer_.Start( - FROM_HERE, base::TimeDelta::FromMicroseconds(16666), + FROM_HERE, + base::TimeDelta::FromMicroseconds(high_frequency ? 8333 : 16666), base::BindRepeating( [](base::WeakPtr<SyntheticGestureController> weak_ptr) { if (weak_ptr) @@ -90,7 +89,7 @@ "SyntheticGestureController::running", &gesture); if (!dispatch_timer_.IsRunning()) - StartTimer(); + StartTimer(gesture.AllowHighFrequencyDispatch()); } void SyntheticGestureController::StopGesture(
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller.h b/content/browser/renderer_host/input/synthetic_gesture_controller.h index 085fdc353f..dcc3b8e 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_controller.h +++ b/content/browser/renderer_host/input/synthetic_gesture_controller.h
@@ -52,7 +52,7 @@ private: friend class SyntheticGestureControllerTestBase; - void StartTimer(); + void StartTimer(bool high_frequency); void StartGesture(const SyntheticGesture& gesture); void StopGesture(const SyntheticGesture& gesture, OnGestureCompleteCallback completion_callback,
diff --git a/content/browser/renderer_host/input/synthetic_pointer_action.cc b/content/browser/renderer_host/input/synthetic_pointer_action.cc index 742087c..9e889da 100644 --- a/content/browser/renderer_host/input/synthetic_pointer_action.cc +++ b/content/browser/renderer_host/input/synthetic_pointer_action.cc
@@ -47,6 +47,10 @@ : SyntheticGesture::GESTURE_RUNNING; } +bool SyntheticPointerAction::AllowHighFrequencyDispatch() const { + return false; +} + SyntheticPointerAction::GestureState SyntheticPointerAction::ForwardTouchOrMouseInputEvents( const base::TimeTicks& timestamp,
diff --git a/content/browser/renderer_host/input/synthetic_pointer_action.h b/content/browser/renderer_host/input/synthetic_pointer_action.h index 39b3656..e836a08 100644 --- a/content/browser/renderer_host/input/synthetic_pointer_action.h +++ b/content/browser/renderer_host/input/synthetic_pointer_action.h
@@ -24,6 +24,7 @@ SyntheticGesture::Result ForwardInputEvents( const base::TimeTicks& timestamp, SyntheticGestureTarget* target) override; + bool AllowHighFrequencyDispatch() const override; private: enum GestureState { UNINITIALIZED, RUNNING, INVALID, DONE };
diff --git a/content/browser/renderer_host/input/synthetic_tap_gesture.cc b/content/browser/renderer_host/input/synthetic_tap_gesture.cc index 80503e5..54b70a02 100644 --- a/content/browser/renderer_host/input/synthetic_tap_gesture.cc +++ b/content/browser/renderer_host/input/synthetic_tap_gesture.cc
@@ -46,6 +46,10 @@ : SyntheticGesture::GESTURE_RUNNING; } +bool SyntheticTapGesture::AllowHighFrequencyDispatch() const { + return false; +} + void SyntheticTapGesture::ForwardTouchOrMouseInputEvents( const base::TimeTicks& timestamp, SyntheticGestureTarget* target) { switch (state_) {
diff --git a/content/browser/renderer_host/input/synthetic_tap_gesture.h b/content/browser/renderer_host/input/synthetic_tap_gesture.h index 03d4f47..b3d2bfc 100644 --- a/content/browser/renderer_host/input/synthetic_tap_gesture.h +++ b/content/browser/renderer_host/input/synthetic_tap_gesture.h
@@ -22,6 +22,7 @@ SyntheticGesture::Result ForwardInputEvents( const base::TimeTicks& timestamp, SyntheticGestureTarget* target) override; + bool AllowHighFrequencyDispatch() const override; private: enum GestureState {
diff --git a/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc b/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc index a843d53..2f09cdb 100644 --- a/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc +++ b/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc
@@ -9,10 +9,10 @@ #include "base/bind.h" #include "base/memory/read_only_shared_memory_region.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/sync_socket.h" #include "base/test/mock_callback.h" +#include "base/test/scoped_task_environment.h" #include "media/audio/audio_input_delegate.h" #include "mojo/public/cpp/bindings/binding.h" #include "testing/gmock/include/gmock/gmock.h" @@ -122,7 +122,7 @@ } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; StrictMock<MockRendererAudioInputStreamFactoryClient> client_; mojom::RendererAudioInputStreamFactoryClientPtr client_ptr_; mojo::Binding<mojom::RendererAudioInputStreamFactoryClient> client_binding_;
diff --git a/content/browser/renderer_host/media/media_devices_manager.h b/content/browser/renderer_host/media/media_devices_manager.h index 7ba5aff..2a4b6cf 100644 --- a/content/browser/renderer_host/media/media_devices_manager.h +++ b/content/browser/renderer_host/media/media_devices_manager.h
@@ -15,7 +15,7 @@ #include "base/containers/flat_map.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "content/browser/media/media_devices_util.h" #include "content/common/content_export.h" #include "content/common/media/media_devices.h"
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index a1cd9c20..a9677e7b 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -16,7 +16,7 @@ #include "base/containers/queue.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/browser/renderer_host/media/audio_input_device_manager.h"
diff --git a/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc b/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc index 6088425..80175b1 100644 --- a/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
@@ -17,7 +17,7 @@ #include "base/bind.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "content/browser/renderer_host/media/video_capture_controller.h" #include "media/base/video_frame.h" @@ -93,7 +93,7 @@ new Buffer(pool_, std::move(buffer_handle), buffer_id)); } - base::MessageLoop loop_; + base::test::ScopedTaskEnvironment task_environment_; int expected_dropped_id_; scoped_refptr<media::VideoCaptureBufferPool> pool_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index cc7f561e..6da5e15 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2045,6 +2045,16 @@ origin)); } +void RenderProcessHostImpl::BindFileSystemManager( + blink::mojom::FileSystemManagerRequest request) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&FileSystemManagerImpl::BindRequest, + base::Unretained(file_system_manager_impl_.get()), + std::move(request))); +} + void RenderProcessHostImpl::CancelProcessShutdownDelayForUnload() { if (IsKeepAliveRefCountDisabled()) return; @@ -2160,8 +2170,14 @@ base::Unretained(push_messaging_manager_.get()))); file_system_manager_impl_.reset(new FileSystemManagerImpl( - GetID(), storage_partition_impl_->GetFileSystemContext(), + GetID(), MSG_ROUTING_NONE, + storage_partition_impl_->GetFileSystemContext(), ChromeBlobStorageContext::GetFor(GetBrowserContext()))); + // This interface is still exposed by the RenderProcessHost's registry so + // that it can be accessed by PepperFileSystemHost. Blink accesses this + // interface through RenderFrameHost/RendererInterfaceBinders. + // TODO(https://crbug.com/873661): Make PepperFileSystemHost access this with + // the RenderFrameHost's registry, and remove this registration. registry->AddInterface( base::BindRepeating(&FileSystemManagerImpl::BindRequest, base::Unretained(file_system_manager_impl_.get())));
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index bd316ca5..0f102fe3 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -59,6 +59,7 @@ #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom.h" #include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.h" +#include "third_party/blink/public/mojom/filesystem/file_system.mojom.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gl/gpu_switching_observer.h" @@ -448,6 +449,9 @@ // before the process shuts down. void DelayProcessShutdownForUnload(const base::TimeDelta& timeout); + // Binds request to the FileSystemManager instance owned by the render process + // host, and is used by workers via RendererInterfaceBinders. + void BindFileSystemManager(blink::mojom::FileSystemManagerRequest request); FileSystemManagerImpl* GetFileSystemManagerForTesting() { return file_system_manager_impl_.get(); }
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index c7d29b7..9442799 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -458,8 +458,7 @@ prefs.history_entry_requires_user_gesture = command_line.HasSwitch(switches::kHistoryEntryRequiresUserGesture); - prefs.disable_ipc_flooding_protection = - command_line.HasSwitch(switches::kDisableIpcFloodingProtection) || + prefs.disable_pushstate_throttle = command_line.HasSwitch(switches::kDisablePushStateThrottle); #if defined(OS_ANDROID)
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h index 477dcc3..88340958 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.h +++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -58,7 +58,9 @@ public: // Functions for controlling the browser top controls slide behavior with page // gesture scrolling. - virtual void SetTopControlsShownRatio(float ratio) {} + virtual void SetTopControlsShownRatio( + RenderWidgetHostImpl* render_widget_host, + float ratio) {} virtual bool DoBrowserControlsShrinkRendererSize() const; virtual int GetTopControlsHeight() const; virtual void SetTopControlsGestureScrollInProgress(bool in_progress) {}
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index b2857d6..f141b8e 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2670,7 +2670,7 @@ } void RenderWidgetHostImpl::WindowSnapshotReachedScreen(int snapshot_id) { - DCHECK(base::MessageLoopForUI::IsCurrent()); + DCHECK(base::MessageLoopCurrentForUI::IsSet()); if (!pending_surface_browser_snapshots_.empty()) { GetView()->CopyFromSurface(
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 eeb43e8..7d4ada0 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2116,7 +2116,7 @@ if (host()->delegate()) { host()->delegate()->SetTopControlsShownRatio( - metadata.top_controls_shown_ratio); + host(), metadata.top_controls_shown_ratio); } SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm index 26c6b9e..f27cb7c6 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -9,7 +9,7 @@ #include <stdint.h> #include "base/mac/scoped_nsautorelease_pool.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "content/browser/compositor/test/test_image_transport_factory.h" #include "content/browser/gpu/compositor_util.h" @@ -104,7 +104,7 @@ void TearDown() override { ImageTransportFactory::Terminate(); } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; }; class RenderWidgetHostViewMacEditCommandHelperWithTaskEnvTest
diff --git a/content/browser/renderer_interface_binders.cc b/content/browser/renderer_interface_binders.cc index c3a8bdc..f017a37 100644 --- a/content/browser/renderer_interface_binders.cc +++ b/content/browser/renderer_interface_binders.cc
@@ -149,6 +149,13 @@ static_cast<RenderProcessHostImpl*>(host)->BindCacheStorage( std::move(request), origin); })); + // TODO(https://crbug.com/873661): Pass origin to FileSystemMananger. + parameterized_binder_registry_.AddInterface(base::BindRepeating( + [](blink::mojom::FileSystemManagerRequest request, + RenderProcessHost* host, const url::Origin& origin) { + static_cast<RenderProcessHostImpl*>(host)->BindFileSystemManager( + std::move(request)); + })); parameterized_binder_registry_.AddInterface( base::Bind([](blink::mojom::PermissionServiceRequest request, RenderProcessHost* host, const url::Origin& origin) {
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index 26a57ea0..078dc4f 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -2262,6 +2262,43 @@ EXPECT_EQ(1, GetRequestCount(kPageUrl)); } +IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, + GetLargeResponseText) { + const char kPageUrl[] = "/service_worker/navigation_preload.html"; + const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; + std::string title = "<title>PASS</title>"; + // A large body that exceeds the default size of a mojo::DataPipe. + constexpr size_t kBodySize = 128 * 1024; + // Randomly generate the body data + int index = 0; + std::string body; + for (size_t i = 0; i < kBodySize; ++i) { + body += static_cast<char>(index + 'a'); + index = (37 * index + 11) % 26; + } + const std::string kScript = + kEnableNavigationPreloadScript + + "self.addEventListener('fetch', event => {\n" + " event.respondWith(\n" + " event.preloadResponse\n" + " .then(response => response.text())\n" + " .then(text =>\n" + " new Response(\n" + " text,\n" + " {headers: [['content-type', 'text/html']]})));\n" + " });"; + const GURL page_url = embedded_test_server()->GetURL(kPageUrl); + const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); + RegisterStaticFile(kPageUrl, title + body, "text/html"); + RegisterStaticFile(kWorkerUrl, kScript, "text/javascript"); + + EXPECT_EQ(body, LoadNavigationPreloadTestPage(page_url, worker_url, "PASS")); + + // The page request must be sent only once, since the worker responded with + // "Hello world". + EXPECT_EQ(1, GetRequestCount(kPageUrl)); +} + IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, NetworkError) { const char kPageUrl[] = "/service_worker/navigation_preload.html"; const char kWorkerUrl[] = "/service_worker/navigation_preload.js";
diff --git a/content/browser/shareable_file_reference_unittest.cc b/content/browser/shareable_file_reference_unittest.cc index 5003f6c..d2ec24e 100644 --- a/content/browser/shareable_file_reference_unittest.cc +++ b/content/browser/shareable_file_reference_unittest.cc
@@ -6,9 +6,9 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -17,7 +17,7 @@ namespace content { TEST(ShareableFileReferenceTest, TestReferences) { - base::MessageLoop message_loop; + base::test::ScopedTaskEnvironment task_environment; scoped_refptr<base::SingleThreadTaskRunner> task_runner = base::ThreadTaskRunnerHandle::Get(); base::ScopedTempDir temp_dir;
diff --git a/content/browser/shared_worker/shared_worker_host.cc b/content/browser/shared_worker/shared_worker_host.cc index 9ae8040..7715dd77 100644 --- a/content/browser/shared_worker/shared_worker_host.cc +++ b/content/browser/shared_worker/shared_worker_host.cc
@@ -292,7 +292,9 @@ } // This is similar to -// RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryAndObserve. +// RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryAndObserve, but this +// host doesn't observe network service crashes. Instead, the renderer detects +// the connection error and terminates the worker. void SharedWorkerHost::CreateNetworkFactory( network::mojom::URLLoaderFactoryRequest request) { network::mojom::URLLoaderFactoryParamsPtr params = @@ -303,9 +305,6 @@ service_->storage_partition()->GetNetworkContext()->CreateURLLoaderFactory( std::move(request), std::move(params)); - - // TODO(crbug.com/848256): Detect connection error and send a IPC with a new - // network factory like UpdateSubresourceLoaderFactories does for frames. } void SharedWorkerHost::AllowFileSystem(
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc index 00b3d6b..04d191312 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.cc +++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -297,6 +297,12 @@ } } +void SharedWorkerServiceImpl::SetWorkerTerminationCallbackForTesting( + base::OnceClosure callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + terminate_all_workers_callback_ = std::move(callback); +} + void SharedWorkerServiceImpl::ConnectToWorker( int process_id, int frame_id, @@ -363,7 +369,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); worker_hosts_.erase(worker_hosts_.find(host)); - // Complete the call to TerminateAllWorkersForTesting if no more workers. + // Run the termination callback if no more workers. if (worker_hosts_.empty() && terminate_all_workers_callback_) std::move(terminate_all_workers_callback_).Run(); }
diff --git a/content/browser/shared_worker/shared_worker_service_impl.h b/content/browser/shared_worker/shared_worker_service_impl.h index ea570170..1433f18 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.h +++ b/content/browser/shared_worker/shared_worker_service_impl.h
@@ -54,6 +54,7 @@ const url::Origin& constructor_origin) override; void TerminateAllWorkersForTesting(base::OnceClosure callback); + void SetWorkerTerminationCallbackForTesting(base::OnceClosure callback); // Creates the worker if necessary or connects to an already existing worker. void ConnectToWorker( @@ -72,6 +73,7 @@ private: friend class SharedWorkerServiceImplTest; friend class SharedWorkerHostTest; + FRIEND_TEST_ALL_PREFIXES(NetworkServiceRestartBrowserTest, SharedWorker); static void AddAdditionalRequestHeaders( network::ResourceRequest* resource_request,
diff --git a/content/browser/speech/speech_recognition_engine_unittest.cc b/content/browser/speech/speech_recognition_engine_unittest.cc index e67d251..3fc7a3b 100644 --- a/content/browser/speech/speech_recognition_engine_unittest.cc +++ b/content/browser/speech/speech_recognition_engine_unittest.cc
@@ -11,10 +11,11 @@ #include "base/big_endian.h" #include "base/containers/queue.h" -#include "base/message_loop/message_loop.h" #include "base/numerics/safe_conversions.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "base/sys_byteorder.h" +#include "base/test/scoped_task_environment.h" #include "content/browser/speech/audio_buffer.h" #include "content/browser/speech/proto/google_streaming_api.pb.h" #include "net/base/net_errors.h" @@ -99,7 +100,7 @@ std::string ConsumeChunkedUploadData(); void CloseMockDownstream(DownstreamError error); - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; network::TestURLLoaderFactory url_loader_factory_; mojo::ScopedDataPipeProducerHandle downstream_data_pipe_;
diff --git a/content/browser/streams/stream_unittest.cc b/content/browser/streams/stream_unittest.cc index a0bcee9..e256944 100644 --- a/content/browser/streams/stream_unittest.cc +++ b/content/browser/streams/stream_unittest.cc
@@ -4,8 +4,8 @@ #include <stddef.h> -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/test/test_simple_task_runner.h" #include "content/browser/streams/stream.h" #include "content/browser/streams/stream_read_observer.h" @@ -36,7 +36,7 @@ } protected: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<StreamRegistry> registry_; private:
diff --git a/content/browser/streams/stream_url_request_job_unittest.cc b/content/browser/streams/stream_url_request_job_unittest.cc index 4bb4e73..6d3cd75d 100644 --- a/content/browser/streams/stream_url_request_job_unittest.cc +++ b/content/browser/streams/stream_url_request_job_unittest.cc
@@ -4,8 +4,8 @@ #include "content/browser/streams/stream_url_request_job.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/test/test_simple_task_runner.h" #include "content/browser/streams/stream.h" #include "content/browser/streams/stream_metadata.h" @@ -55,7 +55,9 @@ StreamRegistry* registry_; }; - StreamURLRequestJobTest() {} + StreamURLRequestJobTest() + : task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO) {} void SetUp() override { registry_.reset(new StreamRegistry()); @@ -107,7 +109,7 @@ } protected: - base::MessageLoopForIO message_loop_; + base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<StreamRegistry> registry_; net::URLRequestContext url_request_context_;
diff --git a/content/browser/tracing/background_tracing_config_unittest.cc b/content/browser/tracing/background_tracing_config_unittest.cc index 12de19f..3d2520c4 100644 --- a/content/browser/tracing/background_tracing_config_unittest.cc +++ b/content/browser/tracing/background_tracing_config_unittest.cc
@@ -6,7 +6,7 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/values.h" #include "content/browser/tracing/background_tracing_config_impl.h" #include "content/browser/tracing/background_tracing_rule.h" @@ -18,10 +18,11 @@ class BackgroundTracingConfigTest : public testing::Test { public: BackgroundTracingConfigTest() - : ui_thread_(BrowserThread::UI, &message_loop_) {} + : ui_thread_(BrowserThread::UI, + task_environment_.GetMainThreadTaskRunner()) {} protected: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; TestBrowserThread ui_thread_; };
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 9cb87f79..a0f8530 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2143,9 +2143,17 @@ return last_committed_source_id_; } -void WebContentsImpl::SetTopControlsShownRatio(float ratio) { - if (delegate_) - delegate_->SetTopControlsShownRatio(this, ratio); +void WebContentsImpl::SetTopControlsShownRatio( + RenderWidgetHostImpl* render_widget_host, + float ratio) { + if (!delegate_) + return; + + RenderFrameHostImpl* rfh = GetMainFrame(); + if (!rfh || render_widget_host != rfh->GetRenderWidgetHost()) + return; + + delegate_->SetTopControlsShownRatio(this, ratio); } bool WebContentsImpl::DoBrowserControlsShrinkRendererSize() const {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index ddde2f7..588a42f6 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -691,7 +691,8 @@ // RenderWidgetHostDelegate -------------------------------------------------- ukm::SourceId GetUkmSourceIdForLastCommittedSource() const override; - void SetTopControlsShownRatio(float ratio) override; + void SetTopControlsShownRatio(RenderWidgetHostImpl* render_widget_host, + float ratio) override; bool DoBrowserControlsShrinkRendererSize() const override; int GetTopControlsHeight() const override; void SetTopControlsGestureScrollInProgress(bool in_progress) override;
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn index c886da7..ac7667c 100644 --- a/content/child/BUILD.gn +++ b/content/child/BUILD.gn
@@ -110,7 +110,7 @@ "//services/device/public/cpp:device_features", "//services/device/public/cpp/power_monitor", "//services/device/public/mojom:constants", - "//services/resource_coordinator/public/cpp:resource_coordinator_cpp", + "//services/resource_coordinator/public/cpp/memory_instrumentation", "//services/service_manager/public/cpp", "//services/service_manager/public/mojom", "//services/service_manager/runner/common",
diff --git a/content/child/memory/child_memory_coordinator_impl_unittest.cc b/content/child/memory/child_memory_coordinator_impl_unittest.cc index 976b67c..842ac14 100644 --- a/content/child/memory/child_memory_coordinator_impl_unittest.cc +++ b/content/child/memory/child_memory_coordinator_impl_unittest.cc
@@ -11,8 +11,8 @@ #include <memory> #include "base/memory/memory_coordinator_client_registry.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" #include "testing/gtest/include/gtest/gtest.h" @@ -44,7 +44,7 @@ public ChildMemoryCoordinatorDelegate { public: ChildMemoryCoordinatorImplTest() - : message_loop_(new base::MessageLoop) { + : task_environment_(new base::test::ScopedTaskEnvironment) { auto parent = coordinator_handle_.Bind(); coordinator_impl_ = CreateChildMemoryCoordinator(std::move(parent), this); // Needs to run loop to initalize mojo pointers including |child_| in @@ -84,7 +84,7 @@ bool on_trim_memory_called_ = false; private: - std::unique_ptr<base::MessageLoop> message_loop_; + std::unique_ptr<base::test::ScopedTaskEnvironment> task_environment_; MockMemoryCoordinatorHandle coordinator_handle_; std::unique_ptr<ChildMemoryCoordinatorImpl> coordinator_impl_;
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index b7a0d6ec..1482d16d 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -503,6 +503,9 @@ WebRuntimeFeatures::EnableJankTracking( base::FeatureList::IsEnabled(blink::features::kJankTracking) || enableExperimentalWebPlatformFeatures); + + WebRuntimeFeatures::EnableNoHoverDuringScroll( + base::FeatureList::IsEnabled(features::kNoHoverDuringScroll)); } } // namespace content
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index c45d6318..52ad94e 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -328,7 +328,7 @@ "//sandbox:sandbox_buildflags", "//services/network/public/cpp", "//services/network/public/mojom", - "//services/resource_coordinator/public/cpp:resource_coordinator_cpp", + "//services/resource_coordinator/public/cpp/memory_instrumentation", "//services/service_manager", "//services/service_manager/embedder", "//services/service_manager/public/cpp",
diff --git a/content/common/service_manager/service_manager_connection_impl_unittest.cc b/content/common/service_manager/service_manager_connection_impl_unittest.cc index ee5c8da..64065b2f 100644 --- a/content/common/service_manager/service_manager_connection_impl_unittest.cc +++ b/content/common/service_manager/service_manager_connection_impl_unittest.cc
@@ -4,8 +4,8 @@ #include "content/common/service_manager/service_manager_connection_impl.h" -#include "base/message_loop/message_loop.h" #include "base/synchronization/waitable_event.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" #include "services/service_manager/public/cpp/identity.h" #include "services/service_manager/public/cpp/service.h" @@ -27,7 +27,7 @@ } // namespace TEST(ServiceManagerConnectionImplTest, ServiceLaunchThreading) { - base::MessageLoop message_loop; + base::test::ScopedTaskEnvironment task_environment; base::Thread io_thread("ServiceManagerConnectionImplTest IO Thread"); io_thread.Start(); service_manager::mojom::ServicePtr service;
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index 60fdaaa..5b2f498 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -164,6 +164,7 @@ "blink.mojom.CredentialManager", "blink.mojom.DisplayCutoutHost", "blink.mojom.DedicatedWorkerFactory", + "blink.mojom.FileSystemManager", "blink.mojom.LockManager", "blink.mojom.GeolocationService", "blink.mojom.InsecureInputService", @@ -229,6 +230,7 @@ "renderer": [ "blink.mojom.CacheStorage", "blink.mojom.DedicatedWorkerFactory", + "blink.mojom.FileSystemManager", "blink.mojom.LockManager", "blink.mojom.NotificationService", "blink.mojom.PermissionService", @@ -265,6 +267,7 @@ "provides": { "renderer": [ "blink.mojom.CacheStorage", + "blink.mojom.FileSystemManager", "blink.mojom.LockManager", "blink.mojom.NotificationService", "blink.mojom.PermissionService",
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index d993bd0..09aa092 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -133,7 +133,7 @@ IPC_STRUCT_TRAITS_MEMBER(application_cache_enabled) IPC_STRUCT_TRAITS_MEMBER(tabs_to_links) IPC_STRUCT_TRAITS_MEMBER(history_entry_requires_user_gesture) - IPC_STRUCT_TRAITS_MEMBER(disable_ipc_flooding_protection) + IPC_STRUCT_TRAITS_MEMBER(disable_pushstate_throttle) IPC_STRUCT_TRAITS_MEMBER(hyperlink_auditing_enabled) IPC_STRUCT_TRAITS_MEMBER(allow_universal_access_from_file_urls) IPC_STRUCT_TRAITS_MEMBER(allow_file_access_from_file_urls)
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 02e5be2..e9f3fcc 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -162,12 +162,6 @@ // many frames. Only effective if compositor image animations are enabled. const char kDisableImageAnimationResync[] = "disable-image-animation-resync"; -// Disables the IPC flooding protection. -// It is activated by default. Some javascript functions can be used to flood -// the browser process with IPC. This protection limits the rate at which they -// can be used. -const char kDisableIpcFloodingProtection[] = "disable-ipc-flooding-protection"; - // Suppresses hang monitor dialogs in renderer processes. This may allow slow // unload handlers on a page to prevent the tab from closing, but the Task // Manager can be used to terminate the offending process in this case.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index bb72c2f..e7f9962 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -58,7 +58,6 @@ extern const char kDisableGpuProcessCrashLimit[]; CONTENT_EXPORT extern const char kDisableGpuWatchdog[]; CONTENT_EXPORT extern const char kDisableImageAnimationResync[]; -CONTENT_EXPORT extern const char kDisableIpcFloodingProtection[]; CONTENT_EXPORT extern const char kDisableJavaScriptHarmonyShipping[]; CONTENT_EXPORT extern const char kDisableLowLatencyDxva[]; CONTENT_EXPORT extern const char kDisableLowResTiling[];
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index 5bede35..581c666 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc
@@ -97,7 +97,7 @@ application_cache_enabled(false), tabs_to_links(true), history_entry_requires_user_gesture(false), - disable_ipc_flooding_protection(false), + disable_pushstate_throttle(false), hyperlink_auditing_enabled(true), allow_universal_access_from_file_urls(false), allow_file_access_from_file_urls(false),
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index 7fefb27b..c1881cb0 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h
@@ -131,7 +131,7 @@ bool application_cache_enabled; bool tabs_to_links; bool history_entry_requires_user_gesture; - bool disable_ipc_flooding_protection; + bool disable_pushstate_throttle; bool hyperlink_auditing_enabled; bool allow_universal_access_from_file_urls; bool allow_file_access_from_file_urls;
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc index 3be3f5a7..a113eab 100644 --- a/content/public/test/content_browser_test.cc +++ b/content/public/test/content_browser_test.cc
@@ -134,7 +134,7 @@ #endif // Pump startup related events. - DCHECK(base::MessageLoopForUI::IsCurrent()); + DCHECK(base::MessageLoopCurrentForUI::IsSet()); base::RunLoop().RunUntilIdle(); #if defined(OS_MACOSX)
diff --git a/content/public/test/test_browser_thread.cc b/content/public/test/test_browser_thread.cc index 78dd3bf..1c8f0ec 100644 --- a/content/public/test/test_browser_thread.cc +++ b/content/public/test/test_browser_thread.cc
@@ -26,10 +26,6 @@ fake_thread_( new BrowserThreadImpl(identifier_, std::move(thread_runner))) {} -TestBrowserThread::TestBrowserThread(BrowserThread::ID identifier, - base::MessageLoop* message_loop) - : TestBrowserThread(identifier, message_loop->task_runner()) {} - TestBrowserThread::~TestBrowserThread() { // The upcoming BrowserThreadImpl::ResetGlobalsForTesting() call requires that // |identifier_| have completed its SHUTDOWN phase.
diff --git a/content/public/test/test_browser_thread.h b/content/public/test/test_browser_thread.h index 8816709b..4c371620 100644 --- a/content/public/test/test_browser_thread.h +++ b/content/public/test/test_browser_thread.h
@@ -13,7 +13,6 @@ #include "content/public/browser/browser_thread.h" namespace base { -class MessageLoop; class Thread; } @@ -36,11 +35,6 @@ TestBrowserThread(BrowserThread::ID identifier, scoped_refptr<base::SingleThreadTaskRunner> thread_runner); - // Deprecated: Forwards |message_loop->task_runner()| to the above - // constructor. - TestBrowserThread(BrowserThread::ID identifier, - base::MessageLoop* message_loop); - ~TestBrowserThread(); // We provide a subset of the capabilities of the Thread interface
diff --git a/content/public/test/test_browser_thread_bundle_unittest.cc b/content/public/test/test_browser_thread_bundle_unittest.cc index 0f5db31..2ffe38f4 100644 --- a/content/public/test/test_browser_thread_bundle_unittest.cc +++ b/content/public/test/test_browser_thread_bundle_unittest.cc
@@ -6,7 +6,6 @@ #include "base/atomicops.h" #include "base/bind_helpers.h" -#include "base/message_loop/message_loop.h" #include "base/task/post_task.h" #include "base/test/scoped_task_environment.h" #include "content/public/browser/browser_task_traits.h" @@ -134,7 +133,8 @@ } TEST(TestBrowserThreadBundleTest, MessageLoopTypeMismatch) { - base::MessageLoopForUI message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::UI); EXPECT_DEATH_IF_SUPPORTED( {
diff --git a/content/public/test/test_renderer_host.cc b/content/public/test/test_renderer_host.cc index 91ff4e9..bc2b6db 100644 --- a/content/public/test/test_renderer_host.cc +++ b/content/public/test/test_renderer_host.cc
@@ -8,6 +8,7 @@ #include "base/message_loop/message_loop_current.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/browser/compositor/test/test_image_transport_factory.h" @@ -147,7 +148,7 @@ // means tests must ensure any MessageLoop they make is created before // the RenderViewHostTestEnabler. if (!base::MessageLoopCurrent::Get()) - message_loop_ = std::make_unique<base::MessageLoop>(); + task_environment_ = std::make_unique<base::test::ScopedTaskEnvironment>(); #if !defined(OS_ANDROID) ImageTransportFactory::SetFactory( std::make_unique<TestImageTransportFactory>());
diff --git a/content/public/test/test_renderer_host.h b/content/public/test/test_renderer_host.h index 7813260..8c7b857 100644 --- a/content/public/test/test_renderer_host.h +++ b/content/public/test/test_renderer_host.h
@@ -12,7 +12,7 @@ #include <vector> #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" @@ -183,7 +183,7 @@ #if defined(OS_ANDROID) std::unique_ptr<display::Screen> screen_; #endif - std::unique_ptr<base::MessageLoop> message_loop_; + std::unique_ptr<base::test::ScopedTaskEnvironment> task_environment_; std::unique_ptr<MockRenderProcessHostFactory> rph_factory_; std::unique_ptr<TestRenderViewHostFactory> rvh_factory_; std::unique_ptr<TestRenderFrameHostFactory> rfh_factory_;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index e93af24..d7b27af79 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -109,10 +109,6 @@ "fetchers/multi_resolution_image_resource_fetcher.h", "fetchers/resource_fetcher_impl.cc", "fetchers/resource_fetcher_impl.h", - "fileapi/file_system_dispatcher.cc", - "fileapi/file_system_dispatcher.h", - "fileapi/webfilesystem_impl.cc", - "fileapi/webfilesystem_impl.h", "frame_blame_context.cc", "frame_blame_context.h", "frame_owner_properties.cc",
diff --git a/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc b/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc index f4d390d..68607d75 100644 --- a/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc +++ b/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc
@@ -9,8 +9,8 @@ #include <memory> #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_task_environment.h" #include "content/renderer/dom_storage/dom_storage_proxy.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/scheduler/test/fake_renderer_scheduler.h" @@ -159,7 +159,8 @@ } protected: - base::MessageLoop message_loop_; // Needed to construct a RendererScheduler. + base::test::ScopedTaskEnvironment + task_environment_; // Needed to construct a RendererScheduler. std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler_; scoped_refptr<MockProxy> mock_proxy_; };
diff --git a/content/renderer/fileapi/OWNERS b/content/renderer/fileapi/OWNERS deleted file mode 100644 index 6269c8b3..0000000 --- a/content/renderer/fileapi/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -file://content/browser/fileapi/OWNERS - -# TEAM: storage-dev@chromium.org -# COMPONENT: Blink>Storage>FileSystem
diff --git a/content/renderer/fileapi/file_system_dispatcher.cc b/content/renderer/fileapi/file_system_dispatcher.cc deleted file mode 100644 index d8cd6a7..0000000 --- a/content/renderer/fileapi/file_system_dispatcher.cc +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/fileapi/file_system_dispatcher.h" - -#include <memory> -#include <utility> - -#include "base/callback.h" -#include "base/files/file_util.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/no_destructor.h" -#include "base/process/process.h" -#include "components/services/filesystem/public/interfaces/types.mojom.h" -#include "content/child/child_thread_impl.h" -#include "content/public/common/service_names.mojom.h" -#include "content/public/renderer/worker_thread.h" -#include "services/service_manager/public/cpp/connector.h" -#include "storage/common/fileapi/file_system_info.h" -#include "storage/common/fileapi/file_system_type_converters.h" - -namespace content { - -FileSystemDispatcher::FileSystemDispatcher( - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) - : main_thread_task_runner_(std::move(main_thread_task_runner)) {} - -FileSystemDispatcher::~FileSystemDispatcher() = default; - -blink::mojom::FileSystemManager& FileSystemDispatcher::GetFileSystemManager() { - auto BindInterfaceOnMainThread = - [](blink::mojom::FileSystemManagerRequest request) { - DCHECK(ChildThreadImpl::current()); - ChildThreadImpl::current()->GetConnector()->BindInterface( - mojom::kBrowserServiceName, std::move(request)); - }; - if (!file_system_manager_ptr_) { - if (WorkerThread::GetCurrentId()) { - blink::mojom::FileSystemManagerRequest request = - mojo::MakeRequest(&file_system_manager_ptr_); - main_thread_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(BindInterfaceOnMainThread, std::move(request))); - } else { - BindInterfaceOnMainThread(mojo::MakeRequest(&file_system_manager_ptr_)); - } - } - return *file_system_manager_ptr_; -} - -void FileSystemDispatcher::ChooseEntry( - int render_frame_id, - std::unique_ptr<ChooseEntryCallbacks> callbacks) { - GetFileSystemManager().ChooseEntry( - render_frame_id, - base::BindOnce( - [](std::unique_ptr<ChooseEntryCallbacks> callbacks, - base::File::Error result, - std::vector<blink::mojom::FileSystemEntryPtr> entries) { - if (result != base::File::FILE_OK) { - callbacks->OnError(result); - } else { - blink::WebVector<blink::WebFileSystem::FileSystemEntry> - web_entries(entries.size()); - for (size_t i = 0; i < entries.size(); ++i) { - web_entries[i].file_system_id = - blink::WebString::FromASCII(entries[i]->file_system_id); - web_entries[i].base_name = - blink::WebString::FromASCII(entries[i]->base_name); - } - callbacks->OnSuccess(std::move(web_entries)); - } - }, - std::move(callbacks))); -} - -} // namespace content
diff --git a/content/renderer/fileapi/file_system_dispatcher.h b/content/renderer/fileapi/file_system_dispatcher.h deleted file mode 100644 index b5df614..0000000 --- a/content/renderer/fileapi/file_system_dispatcher.h +++ /dev/null
@@ -1,44 +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_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_ -#define CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_ - -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/public/mojom/filesystem/file_system.mojom.h" -#include "third_party/blink/public/platform/web_file_system.h" - -namespace base { -class SingleThreadTaskRunner; -} // namespace base - -namespace content { - -// Dispatches and sends file system related messages sent to/from a child -// process from/to the main browser process. There is an instance held by -// each WebFileSystemImpl object. -// TODO(adithyas): Move functionality to blink::FileSystemDispatcher and -// remove this class. -class FileSystemDispatcher { - public: - explicit FileSystemDispatcher( - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); - ~FileSystemDispatcher(); - - using ChooseEntryCallbacks = blink::WebFileSystem::ChooseEntryCallbacks; - void ChooseEntry(int render_frame_id, - std::unique_ptr<ChooseEntryCallbacks> callbacks); - - private: - blink::mojom::FileSystemManager& GetFileSystemManager(); - - blink::mojom::FileSystemManagerPtr file_system_manager_ptr_; - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(FileSystemDispatcher); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
diff --git a/content/renderer/fileapi/webfilesystem_impl.cc b/content/renderer/fileapi/webfilesystem_impl.cc deleted file mode 100644 index b471ad4..0000000 --- a/content/renderer/fileapi/webfilesystem_impl.cc +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/fileapi/webfilesystem_impl.h" - -#include "base/lazy_instance.h" -#include "base/threading/thread_local.h" -#include "base/threading/thread_task_runner_handle.h" -#include "content/public/renderer/render_frame.h" -#include "content/renderer/fileapi/file_system_dispatcher.h" -#include "content/renderer/render_thread_impl.h" -#include "third_party/blink/public/web/web_frame.h" - -namespace content { - -namespace { - -base::LazyInstance<base::ThreadLocalPointer<WebFileSystemImpl>>::Leaky - g_webfilesystem_tls = LAZY_INSTANCE_INITIALIZER; - -enum CallbacksUnregisterMode { - UNREGISTER_CALLBACKS, - DO_NOT_UNREGISTER_CALLBACKS, -}; - -} // namespace - -//----------------------------------------------------------------------------- -// WebFileSystemImpl - -WebFileSystemImpl* WebFileSystemImpl::ThreadSpecificInstance( - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) { - if (g_webfilesystem_tls.Pointer()->Get() || !main_thread_task_runner) - return g_webfilesystem_tls.Pointer()->Get(); - WebFileSystemImpl* filesystem = - new WebFileSystemImpl(std::move(main_thread_task_runner)); - if (WorkerThread::GetCurrentId()) - WorkerThread::AddObserver(filesystem); - return filesystem; -} - -void WebFileSystemImpl::DeleteThreadSpecificInstance() { - DCHECK(!WorkerThread::GetCurrentId()); - if (g_webfilesystem_tls.Pointer()->Get()) - delete g_webfilesystem_tls.Pointer()->Get(); -} - -WebFileSystemImpl::WebFileSystemImpl( - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) - : main_thread_task_runner_(main_thread_task_runner), - file_system_dispatcher_(std::move(main_thread_task_runner)) { - g_webfilesystem_tls.Pointer()->Set(this); -} - -WebFileSystemImpl::~WebFileSystemImpl() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - g_webfilesystem_tls.Pointer()->Set(nullptr); -} - -void WebFileSystemImpl::WillStopCurrentWorkerThread() { - delete this; -} - -void WebFileSystemImpl::ChooseEntry( - blink::WebFrame* frame, - std::unique_ptr<ChooseEntryCallbacks> callbacks) { - file_system_dispatcher_.ChooseEntry( - RenderFrame::GetRoutingIdForWebFrame(frame), std::move(callbacks)); -} - -} // namespace content
diff --git a/content/renderer/fileapi/webfilesystem_impl.h b/content/renderer/fileapi/webfilesystem_impl.h deleted file mode 100644 index a3c2ecf86..0000000 --- a/content/renderer/fileapi/webfilesystem_impl.h +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_ -#define CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_ - -#include "base/memory/ref_counted.h" -#include "base/threading/thread_checker.h" -#include "content/public/renderer/worker_thread.h" -#include "content/renderer/fileapi/file_system_dispatcher.h" -#include "third_party/blink/public/platform/web_file_system.h" - -namespace base { -class SingleThreadTaskRunner; -} - -namespace content { - -// TODO(adithyas): Move functionality to blink::FileSystemDispatcher and remove -// this class. -class WebFileSystemImpl : public blink::WebFileSystem, - public WorkerThread::Observer { - public: - // Returns thread-specific instance. If non-null |main_thread_loop| - // is given and no thread-specific instance has been created it may - // create a new instance. - static WebFileSystemImpl* ThreadSpecificInstance( - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); - - // Deletes thread-specific instance (if exists). For workers it deletes - // itself in WillStopCurrentWorkerThread(), but for an instance created on the - // main thread this method must be called. - static void DeleteThreadSpecificInstance(); - - explicit WebFileSystemImpl( - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); - ~WebFileSystemImpl() override; - - // WorkerThread::Observer implementation. - void WillStopCurrentWorkerThread() override; - - void ChooseEntry(blink::WebFrame* frame, - std::unique_ptr<ChooseEntryCallbacks>) override; - - private: - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; - FileSystemDispatcher file_system_dispatcher_; - - // Thread-affine per use of TLS in impl. - THREAD_CHECKER(thread_checker_); - - DISALLOW_COPY_AND_ASSIGN(WebFileSystemImpl); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_
diff --git a/content/renderer/gpu/layer_tree_view_unittest.cc b/content/renderer/gpu/layer_tree_view_unittest.cc index abc5529..2b48efd 100644 --- a/content/renderer/gpu/layer_tree_view_unittest.cc +++ b/content/renderer/gpu/layer_tree_view_unittest.cc
@@ -8,9 +8,9 @@ #include "base/location.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "cc/test/fake_layer_tree_frame_sink.h" @@ -253,7 +253,7 @@ } protected: - base::MessageLoop ye_olde_message_loope_; + base::test::ScopedTaskEnvironment task_environment_; cc::TestTaskGraphRunner test_task_graph_runner_; blink::scheduler::FakeRendererScheduler fake_renderer_scheduler_; FakeLayerTreeViewDelegate layer_tree_view_delegate_; @@ -328,7 +328,7 @@ // Test that LayerTreeView does not retry FrameSink request while // invisible. - base::MessageLoop message_loop; + base::test::ScopedTaskEnvironment task_environment; cc::TestTaskGraphRunner test_task_graph_runner; blink::scheduler::FakeRendererScheduler fake_renderer_scheduler;
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc index 186292f..a129c4d 100644 --- a/content/renderer/loader/resource_dispatcher_unittest.cc +++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -15,10 +15,10 @@ #include "base/macros.h" #include "base/memory/shared_memory.h" -#include "base/message_loop/message_loop.h" #include "base/process/process_handle.h" #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" +#include "base/test/scoped_task_environment.h" #include "content/common/appcache_interfaces.h" #include "content/public/common/content_features.h" #include "content/public/renderer/fixed_received_data.h" @@ -130,7 +130,7 @@ std::vector<std::pair<network::mojom::URLLoaderRequest, network::mojom::URLLoaderClientPtr>> loader_and_clients_; - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<ResourceDispatcher> dispatcher_; };
diff --git a/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc b/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc index 777deb6c..77f7542b 100644 --- a/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc +++ b/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc
@@ -15,11 +15,11 @@ #include "base/callback.h" #include "base/location.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_split.h" #include "base/task_runner.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "content/public/renderer/fixed_received_data.h" @@ -129,11 +129,12 @@ class ReadDataOperation final { public: typedef WebDataConsumerHandle::Result Result; - ReadDataOperation(std::unique_ptr<SharedMemoryDataConsumerHandle> handle, - base::MessageLoop* main_message_loop, - const base::Closure& on_done) + ReadDataOperation( + std::unique_ptr<SharedMemoryDataConsumerHandle> handle, + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, + const base::Closure& on_done) : handle_(std::move(handle)), - main_message_loop_(main_message_loop), + main_thread_task_runner_(main_thread_task_runner), on_done_(on_done) {} const std::string& result() const { return result_; } @@ -169,14 +170,14 @@ // The operation is done. reader_.reset(); - main_message_loop_->task_runner()->PostTask(FROM_HERE, on_done_); + main_thread_task_runner_->PostTask(FROM_HERE, on_done_); } private: std::unique_ptr<SharedMemoryDataConsumerHandle> handle_; std::unique_ptr<WebDataConsumerHandle::Reader> reader_; std::unique_ptr<WebDataConsumerHandle::Client> client_; - base::MessageLoop* main_message_loop_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; base::Closure on_done_; std::string result_; }; @@ -189,7 +190,7 @@ StrictMock<MockClient> client_; std::unique_ptr<SharedMemoryDataConsumerHandle> handle_; std::unique_ptr<Writer> writer_; - base::MessageLoop loop_; + base::test::ScopedTaskEnvironment task_environment_; }; class SharedMemoryDataConsumerHandleTest @@ -205,7 +206,7 @@ StrictMock<MockClient> client_; std::unique_ptr<SharedMemoryDataConsumerHandle> handle_; std::unique_ptr<Writer> writer_; - base::MessageLoop loop_; + base::test::ScopedTaskEnvironment task_environment_; }; void RunPostedTasks() { @@ -923,7 +924,7 @@ } TEST(SharedMemoryDataConsumerHandleBackpressureTest, Read) { - base::MessageLoop loop; + base::test::ScopedTaskEnvironment task_environment; char buffer[20]; Result result; size_t size; @@ -969,7 +970,7 @@ } TEST(SharedMemoryDataConsumerHandleBackpressureTest, CloseAndReset) { - base::MessageLoop loop; + base::test::ScopedTaskEnvironment task_environment; char buffer[20]; Result result; size_t size; @@ -1017,7 +1018,7 @@ } TEST(SharedMemoryDataConsumerHandleWithoutBackpressureTest, AddData) { - base::MessageLoop loop; + base::test::ScopedTaskEnvironment task_environment; std::unique_ptr<Writer> writer; auto handle = std::make_unique<SharedMemoryDataConsumerHandle>( kDoNotApplyBackpressure, &writer); @@ -1043,7 +1044,8 @@ TEST_F(ThreadedSharedMemoryDataConsumerHandleTest, Read) { base::RunLoop run_loop; auto operation = std::make_unique<ReadDataOperation>( - std::move(handle_), &loop_, run_loop.QuitClosure()); + std::move(handle_), base::ThreadTaskRunnerHandle::Get(), + run_loop.QuitClosure()); scoped_refptr<Logger> logger(new Logger); base::Thread t("DataConsumerHandle test thread");
diff --git a/content/renderer/loader/url_loader_client_impl_unittest.cc b/content/renderer/loader/url_loader_client_impl_unittest.cc index bdb6d90e..42a3691b 100644 --- a/content/renderer/loader/url_loader_client_impl_unittest.cc +++ b/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -5,8 +5,8 @@ #include "content/renderer/loader/url_loader_client_impl.h" #include <vector> -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/renderer/loader/navigation_response_override_parameters.h" #include "content/renderer/loader/resource_dispatcher.h" #include "content/renderer/loader/test_request_peer.h" @@ -76,7 +76,7 @@ return options; } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<ResourceDispatcher> dispatcher_; TestRequestPeer::Context request_peer_context_; int request_id_ = 0;
diff --git a/content/renderer/loader/url_response_body_consumer_unittest.cc b/content/renderer/loader/url_response_body_consumer_unittest.cc index fb32f80..36b002b 100644 --- a/content/renderer/loader/url_response_body_consumer_unittest.cc +++ b/content/renderer/loader/url_response_body_consumer_unittest.cc
@@ -7,9 +7,9 @@ #include "base/bind.h" #include "base/callback_forward.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/test/scoped_task_environment.h" #include "content/public/renderer/request_peer.h" #include "content/renderer/loader/navigation_response_override_parameters.h" #include "content/renderer/loader/request_extra_data.h" @@ -154,7 +154,8 @@ blink::scheduler::GetSingleThreadTaskRunnerForTesting(), TRAFFIC_ANNOTATION_FOR_TESTS, false, false /* pass_response_pipe_to_peer */, - std::make_unique<TestRequestPeer>(context, message_loop_.task_runner()), + std::make_unique<TestRequestPeer>(context, + base::ThreadTaskRunnerHandle::Get()), base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &factory_), std::vector<std::unique_ptr<URLLoaderThrottle>>(), @@ -168,7 +169,7 @@ run_loop.Run(); } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; NoopURLLoaderFactory factory_; std::unique_ptr<ResourceDispatcher> dispatcher_; static const MojoWriteDataFlags kNone = MOJO_WRITE_DATA_FLAG_NONE; @@ -182,7 +183,7 @@ scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), - message_loop_.task_runner())); + base::ThreadTaskRunnerHandle::Get())); consumer->ArmOrNotify(); mojo::ScopedDataPipeProducerHandle writer = @@ -207,7 +208,7 @@ scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), - message_loop_.task_runner())); + base::ThreadTaskRunnerHandle::Get())); consumer->ArmOrNotify(); consumer->OnComplete(network::URLLoaderCompletionStatus()); @@ -242,7 +243,7 @@ scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), - message_loop_.task_runner())); + base::ThreadTaskRunnerHandle::Get())); consumer->ArmOrNotify(); consumer->OnComplete(network::URLLoaderCompletionStatus()); @@ -274,7 +275,7 @@ scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), - message_loop_.task_runner())); + base::ThreadTaskRunnerHandle::Get())); consumer->ArmOrNotify(); network::URLLoaderCompletionStatus status; @@ -317,7 +318,7 @@ scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), - message_loop_.task_runner())); + base::ThreadTaskRunnerHandle::Get())); consumer->ArmOrNotify(); Run(&context);
diff --git a/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc b/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc index 8e4f0a21..da0eb4f 100644 --- a/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc +++ b/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc
@@ -14,10 +14,10 @@ #include "base/bind.h" #include "base/location.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "mojo/public/cpp/system/data_pipe.h" @@ -62,11 +62,12 @@ class ReadDataOperation : public ReadDataOperationBase { public: typedef WebDataConsumerHandle::Result Result; - ReadDataOperation(mojo::ScopedDataPipeConsumerHandle handle, - base::MessageLoop* main_message_loop, - const base::Closure& on_done) + ReadDataOperation( + mojo::ScopedDataPipeConsumerHandle handle, + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, + const base::Closure& on_done) : handle_(new WebDataConsumerHandleImpl(std::move(handle))), - main_message_loop_(main_message_loop), + main_thread_task_runner_(main_thread_task_runner), on_done_(on_done) {} const std::string& result() const { return result_; } @@ -107,14 +108,14 @@ // The operation is done. reader_.reset(); - main_message_loop_->task_runner()->PostTask(FROM_HERE, on_done_); + main_thread_task_runner_->PostTask(FROM_HERE, on_done_); } private: std::unique_ptr<WebDataConsumerHandleImpl> handle_; std::unique_ptr<WebDataConsumerHandle::Reader> reader_; std::unique_ptr<WebDataConsumerHandle::Client> client_; - base::MessageLoop* main_message_loop_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; base::Closure on_done_; std::string result_; }; @@ -122,11 +123,12 @@ class TwoPhaseReadDataOperation : public ReadDataOperationBase { public: typedef WebDataConsumerHandle::Result Result; - TwoPhaseReadDataOperation(mojo::ScopedDataPipeConsumerHandle handle, - base::MessageLoop* main_message_loop, - const base::Closure& on_done) + TwoPhaseReadDataOperation( + mojo::ScopedDataPipeConsumerHandle handle, + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, + const base::Closure& on_done) : handle_(new WebDataConsumerHandleImpl(std::move(handle))), - main_message_loop_(main_message_loop), + main_thread_task_runner_(main_thread_task_runner), on_done_(on_done) {} const std::string& result() const { return result_; } @@ -160,7 +162,7 @@ if (rv != kOk) { // Something is wrong. result_ = "error"; - main_message_loop_->task_runner()->PostTask(FROM_HERE, on_done_); + main_thread_task_runner_->PostTask(FROM_HERE, on_done_); return; } } @@ -177,14 +179,14 @@ // The operation is done. reader_.reset(); - main_message_loop_->task_runner()->PostTask(FROM_HERE, on_done_); + main_thread_task_runner_->PostTask(FROM_HERE, on_done_); } private: std::unique_ptr<WebDataConsumerHandleImpl> handle_; std::unique_ptr<WebDataConsumerHandle::Reader> reader_; std::unique_ptr<WebDataConsumerHandle::Client> client_; - base::MessageLoop* main_message_loop_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; base::Closure on_done_; std::string result_; }; @@ -236,7 +238,7 @@ return expected; } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; mojo::ScopedDataPipeProducerHandle producer_; mojo::ScopedDataPipeConsumerHandle consumer_; @@ -245,7 +247,8 @@ TEST_F(WebDataConsumerHandleImplTest, ReadData) { base::RunLoop run_loop; auto operation = std::make_unique<ReadDataOperation>( - std::move(consumer_), &message_loop_, run_loop.QuitClosure()); + std::move(consumer_), base::ThreadTaskRunnerHandle::Get(), + run_loop.QuitClosure()); base::Thread t("DataConsumerHandle test thread"); ASSERT_TRUE(t.Start()); @@ -266,7 +269,8 @@ TEST_F(WebDataConsumerHandleImplTest, TwoPhaseReadData) { base::RunLoop run_loop; auto operation = std::make_unique<TwoPhaseReadDataOperation>( - std::move(consumer_), &message_loop_, run_loop.QuitClosure()); + std::move(consumer_), base::ThreadTaskRunnerHandle::Get(), + run_loop.QuitClosure()); base::Thread t("DataConsumerHandle test thread"); ASSERT_TRUE(t.Start());
diff --git a/content/renderer/loader/web_url_loader_impl_unittest.cc b/content/renderer/loader/web_url_loader_impl_unittest.cc index 282e2753..5c2d91a 100644 --- a/content/renderer/loader/web_url_loader_impl_unittest.cc +++ b/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -13,9 +13,9 @@ #include "base/command_line.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/test/scoped_task_environment.h" #include "base/time/default_tick_clock.h" #include "base/time/time.h" #include "content/public/common/content_switches.h" @@ -408,10 +408,9 @@ TestWebURLLoaderClient* client() { return client_.get(); } TestResourceDispatcher* dispatcher() { return &dispatcher_; } RequestPeer* peer() { return dispatcher()->peer(); } - base::MessageLoop* message_loop() { return &message_loop_; } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; TestResourceDispatcher dispatcher_; std::unique_ptr<TestWebURLLoaderClient> client_; };
diff --git a/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc b/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc index cefb2a3c..57aa5955 100644 --- a/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc +++ b/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc
@@ -8,8 +8,8 @@ #include <utility> #include <vector> -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" #include "media/audio/audio_output_ipc.h" #include "mojo/public/cpp/bindings/binding.h" @@ -99,7 +99,7 @@ TEST_F(AudioOutputIPCFactoryTest, CallFactoryFromIOThread) { // This test makes sure that AudioOutputIPCFactory correctly binds the // RendererAudioOutputStreamFactoryPtr to the IO thread. - base::MessageLoop message_loop; + base::test::ScopedTaskEnvironment task_environment; base::RunLoop run_loop; auto io_thread = MakeIOThread(); @@ -137,7 +137,7 @@ TEST_F(AudioOutputIPCFactoryTest, SeveralFactories) { // This test simulates having several frames being created and destructed. - base::MessageLoop message_loop; + base::test::ScopedTaskEnvironment task_environment; auto io_thread = MakeIOThread(); const int n_factories = 5; @@ -197,7 +197,7 @@ TEST_F(AudioOutputIPCFactoryTest, RegisterDeregisterBackToBack_Deregisters) { // This test makes sure that calling Register... followed by Deregister... // correctly sequences the registration before the deregistration. - base::MessageLoop message_loop; + base::test::ScopedTaskEnvironment task_environment; auto io_thread = MakeIOThread(); FakeRemoteFactory remote_factory;
diff --git a/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc b/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc index a45f6367..f01899b 100644 --- a/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc +++ b/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc
@@ -9,10 +9,10 @@ #include <string> #include <utility> -#include "base/message_loop/message_loop.h" #include "base/optional.h" #include "base/run_loop.h" #include "base/test/gtest_util.h" +#include "base/test/scoped_task_environment.h" #include "media/audio/audio_device_description.h" #include "media/base/audio_parameters.h" #include "mojo/public/cpp/bindings/binding.h" @@ -132,7 +132,8 @@ } // namespace TEST(MojoAudioInputIPC, OnStreamCreated_Propagates) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; FakeStreamCreator creator(&stream, false); @@ -152,7 +153,8 @@ } TEST(MojoAudioInputIPC, FactoryDisconnected_SendsError) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockDelegate> delegate; const std::unique_ptr<media::AudioInputIPC> ipc = @@ -176,7 +178,8 @@ } TEST(MojoAudioInputIPC, OnStreamCreated_PropagatesInitiallyMuted) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; FakeStreamCreator creator(&stream, true); @@ -196,7 +199,8 @@ } TEST(MojoAudioInputIPC, IsReusable) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; FakeStreamCreator creator(&stream, false); @@ -221,7 +225,8 @@ } TEST(MojoAudioInputIPC, IsReusableAfterError) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; FakeStreamCreator creator(&stream, false); @@ -251,7 +256,8 @@ } TEST(MojoAudioInputIPC, Record_Records) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; FakeStreamCreator creator(&stream, false); @@ -274,7 +280,8 @@ } TEST(MojoAudioInputIPC, SetVolume_SetsVolume) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; FakeStreamCreator creator(&stream, false); @@ -297,7 +304,8 @@ } TEST(MojoAudioInputIPC, SetOutputDeviceForAec_AssociatesInputAndOutputForAec) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; FakeStreamCreator creator(&stream, false);
diff --git a/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc b/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc index 1f8f1e3d..2276ded 100644 --- a/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc +++ b/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc
@@ -9,10 +9,10 @@ #include <string> #include <utility> -#include "base/message_loop/message_loop.h" #include "base/optional.h" #include "base/run_loop.h" #include "base/test/gtest_util.h" +#include "base/test/scoped_task_environment.h" #include "media/audio/audio_device_description.h" #include "media/base/audio_parameters.h" #include "mojo/public/cpp/bindings/binding.h" @@ -200,7 +200,8 @@ } // namespace TEST(MojoAudioOutputIPC, AuthorizeWithoutFactory_CallsAuthorizedWithError) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockDelegate> delegate; std::unique_ptr<media::AudioOutputIPC> ipc = @@ -221,7 +222,8 @@ TEST(MojoAudioOutputIPC, CreateWithoutAuthorizationWithoutFactory_CallsAuthorizedWithError) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); StrictMock<MockDelegate> delegate; std::unique_ptr<media::AudioOutputIPC> ipc = @@ -238,7 +240,8 @@ } TEST(MojoAudioOutputIPC, DeviceAuthorized_Propagates) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockDelegate> delegate; @@ -261,7 +264,8 @@ } TEST(MojoAudioOutputIPC, OnDeviceCreated_Propagates) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; @@ -288,7 +292,8 @@ TEST(MojoAudioOutputIPC, CreateWithoutAuthorization_RequestsAuthorizationFirst) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; @@ -315,7 +320,8 @@ } TEST(MojoAudioOutputIPC, IsReusable) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; @@ -346,7 +352,8 @@ } TEST(MojoAudioOutputIPC, IsReusableAfterError) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; @@ -399,7 +406,8 @@ } TEST(MojoAudioOutputIPC, DeviceNotAuthorized_Propagates) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockDelegate> delegate; @@ -430,7 +438,8 @@ // The authorization IPC message might be aborted by the remote end // disconnecting. In this case, the MojoAudioOutputIPC object must still // send a notification to unblock the AudioOutputIPCDelegate. - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockDelegate> delegate; @@ -460,7 +469,8 @@ // This test makes sure that the MojoAudioOutputIPC doesn't callback for // authorization when the factory disconnects if it already got a callback // for authorization. - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; stream_factory.PrepareProviderForAuthorization( kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(nullptr)); @@ -486,7 +496,8 @@ } TEST(MojoAudioOutputIPC, AuthorizeNoClose_DCHECKs) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockDelegate> delegate; @@ -506,7 +517,8 @@ } TEST(MojoAudioOutputIPC, CreateNoClose_DCHECKs) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockDelegate> delegate; StrictMock<MockStream> stream; @@ -528,7 +540,8 @@ } TEST(MojoAudioOutputIPC, Play_Plays) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; @@ -556,7 +569,8 @@ } TEST(MojoAudioOutputIPC, Pause_Pauses) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; @@ -584,7 +598,8 @@ } TEST(MojoAudioOutputIPC, SetVolume_SetsVolume) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); TestRemoteFactory stream_factory; StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate;
diff --git a/content/renderer/media/render_media_log_unittest.cc b/content/renderer/media/render_media_log_unittest.cc index 9f5d15d..ae362c89 100644 --- a/content/renderer/media/render_media_log_unittest.cc +++ b/content/renderer/media/render_media_log_unittest.cc
@@ -5,7 +5,7 @@ #include <tuple> #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/test/simple_test_tick_clock.h" #include "base/test/test_mock_time_task_runner.h" #include "content/common/view_messages.h" @@ -57,7 +57,7 @@ } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; MockRenderThread render_thread_; base::SimpleTestTickClock tick_clock_; RenderMediaLog log_;
diff --git a/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc b/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc index 6da7d4f..8cb93d6 100644 --- a/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc +++ b/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc
@@ -5,8 +5,8 @@ #include "content/renderer/media/renderer_webaudiodevice_impl.h" #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/strings/stringprintf.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "content/renderer/media/audio/audio_device_factory.h" #include "media/base/audio_capturer_source.h" @@ -68,7 +68,8 @@ void SetupDevice(blink::WebAudioLatencyHint latencyHint) { webaudio_device_.reset(new RendererWebAudioDeviceImplUnderTest( media::CHANNEL_LAYOUT_MONO, 1, latencyHint, this, 0)); - webaudio_device_->SetMediaTaskRunnerForTesting(message_loop_.task_runner()); + webaudio_device_->SetMediaTaskRunnerForTesting( + task_environment_.GetMainThreadTaskRunner()); } void SetupDevice(media::ChannelLayout layout, int channels) { @@ -77,7 +78,8 @@ blink::WebAudioLatencyHint( blink::WebAudioLatencyHint::kCategoryInteractive), this, 0)); - webaudio_device_->SetMediaTaskRunnerForTesting(message_loop_.task_runner()); + webaudio_device_->SetMediaTaskRunnerForTesting( + task_environment_.GetMainThreadTaskRunner()); } MOCK_METHOD2(CreateAudioCapturerSource, @@ -114,7 +116,7 @@ void TearDown() override { webaudio_device_.reset(); } std::unique_ptr<RendererWebAudioDeviceImpl> webaudio_device_; - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; }; TEST_F(RendererWebAudioDeviceImplTest, ChannelLayout) {
diff --git a/content/renderer/media/stream/media_stream_audio_unittest.cc b/content/renderer/media/stream/media_stream_audio_unittest.cc index abddd1d..4c881a0 100644 --- a/content/renderer/media/stream/media_stream_audio_unittest.cc +++ b/content/renderer/media/stream/media_stream_audio_unittest.cc
@@ -5,9 +5,9 @@ #include <stdint.h> #include "base/atomicops.h" -#include "base/message_loop/message_loop.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" +#include "base/test/scoped_task_environment.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" #include "base/threading/thread_checker.h" @@ -267,7 +267,7 @@ blink::WebMediaStreamSource blink_audio_source_; blink::WebMediaStreamTrack blink_audio_track_; - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; }; // Tests that a simple source-->track-->sink connection and audio data flow
diff --git a/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc index 8757ba3..934644c 100644 --- a/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc +++ b/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
@@ -9,7 +9,7 @@ #include <string> #include <utility> -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/renderer/media/stream/local_media_stream_audio_source.h" #include "content/renderer/media/stream/media_stream_audio_source.h" #include "content/renderer/media/stream/media_stream_source.h" @@ -467,7 +467,7 @@ private: // Required for tests involving a MediaStreamAudioSource. - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; MockPeerConnectionDependencyFactory pc_factory_; };
diff --git a/content/renderer/media/stream/processed_local_audio_source_unittest.cc b/content/renderer/media/stream/processed_local_audio_source_unittest.cc index 6cc48ae1c3..50003e7 100644 --- a/content/renderer/media/stream/processed_local_audio_source_unittest.cc +++ b/content/renderer/media/stream/processed_local_audio_source_unittest.cc
@@ -6,7 +6,7 @@ #include <string> #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "content/public/renderer/media_stream_audio_sink.h" #include "content/renderer/media/audio/mock_audio_device_factory.h" @@ -144,7 +144,8 @@ const blink::WebString& result_name) {} private: - base::MessageLoop main_thread_message_loop_; // Needed for MSAudioProcessor. + base::test::ScopedTaskEnvironment + task_environment_; // Needed for MSAudioProcessor. MockAudioDeviceFactory mock_audio_device_factory_; MockPeerConnectionDependencyFactory mock_dependency_factory_; blink::WebMediaStreamSource blink_audio_source_;
diff --git a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc index 00835f1..58e88fc 100644 --- a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc +++ b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
@@ -8,9 +8,9 @@ #include <vector> #include "base/containers/circular_deque.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "cc/layers/layer.h" #include "content/public/renderer/media_stream_renderer_factory.h" @@ -525,8 +525,9 @@ public cc::VideoFrameProvider::Client { public: WebMediaPlayerMSTest() - : render_factory_(new MockRenderFactory(message_loop_.task_runner(), - &message_loop_controller_)), + : render_factory_( + new MockRenderFactory(base::ThreadTaskRunnerHandle::Get(), + &message_loop_controller_)), gpu_factories_(new media::MockGpuVideoAcceleratorFactories(nullptr)), surface_layer_bridge_( std::make_unique<NiceMock<MockSurfaceLayerBridge>>()), @@ -648,7 +649,7 @@ return std::move(submitter_); } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; MockRenderFactory* render_factory_; std::unique_ptr<media::MockGpuVideoAcceleratorFactories> gpu_factories_; FakeWebMediaPlayerDelegate delegate_; @@ -679,8 +680,8 @@ player_ = std::make_unique<WebMediaPlayerMS>( nullptr, this, &delegate_, std::make_unique<media::MediaLog>(), std::unique_ptr<MediaStreamRendererFactory>(render_factory_), - message_loop_.task_runner(), message_loop_.task_runner(), - message_loop_.task_runner(), message_loop_.task_runner(), + base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(), gpu_factories_.get(), blink::WebString(), base::BindOnce(&WebMediaPlayerMSTest::CreateMockSurfaceLayerBridge, base::Unretained(this)), @@ -759,7 +760,7 @@ void WebMediaPlayerMSTest::StartRendering() { if (!rendering_) { rendering_ = true; - message_loop_.task_runner()->PostTask( + base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&WebMediaPlayerMSTest::RenderFrame, base::Unretained(this))); } @@ -794,7 +795,7 @@ auto frame = compositor_->GetCurrentFrame(); compositor_->PutCurrentFrame(); } - message_loop_.task_runner()->PostDelayedTask( + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&WebMediaPlayerMSTest::RenderFrame, base::Unretained(this)),
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc index 79f3bcbc..6f896e9 100644 --- a/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc +++ b/content/renderer/media/webrtc/peer_connection_dependency_factory_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 "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" #include "content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,7 +18,7 @@ } protected: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_; };
diff --git a/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc b/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc index 2bda94c..7c43ad4 100644 --- a/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc +++ b/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
@@ -4,7 +4,7 @@ #include "content/renderer/media/webrtc/peer_connection_tracker.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/common/media/peer_connection_tracker.mojom.h" #include "content/common/media/peer_connection_tracker_messages.h" #include "content/public/test/mock_render_thread.h" @@ -168,7 +168,7 @@ } protected: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<MockPeerConnectionTrackerHost> mock_host_; std::unique_ptr<PeerConnectionTracker> tracker_; std::unique_ptr<MockSendTargetThread> target_thread_;
diff --git a/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc b/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc index fa3c5767..ba3349f2 100644 --- a/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc +++ b/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc
@@ -31,20 +31,18 @@ ~Observer() override {} - void OnToneChange(const std::string& tone, - const std::string& tone_buffer) override { + void OnToneChange(const std::string& tone) override { main_thread_->PostTask( FROM_HERE, base::BindOnce( &RtcDtmfSenderHandler::Observer::OnToneChangeOnMainThread, this, - tone, tone_buffer)); + tone)); } - void OnToneChangeOnMainThread(const std::string& tone, - const std::string& tone_buffer) { + void OnToneChangeOnMainThread(const std::string& tone) { DCHECK(thread_checker_.CalledOnValidThread()); if (handler_) - handler_->OnToneChange(tone, tone_buffer); + handler_->OnToneChange(tone); } base::ThreadChecker thread_checker_; @@ -90,14 +88,12 @@ static_cast<int>(interToneGap)); } -void RtcDtmfSenderHandler::OnToneChange(const std::string& tone, - const std::string& tone_buffer) { +void RtcDtmfSenderHandler::OnToneChange(const std::string& tone) { if (!webkit_client_) { LOG(ERROR) << "WebRTCDTMFSenderHandlerClient not set."; return; } - webkit_client_->DidPlayTone(blink::WebString::FromUTF8(tone), - blink::WebString::FromUTF8(tone_buffer)); + webkit_client_->DidPlayTone(blink::WebString::FromUTF8(tone)); } } // namespace content
diff --git a/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h b/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h index a314ecc1..8f59a39 100644 --- a/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h +++ b/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h
@@ -43,7 +43,7 @@ long duration, long interToneGap) override; - void OnToneChange(const std::string& tone, const std::string& tone_buffer); + void OnToneChange(const std::string& tone); private: scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender_;
diff --git a/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc b/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc index 3690936b..dd1e0b2 100644 --- a/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc +++ b/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
@@ -8,11 +8,11 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" #include "base/optional.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "content/child/child_process.h" #include "content/renderer/media/stream/media_stream_audio_source.h" @@ -172,7 +172,7 @@ } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; protected: std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
diff --git a/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc b/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc index 273bac1..6c98bc2 100644 --- a/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc +++ b/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
@@ -9,8 +9,9 @@ #include <vector> #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/public/renderer/media_stream_audio_renderer.h" #include "content/renderer/media/audio/audio_device_factory.h" @@ -66,7 +67,8 @@ protected: WebRtcAudioRendererTest() - : message_loop_(new base::MessageLoopForIO), + : task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO), source_(new MockAudioRendererSource()) { blink::WebVector<blink::WebMediaStreamTrack> dummy_tracks; stream_.Initialize(blink::WebString::FromUTF8("new stream"), dummy_tracks, @@ -76,8 +78,8 @@ } void SetupRenderer(const std::string& device_id) { - renderer_ = new WebRtcAudioRenderer(message_loop_->task_runner(), stream_, - 1, 1, device_id); + renderer_ = new WebRtcAudioRenderer(base::ThreadTaskRunnerHandle::Get(), + stream_, 1, 1, device_id); EXPECT_CALL( *this, MockCreateAudioRendererSink(AudioDeviceFactory::kSourceWebRtc, _, _, device_id, _)); @@ -142,7 +144,7 @@ const base::Optional<base::UnguessableToken> kAudioProcessingId = base::UnguessableToken::Create(); - std::unique_ptr<base::MessageLoopForIO> message_loop_; + base::test::ScopedTaskEnvironment task_environment_; scoped_refptr<media::MockAudioRendererSink> mock_sink_; std::unique_ptr<MockAudioRendererSource> source_; blink::WebMediaStream stream_; @@ -292,8 +294,8 @@ } TEST_F(WebRtcAudioRendererTest, InitializeWithInvalidDevice) { - renderer_ = new WebRtcAudioRenderer(message_loop_->task_runner(), stream_, 1, - 1, kInvalidOutputDeviceId); + renderer_ = new WebRtcAudioRenderer(base::ThreadTaskRunnerHandle::Get(), + stream_, 1, 1, kInvalidOutputDeviceId); EXPECT_CALL(*this, MockCreateAudioRendererSink( AudioDeviceFactory::kSourceWebRtc, _, _,
diff --git a/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc b/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc index 6c2d52e..8e20a934 100644 --- a/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc +++ b/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc
@@ -11,8 +11,8 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/renderer/pepper/pepper_device_enumeration_host_helper.h" #include "ppapi/c/pp_errors.h" #include "ppapi/host/host_message_context.h" @@ -146,7 +146,8 @@ ppapi::host::PpapiHost ppapi_host_; ppapi::host::ResourceHost resource_host_; PepperDeviceEnumerationHostHelper device_enumeration_; - base::MessageLoop message_loop_; // required for async calls to work. + base::test::ScopedTaskEnvironment + task_environment_; // required for async calls to work. private: DISALLOW_COPY_AND_ASSIGN(PepperDeviceEnumerationHostHelperTest);
diff --git a/content/renderer/pepper/pepper_file_system_host.cc b/content/renderer/pepper/pepper_file_system_host.cc index 53915df..2622490 100644 --- a/content/renderer/pepper/pepper_file_system_host.cc +++ b/content/renderer/pepper/pepper_file_system_host.cc
@@ -10,7 +10,6 @@ #include "content/public/common/service_names.mojom.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/renderer_ppapi_host.h" -#include "content/renderer/fileapi/file_system_dispatcher.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/render_thread_impl.h" #include "ppapi/c/pp_errors.h"
diff --git a/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc b/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc index 5b24e209..c2d365a 100644 --- a/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc +++ b/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc
@@ -7,7 +7,7 @@ #include <stddef.h> #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/renderer/pepper/gfx_conversion.h" #include "content/renderer/pepper/mock_renderer_ppapi_host.h" #include "content/renderer/pepper/ppb_image_data_impl.h" @@ -82,7 +82,7 @@ private: ppapi::ViewData renderer_view_data_; std::unique_ptr<PepperGraphics2DHost> host_; - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; MockRendererPpapiHost renderer_ppapi_host_; ppapi::TestGlobals test_globals_; };
diff --git a/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc b/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc index 1165db9..65dea55 100644 --- a/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc +++ b/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc
@@ -9,7 +9,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/public/common/content_switches.h" #include "content/public/renderer/render_frame.h" #include "skia/ext/platform_canvas.h" @@ -83,7 +83,7 @@ int change_callback_calls_; - base::MessageLoop loop_; + base::test::ScopedTaskEnvironment task_environment_; }; TEST_F(PluginInstanceThrottlerImplTest, ThrottleAndUnthrottleByClick) {
diff --git a/content/renderer/pepper/v8_var_converter_unittest.cc b/content/renderer/pepper/v8_var_converter_unittest.cc index 3de4b45..543fb868 100644 --- a/content/renderer/pepper/v8_var_converter_unittest.cc +++ b/content/renderer/pepper/v8_var_converter_unittest.cc
@@ -12,9 +12,9 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/synchronization/waitable_event.h" +#include "base/test/scoped_task_environment.h" #include "base/values.h" #include "content/renderer/pepper/resource_converter.h" #include "ppapi/c/pp_bool.h" @@ -236,7 +236,8 @@ std::unique_ptr<V8VarConverter> converter_; private: - base::MessageLoop message_loop_; // Required to receive callbacks. + base::test::ScopedTaskEnvironment + task_environment_; // Required to receive callbacks. TestGlobals globals_; };
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index ee4469b..f0266e8 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -4177,11 +4177,6 @@ observer.WillSendSubmitEvent(form); } -void RenderFrameImpl::WillSubmitForm(const blink::WebFormElement& form) { - for (auto& observer : observers_) - observer.WillSubmitForm(form); -} - void RenderFrameImpl::DidCreateDocumentLoader( blink::WebDocumentLoader* document_loader) { DocumentState* document_state = @@ -6174,6 +6169,10 @@ !url.SchemeIs(url::kDataScheme); if (info.default_policy == blink::kWebNavigationPolicyCurrentTab) { + if (!info.form.IsNull()) { + for (auto& observer : observers_) + observer.WillSubmitForm(info.form); + } // If the navigation is not synchronous, send it to the browser. This // includes navigations with no request being sent to the network stack. if (!use_archive && IsURLHandledByNetworkStack(url)) {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 3b2515d..e993cf33 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -647,7 +647,6 @@ blink::WebNavigationPolicy DecidePolicyForNavigation( const NavigationPolicyInfo& info) override; void WillSendSubmitEvent(const blink::WebFormElement& form) override; - void WillSubmitForm(const blink::WebFormElement& form) override; void DidCreateDocumentLoader( blink::WebDocumentLoader* document_loader) override; void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 70dc575..38263dc 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -87,8 +87,6 @@ #include "content/renderer/dom_storage/webstoragearea_impl.h" #include "content/renderer/dom_storage/webstoragenamespace_impl.h" #include "content/renderer/effective_connection_type_helper.h" -#include "content/renderer/fileapi/file_system_dispatcher.h" -#include "content/renderer/fileapi/webfilesystem_impl.h" #include "content/renderer/gpu/frame_swap_message_queue.h" #include "content/renderer/indexed_db/indexed_db_dispatcher.h" #include "content/renderer/input/widget_input_handler_manager.h" @@ -1007,7 +1005,6 @@ void RenderThreadImpl::Shutdown() { ChildThreadImpl::Shutdown(); - WebFileSystemImpl::DeleteThreadSpecificInstance(); // In a multi-process mode, we immediately exit the renderer. // Historically we had a graceful shutdown sequence here but it was // 1) a waste of performance and 2) a source of lots of complicated
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 05f920c3..89e48f2d 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -694,8 +694,7 @@ prefs.application_cache_enabled); settings->SetHistoryEntryRequiresUserGesture( prefs.history_entry_requires_user_gesture); - settings->SetShouldProtectAgainstIpcFlooding( - !prefs.disable_ipc_flooding_protection); + settings->SetShouldThrottlePushState(!prefs.disable_pushstate_throttle); settings->SetHyperlinkAuditingEnabled(prefs.hyperlink_auditing_enabled); settings->SetCookieEnabled(prefs.cookie_enabled); settings->SetNavigateOnDragDrop(prefs.navigate_on_drag_drop);
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 7911a12..e9ea249 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -45,7 +45,6 @@ #include "content/renderer/dom_storage/local_storage_namespace.h" #include "content/renderer/dom_storage/session_web_storage_namespace_impl.h" #include "content/renderer/dom_storage/webstoragenamespace_impl.h" -#include "content/renderer/fileapi/webfilesystem_impl.h" #include "content/renderer/image_capture/image_capture_frame_grabber.h" #include "content/renderer/indexed_db/webidbfactory_impl.h" #include "content/renderer/loader/child_url_loader_factory_bundle.h" @@ -141,7 +140,6 @@ using blink::WebBlobRegistry; using blink::WebCanvasCaptureHandler; using blink::WebDatabaseObserver; -using blink::WebFileSystem; using blink::WebIDBFactory; using blink::WebImageCaptureFrameGrabber; using blink::WebMediaPlayer; @@ -294,7 +292,6 @@ } RendererBlinkPlatformImpl::~RendererBlinkPlatformImpl() { - WebFileSystemImpl::DeleteThreadSpecificInstance(); main_thread_scheduler_->SetTopLevelBlameContext(nullptr); } @@ -577,10 +574,6 @@ //------------------------------------------------------------------------------ -WebFileSystem* RendererBlinkPlatformImpl::FileSystem() { - return WebFileSystemImpl::ThreadSpecificInstance(default_task_runner_.get()); -} - WebString RendererBlinkPlatformImpl::FileSystemCreateOriginIdentifier( const blink::WebSecurityOrigin& origin) { return WebString::FromUTF8(
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index 81e542c..4ec814f 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -126,7 +126,6 @@ bool IsLockedToSite() const override; std::unique_ptr<blink::WebIDBFactory> CreateIdbFactory() override; - blink::WebFileSystem* FileSystem() override; blink::WebString FileSystemCreateOriginIdentifier( const blink::WebSecurityOrigin& origin) override;
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 734d704..fa4d474a 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -467,7 +467,7 @@ false /* report_security_info */, -1 /* request_id */); client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_), - nullptr); + mojo::ScopedDataPipeConsumerHandle()); // This will delete |this|. client->OnNavigationPreloadComplete( fetch_event_id_, response_head.response_start, @@ -527,7 +527,7 @@ // without OnStartLoadingResponseBody(). DCHECK(!body_.is_valid()); client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_), - nullptr); + mojo::ScopedDataPipeConsumerHandle()); } // This will delete |this|. client->OnNavigationPreloadComplete( @@ -544,9 +544,8 @@ if (!client) return; - client->OnNavigationPreloadResponse( - fetch_event_id_, std::move(response_), - std::make_unique<WebDataConsumerHandleImpl>(std::move(body_))); + client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_), + std::move(body_)); } void ReportErrorToClient(const std::string& message, @@ -1740,7 +1739,7 @@ void ServiceWorkerContextClient::OnNavigationPreloadResponse( int fetch_event_id, std::unique_ptr<blink::WebURLResponse> response, - std::unique_ptr<blink::WebDataConsumerHandle> data_consumer_handle) { + mojo::ScopedDataPipeConsumerHandle data_pipe) { TRACE_EVENT_WITH_FLOW0( "ServiceWorker", "ServiceWorkerContextClient::OnNavigationPreloadResponse", @@ -1748,7 +1747,7 @@ TRACE_ID_LOCAL(fetch_event_id)), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); proxy_->OnNavigationPreloadResponse(fetch_event_id, std::move(response), - std::move(data_consumer_handle)); + std::move(data_pipe)); } void ServiceWorkerContextClient::OnNavigationPreloadError(
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 5955295..5d7eab5 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -46,7 +46,6 @@ namespace blink { struct PlatformNotificationData; -class WebDataConsumerHandle; class WebServiceWorkerContextProxy; class WebServiceWorkerResponse; class WebURLResponse; @@ -338,7 +337,7 @@ void OnNavigationPreloadResponse( int fetch_event_id, std::unique_ptr<blink::WebURLResponse> response, - std::unique_ptr<blink::WebDataConsumerHandle> data_consumer_handle); + mojo::ScopedDataPipeConsumerHandle data_pipe); // Called when the navigation preload request completed. Either // OnNavigationPreloadComplete() or OnNavigationPreloadError() must be // called to release the preload related resources.
diff --git a/content/renderer/service_worker/service_worker_context_client_unittest.cc b/content/renderer/service_worker/service_worker_context_client_unittest.cc index 7a18782..554d1ac1 100644 --- a/content/renderer/service_worker/service_worker_context_client_unittest.cc +++ b/content/renderer/service_worker/service_worker_context_client_unittest.cc
@@ -158,7 +158,7 @@ void OnNavigationPreloadResponse( int fetch_event_id, std::unique_ptr<blink::WebURLResponse>, - std::unique_ptr<blink::WebDataConsumerHandle>) override { + mojo::ScopedDataPipeConsumerHandle) override { NOTREACHED(); } void OnNavigationPreloadError(
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/content/renderer/shared_worker/embedded_shared_worker_stub.cc index c2a3eea..c272606b 100644 --- a/content/renderer/shared_worker/embedded_shared_worker_stub.cc +++ b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -15,6 +15,7 @@ #include "content/public/common/appcache_info.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" #include "content/public/common/origin_util.h" #include "content/public/common/renderer_preferences.h" #include "content/public/renderer/content_renderer_client.h" @@ -202,6 +203,14 @@ std::unique_ptr<NavigationResponseOverrideParameters> response_override_; }; +// "ForSharedWorker" is to avoid collisions in Jumbo builds. +bool IsOutOfProcessNetworkServiceForSharedWorker() { + return base::FeatureList::IsEnabled(network::features::kNetworkService) && + !base::FeatureList::IsEnabled(features::kNetworkServiceInProcess) && + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSingleProcess); +} + } // namespace EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub( @@ -217,7 +226,7 @@ network::mojom::URLLoaderFactoryAssociatedPtrInfo main_script_loader_factory, blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params, - std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories, + std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle, mojom::ControllerServiceWorkerInfoPtr controller_info, mojom::SharedWorkerHostPtr host, mojom::SharedWorkerRequest request, @@ -272,10 +281,30 @@ base::nullopt /* subresource_overrides */); } - if (subresource_loader_factories) { + // |factory_bundle| is provided in the + // ServiceWorkerServicification or NetworkService case. + DCHECK(factory_bundle || + !blink::ServiceWorkerUtils::IsServicificationEnabled()); + if (factory_bundle) { + // If the network service crashes, then self-destruct so clients don't get + // stuck with a worker with a broken loader. Self-destruction is effectively + // the same as the worker's process crashing. + // The default factory might not be to the network service if a feature like + // AppCache set itself to the default, but treat a connection error as fatal + // anyway so clients don't get stuck. + if (IsOutOfProcessNetworkServiceForSharedWorker()) { + default_factory_connection_error_handler_holder_.Bind( + std::move(factory_bundle->default_factory_info())); + default_factory_connection_error_handler_holder_->Clone( + mojo::MakeRequest(&factory_bundle->default_factory_info())); + default_factory_connection_error_handler_holder_ + .set_connection_error_handler(base::BindOnce( + &EmbeddedSharedWorkerStub::Terminate, base::Unretained(this))); + } + subresource_loader_factories_->Update( std::make_unique<ChildURLLoaderFactoryBundleInfo>( - std::move(subresource_loader_factories), + std::move(factory_bundle), nullptr /* prefetch_loader_factory_info */), base::nullopt /* subresource_overrides */); } @@ -466,7 +495,7 @@ } void EmbeddedSharedWorkerStub::Terminate() { - // After this we wouldn't get any IPC for this stub. + // After this we should ignore any IPC for this stub. running_ = false; impl_->TerminateWorkerContext(); }
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.h b/content/renderer/shared_worker/embedded_shared_worker_stub.h index 408fa7c..a9f2386 100644 --- a/content/renderer/shared_worker/embedded_shared_worker_stub.h +++ b/content/renderer/shared_worker/embedded_shared_worker_stub.h
@@ -148,6 +148,12 @@ // taking a resource pre-requested by the browser process. std::unique_ptr<NavigationResponseOverrideParameters> response_override_; + // Out-of-process NetworkService: + // Detects disconnection from the default factory of the loader factory bundle + // used by this worker (typically the network service). + network::mojom::URLLoaderFactoryPtr + default_factory_connection_error_handler_holder_; + DISALLOW_COPY_AND_ASSIGN(EmbeddedSharedWorkerStub); };
diff --git a/content/renderer/worker_thread_registry_unittest.cc b/content/renderer/worker_thread_registry_unittest.cc index 6dcfbd1d..275630a 100644 --- a/content/renderer/worker_thread_registry_unittest.cc +++ b/content/renderer/worker_thread_registry_unittest.cc
@@ -5,7 +5,7 @@ #include "content/renderer/worker_thread_registry.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "content/public/renderer/worker_thread.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,7 +19,7 @@ WorkerThreadRegistry task_runner_; private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment task_environment_; }; class MockObserver : public WorkerThread::Observer {
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index 88c88d4..aa545ca7 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -724,6 +724,11 @@ self.Flaky('conformance/textures/misc/' + 'tex-video-using-tex-unit-non-zero.html', ['android', 'nvidia'], bug=830901) + self.Flaky('conformance/extensions/oes-texture-half-float-with-video.html', + ['android', 'nvidia'], bug=891456) + self.Flaky('conformance/textures/image_bitmap_from_video/' + + 'tex-2d-rgb-rgb-unsigned_short_5_6_5.html', ['android', 'nvidia'], + bug=891456) # Nexus 9 and Shield TV (NVIDIA GPUs currently on the waterfall) self.Fail('conformance/ogles/GL/array/array_001_to_006.html',
diff --git a/device/gamepad/gamepad_provider.h b/device/gamepad/gamepad_provider.h index 35a856ea8..ff3fd8c 100644 --- a/device/gamepad/gamepad_provider.h +++ b/device/gamepad/gamepad_provider.h
@@ -14,7 +14,7 @@ #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/time/time.h" #include "device/gamepad/gamepad_export.h" #include "device/gamepad/gamepad_pad_state_provider.h"
diff --git a/docs/gpu/pixel_wrangling.md b/docs/gpu/pixel_wrangling.md index 42b73463..b04c333 100644 --- a/docs/gpu/pixel_wrangling.md +++ b/docs/gpu/pixel_wrangling.md
@@ -183,8 +183,7 @@ waterfall 1. <code>[mac_chromium_rel_ng]</code> on the [luci.chromium.try] waterfall - <!-- TODO(kainino): update link to luci.chromium.try --> - 1. <code>[win7_chromium_rel_ng]</code> on the [tryserver.chromium.win] + 1. <code>[win7_chromium_rel_ng]</code> on the [luci.chromium.try] waterfall 1. The best tool to use to quickly find flakiness on the tryservers is the new [Chromium Try Flakes] tool. Look for the names of GPU tests (like @@ -262,13 +261,13 @@ [luci.chromium.try]: https://ci.chromium.org/p/chromium/g/luci.chromium.try/builders [mac_chromium_rel_ng]: https://ci.chromium.org/p/chromium/builders/luci.chromium.try/mac_chromium_rel_ng [tryserver.chromium.mac]: https://ci.chromium.org/p/chromium/g/tryserver.chromium.mac/builders -[win7_chromium_rel_ng]: https://ci.chromium.org/buildbot/tryserver.chromium.win/win7_chromium_rel_ng/ +[win7_chromium_rel_ng]: https://ci.chromium.org/p/chromium/builders/luci.chromium.try/win7_chromium_rel_ng [tryserver.chromium.win]: https://ci.chromium.org/p/chromium/g/tryserver.chromium.win/builders [Chromium Try Flakes]: http://chromium-try-flakes.appspot.com/ <!-- TODO(kainino): link doesn't work, but is still included from chromium-swarm homepage so not removing it now --> [Swarming Server Stats]: https://chromium-swarm.appspot.com/stats [chromium-gpu-archive/reference-images]: https://console.developers.google.com/storage/chromium-gpu-archive/reference-images -[instructions on the GPU testing page]: https://sites.google.com/a/chromium.org/dev/developers/testing/gpu-testing#TOC-Updating-and-Adding-New-Pixel-Tests-to-the-GPU-Bots +[instructions on the GPU testing page]: https://chromium.googlesource.com/chromium/src/+/master/docs/gpu/gpu_testing.md [Chrome Internal GPU Pixel Wrangling Instructions]: https://sites.google.com/a/google.com/client3d/documents/chrome-internal-gpu-pixel-wrangling-instructions [src/content/test/gpu/gpu_tests/]: https://chromium.googlesource.com/chromium/src/+/master/content/test/gpu/gpu_tests/ [webgl_conformance_expectations.py]: https://chromium.googlesource.com/chromium/src/+/master/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
diff --git a/docs/login/restrictive_networks.md b/docs/login/restrictive_networks.md new file mode 100644 index 0000000..cebeba66 --- /dev/null +++ b/docs/login/restrictive_networks.md
@@ -0,0 +1,33 @@ +# Working with Restrictive Networks + +ChromeOS login supports letting the user connect to a restricted network, +such as one that has a captive portal (e.g. a terms of service screen). + +Testing on a restricted network can be tricky. The most robust way to test is +to actually connect your device to a restricted network, but this can greatly +slow iteration time. An alternative is to run chrome locally with +`--proxy-server` and run a proxy HTTP server locally that emulates the +restricted network. + +## go-authproxy + +[go-authproxy](https://github.com/jacobdufault/go-authproxy) is a proxy that +implements HTTP basic authentication and supports serving a captive portal. + +To require HTTP basic authentication + +```sh +# terminal A +$ go-authproxy -basic-auth user:pass # interrupt (e.g. <c-c>) to shutdown +# terminal B +$ chrome --proxy-server="127.0.0.1:8080" +``` + +To show a captive portal + +```sh +# terminal A +$ go-authproxy -captive-portal # interrupt (e.g. <c-c>) to shutdown +# terminal B +$ chrome --proxy-server="127.0.0.1:8080" +``` \ No newline at end of file
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn index 39d7a9d..8053cc7 100644 --- a/ios/chrome/browser/autofill/BUILD.gn +++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -59,6 +59,7 @@ "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/history", "//ios/chrome/browser/passwords:passwords_generation_utils", "//ios/chrome/browser/signin", "//ios/chrome/browser/ui",
diff --git a/ios/chrome/browser/autofill/personal_data_manager_factory.cc b/ios/chrome/browser/autofill/personal_data_manager_factory.cc index 20744b8..9155130 100644 --- a/ios/chrome/browser/autofill/personal_data_manager_factory.cc +++ b/ios/chrome/browser/autofill/personal_data_manager_factory.cc
@@ -16,6 +16,7 @@ #include "ios/chrome/browser/autofill/autofill_profile_validator_factory.h" #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/web_data_service_factory.h" @@ -53,10 +54,12 @@ auto autofill_db = ios::WebDataServiceFactory::GetAutofillWebDataForBrowserState( chrome_browser_state, ServiceAccessType::EXPLICIT_ACCESS); + auto* history_service = ios::HistoryServiceFactory::GetForBrowserState( + chrome_browser_state, ServiceAccessType::EXPLICIT_ACCESS); service->Init( autofill_db, nullptr, chrome_browser_state->GetPrefs(), IdentityManagerFactory::GetForBrowserState(chrome_browser_state), - AutofillProfileValidatorFactory::GetInstance(), + AutofillProfileValidatorFactory::GetInstance(), history_service, chrome_browser_state->IsOffTheRecord()); return service; }
diff --git a/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.cc b/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.cc index c13a0f7..584c8aa 100644 --- a/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.cc +++ b/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.cc
@@ -57,7 +57,8 @@ service->Init( autofill_db, nullptr, browser_state->GetPrefs(), WebViewIdentityManagerFactory::GetForBrowserState(browser_state), - /*client_profile_validator=*/nullptr, browser_state->IsOffTheRecord()); + /*client_profile_validator=*/nullptr, /*history_service=*/nullptr, + browser_state->IsOffTheRecord()); return service; }
diff --git a/media/audio/win/audio_device_listener_win.cc b/media/audio/win/audio_device_listener_win.cc index e39eb06..f147e454 100644 --- a/media/audio/win/audio_device_listener_win.cc +++ b/media/audio/win/audio_device_listener_win.cc
@@ -8,7 +8,7 @@ #include "base/logging.h" #include "base/strings/utf_string_conversions.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/time/default_tick_clock.h" #include "base/win/scoped_co_mem.h" #include "base/win/windows_version.h"
diff --git a/media/audio/win/audio_low_latency_input_win_unittest.cc b/media/audio/win/audio_low_latency_input_win_unittest.cc index 27b0f65f..80a0a82 100644 --- a/media/audio/win/audio_low_latency_input_win_unittest.cc +++ b/media/audio/win/audio_low_latency_input_win_unittest.cc
@@ -300,6 +300,36 @@ } } +// Test effects. +TEST_F(WinAudioInputTest, WASAPIAudioInputStreamEffects) { + AudioDeviceInfoAccessorForTests device_info_accessor(audio_manager_.get()); + ABORT_AUDIO_TEST_IF_NOT(device_info_accessor.HasAudioInputDevices() && + device_info_accessor.HasAudioOutputDevices() && + CoreAudioUtil::IsSupported()); + + // Retrieve a list of all available input devices. + media::AudioDeviceDescriptions device_descriptions; + device_info_accessor.GetAudioInputDeviceDescriptions(&device_descriptions); + + // All devices in the device description list should have the experimental + // echo canceller capability. + for (const auto& device : device_descriptions) { + AudioParameters params = + device_info_accessor.GetInputStreamParameters(device.unique_id); + EXPECT_EQ(params.effects(), AudioParameters::EXPERIMENTAL_ECHO_CANCELLER); + } + + // The two loopback devices is not included in the device description list + // above. They should have no effects. + AudioParameters params = device_info_accessor.GetInputStreamParameters( + AudioDeviceDescription::kLoopbackInputDeviceId); + EXPECT_EQ(params.effects(), AudioParameters::NO_EFFECTS); + + params = device_info_accessor.GetInputStreamParameters( + AudioDeviceDescription::kLoopbackWithMuteDeviceId); + EXPECT_EQ(params.effects(), AudioParameters::NO_EFFECTS); +} + // Test Create(), Close() calling sequence. TEST_P(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) { ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); @@ -455,7 +485,7 @@ CoreAudioUtil::IsSupported()); AudioParameters params = device_info_accessor.GetInputStreamParameters( AudioDeviceDescription::kLoopbackInputDeviceId); - EXPECT_EQ(params.effects(), 0); + EXPECT_EQ(params.effects(), AudioParameters::NO_EFFECTS); AudioParameters output_params = device_info_accessor.GetOutputStreamParameters(std::string());
diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc index 429466d2..0dd2120f 100644 --- a/media/audio/win/audio_manager_win.cc +++ b/media/audio/win/audio_manager_win.cc
@@ -187,8 +187,11 @@ if (user_buffer_size) parameters.set_frames_per_buffer(user_buffer_size); - parameters.set_effects(parameters.effects() | - AudioParameters::EXPERIMENTAL_ECHO_CANCELLER); + if (device_id != AudioDeviceDescription::kLoopbackInputDeviceId && + device_id != AudioDeviceDescription::kLoopbackWithMuteDeviceId) { + parameters.set_effects(parameters.effects() | + AudioParameters::EXPERIMENTAL_ECHO_CANCELLER); + } return parameters; }
diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc index 73ea9ca..dc261937 100644 --- a/media/audio/win/audio_output_win_unittest.cc +++ b/media/audio/win/audio_output_win_unittest.cc
@@ -189,43 +189,6 @@ oas->Close(); } -// Test that can it be cannot be created with invalid parameters. -TEST_F(WinAudioTest, SanityOnMakeParams) { - ABORT_AUDIO_TEST_IF_NOT(audio_manager_device_info_->HasAudioOutputDevices()); - - AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR; - EXPECT_TRUE(NULL == - audio_manager_->MakeAudioOutputStream( - AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 256), - std::string(), AudioManager::LogCallback())); - EXPECT_TRUE(NULL == - audio_manager_->MakeAudioOutputStream( - AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 1024 * 1024, 256), - std::string(), AudioManager::LogCallback())); - EXPECT_TRUE(NULL == audio_manager_->MakeAudioOutputStream( - AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 0, 256), - std::string(), AudioManager::LogCallback())); - EXPECT_TRUE(NULL == - audio_manager_->MakeAudioOutputStream( - AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 256), - std::string(), AudioManager::LogCallback())); - EXPECT_TRUE(NULL == - audio_manager_->MakeAudioOutputStream( - AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, -8000, 256), - std::string(), AudioManager::LogCallback())); - EXPECT_TRUE(NULL == audio_manager_->MakeAudioOutputStream( - AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, -100), - std::string(), AudioManager::LogCallback())); - EXPECT_TRUE(NULL == audio_manager_->MakeAudioOutputStream( - AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 0), - std::string(), AudioManager::LogCallback())); - EXPECT_TRUE(NULL == - audio_manager_->MakeAudioOutputStream( - AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, - media::limits::kMaxSamplesPerPacket + 1), - std::string(), AudioManager::LogCallback())); -} - // Test that it can be opened and closed. TEST_F(WinAudioTest, PCMWaveStreamOpenAndClose) { ABORT_AUDIO_TEST_IF_NOT(audio_manager_device_info_->HasAudioOutputDevices()); @@ -239,19 +202,6 @@ oas->Close(); } -// Test that it has a maximum packet size. -TEST_F(WinAudioTest, PCMWaveStreamOpenLimit) { - ABORT_AUDIO_TEST_IF_NOT(audio_manager_device_info_->HasAudioOutputDevices()); - - AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO, - 8000, 1024 * 1024 * 1024), - std::string(), AudioManager::LogCallback()); - EXPECT_TRUE(NULL == oas); - if (oas) - oas->Close(); -} - // Test potential deadlock situation if the source is slow or blocks for some // time. The actual EXPECT_GT are mostly meaningless and the real test is that // the test completes in reasonable time.
diff --git a/media/device_monitors/device_monitor_mac.h b/media/device_monitors/device_monitor_mac.h index 26f8353..7a8c43ca 100644 --- a/media/device_monitors/device_monitor_mac.h +++ b/media/device_monitors/device_monitor_mac.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/single_thread_task_runner.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/threading/thread_checker.h" #include "media/base/media_export.h"
diff --git a/media/device_monitors/device_monitor_udev.cc b/media/device_monitors/device_monitor_udev.cc index 3998e67..c8b9330 100644 --- a/media/device_monitors/device_monitor_udev.cc +++ b/media/device_monitors/device_monitor_udev.cc
@@ -11,7 +11,7 @@ #include <string> #include "base/macros.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "device/udev_linux/udev.h" #include "device/udev_linux/udev_linux.h"
diff --git a/media/device_monitors/system_message_window_win.cc b/media/device_monitors/system_message_window_win.cc index 2a8630d..c90040b 100644 --- a/media/device_monitors/system_message_window_win.cc +++ b/media/device_monitors/system_message_window_win.cc
@@ -9,7 +9,7 @@ #include "base/logging.h" #include "base/macros.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/win/wrapped_window_proc.h" #include "media/audio/win/core_audio_util_win.h"
diff --git a/media/device_monitors/system_message_window_win_unittest.cc b/media/device_monitors/system_message_window_win_unittest.cc index a6a7dfd..59863df 100644 --- a/media/device_monitors/system_message_window_win_unittest.cc +++ b/media/device_monitors/system_message_window_win_unittest.cc
@@ -11,7 +11,7 @@ #include "base/files/file_path.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/test/mock_devices_changed_observer.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/media/midi/midi_manager_unittest.cc b/media/midi/midi_manager_unittest.cc index ab716c5..d35130d1 100644 --- a/media/midi/midi_manager_unittest.cc +++ b/media/midi/midi_manager_unittest.cc
@@ -16,7 +16,7 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "build/build_config.h" #include "media/midi/midi_service.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/media/midi/midi_manager_win.h b/media/midi/midi_manager_win.h index 826a05de..3516a14 100644 --- a/media/midi/midi_manager_win.h +++ b/media/midi/midi_manager_win.h
@@ -11,7 +11,7 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "media/midi/midi_manager.h" namespace base {
diff --git a/pdf/pdfium/findtext_unittest.cc b/pdf/pdfium/findtext_unittest.cc index af3e34ea..c15b53b 100644 --- a/pdf/pdfium/findtext_unittest.cc +++ b/pdf/pdfium/findtext_unittest.cc
@@ -98,4 +98,23 @@ engine.StartFind("application", /*case_sensitive=*/true); } +TEST_F(FindTextTest, FindLineBreakText) { + SetDocumentForTest(FILE_PATH_LITERAL("spanner.pdf")); + pp::URLLoader dummy_loader; + FindTextTestClient client; + PDFiumEngine engine(&client, true); + ASSERT_TRUE(engine.New("https://chromium.org/dummy.pdf", "")); + ASSERT_TRUE(engine.HandleDocumentLoad(dummy_loader)); + + { + InSequence sequence; + + EXPECT_CALL(client, NotifyNumberOfFindResultsChanged(1, false)); + EXPECT_CALL(client, NotifySelectedFindResultChanged(0)); + EXPECT_CALL(client, NotifyNumberOfFindResultsChanged(1, true)); + } + + engine.StartFind("is the first system", /*case_sensitive=*/true); +} + } // namespace chrome_pdf
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 43fab371..63c39768 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -1931,42 +1931,65 @@ character_to_start_searching_from, text_length, data); api_string_adapter.Close(written); - base::string16 stripped_page_text; - stripped_page_text.reserve(page_text.size()); - // Values in |stripped_indices| are in the stripped text index space and + base::string16 adjusted_page_text; + adjusted_page_text.reserve(page_text.size()); + // Values in |removed_indices| are in the adjusted text index space and // indicate a character was removed from the page text before the given // index. If multiple characters are removed in a row then there will be // multiple entries with the same value. - std::vector<size_t> stripped_indices; + std::vector<size_t> removed_indices; + // When walking through the page text collapse any whitespace regions, + // including \r and \n, down to a single ' ' character. This code does + // not use base::CollapseWhitespace(), because that function does not + // return where the collapsing occurs, but uses the same underlying list of + // whitespace characters. Calculating where the collapsed regions are after + // the fact is as complex as collapsing them manually. for (size_t i = 0; i < page_text.size(); i++) { base::char16 c = page_text[i]; + // Collapse whitespace regions by inserting a ' ' into the + // adjusted text and recording any removed whitespace indices as preceding + // it. + if (base::IsUnicodeWhitespace(c)) { + size_t whitespace_region_begin = i; + while (i < page_text.size() && base::IsUnicodeWhitespace(page_text[i])) + ++i; + + size_t count = i - whitespace_region_begin - 1; + removed_indices.insert(removed_indices.end(), count, + adjusted_page_text.size()); + adjusted_page_text.push_back(' '); + if (i >= page_text.size()) + break; + c = page_text[i]; + } + if (IsIgnorableCharacter(c)) - stripped_indices.push_back(stripped_page_text.size()); + removed_indices.push_back(adjusted_page_text.size()); else - stripped_page_text.push_back(c); + adjusted_page_text.push_back(c); } std::vector<PDFEngine::Client::SearchStringResult> results = - client_->SearchString(stripped_page_text.c_str(), term.c_str(), + client_->SearchString(adjusted_page_text.c_str(), term.c_str(), case_sensitive); for (const auto& result : results) { - // Need to convert from stripped page text start to page text start, by - // incrementing for all the characters stripped before it in the string. - auto stripped_indices_begin = std::upper_bound( - stripped_indices.begin(), stripped_indices.end(), result.start_index); + // Need to convert from adjusted page text start to page text start, by + // incrementing for all the characters adjusted before it in the string. + auto removed_indices_begin = std::upper_bound( + removed_indices.begin(), removed_indices.end(), result.start_index); size_t page_text_result_start_index = result.start_index + - std::distance(stripped_indices.begin(), stripped_indices_begin); + std::distance(removed_indices.begin(), removed_indices_begin); - // Need to convert the stripped page length into a page text length, since - // the matching range may have stripped characters within it. This + // Need to convert the adjusted page length into a page text length, since + // the matching range may have adjusted characters within it. This // conversion only cares about skipped characters in the result interval. - auto stripped_indices_end = - std::upper_bound(stripped_indices_begin, stripped_indices.end(), + auto removed_indices_end = + std::upper_bound(removed_indices_begin, removed_indices.end(), result.start_index + result.length); - int term_stripped_count = - std::distance(stripped_indices_begin, stripped_indices_end); - int page_text_result_length = result.length + term_stripped_count; + int term_removed_count = + std::distance(removed_indices_begin, removed_indices_end); + int page_text_result_length = result.length + term_removed_count; // Need to map the indexes from the page text, which may have generated // characters like space etc, to character indices from the page. @@ -1988,7 +2011,7 @@ end = original_text_length; } DCHECK_LT(start, end); - DCHECK_EQ(term.size() + term_stripped_count, + DCHECK_EQ(term.size() + term_removed_count, static_cast<size_t>(end - start)); AddFindResult(PDFiumRange(pages_[current_page].get(), start, end - start)); }
diff --git a/services/audio/device_notifier.h b/services/audio/device_notifier.h index 5898e2c..4f5f994e 100644 --- a/services/audio/device_notifier.h +++ b/services/audio/device_notifier.h
@@ -8,7 +8,7 @@ #include <memory> #include "base/containers/flat_map.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/audio/public/mojom/device_notifications.mojom.h" #include "services/audio/traced_service_ref.h"
diff --git a/services/audio/device_notifier_unittest.cc b/services/audio/device_notifier_unittest.cc index 86b7c4f..1bee5bc 100644 --- a/services/audio/device_notifier_unittest.cc +++ b/services/audio/device_notifier_unittest.cc
@@ -7,7 +7,7 @@ #include <memory> #include <utility> -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/test/scoped_task_environment.h" #include "services/audio/public/mojom/device_notifications.mojom.h" #include "services/audio/traced_service_ref.h"
diff --git a/services/audio/service.cc b/services/audio/service.cc index 62b2bafd..a9850d8 100644 --- a/services/audio/service.cc +++ b/services/audio/service.cc
@@ -9,7 +9,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/single_thread_task_runner.h" -#include "base/system_monitor/system_monitor.h" +#include "base/system/system_monitor.h" #include "base/time/default_tick_clock.h" #include "base/trace_event/trace_event.h" #include "media/audio/audio_manager.h"
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index aa49131..07939c61 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -69,7 +69,7 @@ } bool IdentityManager::HasPrimaryAccount() const { - return !GetPrimaryAccountInfo().account_id.empty(); + return signin_manager_->IsAuthenticated(); } #if !defined(OS_CHROMEOS)
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index 20a9047..88a1618 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -750,7 +750,15 @@ TEST_F(IdentityManagerTest, HasPrimaryAccount) { EXPECT_TRUE(identity_manager()->HasPrimaryAccount()); + // Removing the account from the AccountTrackerService should not cause + // IdentityManager to think that there is no longer a primary account. + account_tracker()->RemoveAccount( + identity_manager()->GetPrimaryAccountInfo().account_id); + EXPECT_TRUE(identity_manager()->HasPrimaryAccount()); + #if !defined(OS_CHROMEOS) + // Signing out should cause IdentityManager to recognize that there is no + // longer a primary account. base::RunLoop run_loop; identity_manager_observer()->set_on_primary_account_cleared_callback( run_loop.QuitClosure()); @@ -1211,8 +1219,9 @@ } #if !defined(OS_CHROMEOS) -TEST_F(IdentityManagerTest, - IdentityManagerGetsSignInEventBeforeSigninManagerObserver) { +TEST_F( + IdentityManagerTest, + IdentityManagerGivesConsistentValuesFromSigninManagerObserverNotificationOfSignIn) { signin_manager()->ForceSignOut(); base::RunLoop run_loop; @@ -1237,8 +1246,9 @@ EXPECT_EQ(kTestEmail, primary_account_from_signin_callback.email); } -TEST_F(IdentityManagerTest, - IdentityManagerGetsSignOutEventBeforeSigninManagerObserver) { +TEST_F( + IdentityManagerTest, + IdentityManagerGivesConsistentValuesFromSigninManagerObserverNotificationOfSignOut) { base::RunLoop run_loop; TestSigninManagerObserver signin_manager_observer(signin_manager()); signin_manager_observer.set_on_google_signed_out_callback( @@ -1477,8 +1487,9 @@ ->account_from_refresh_token_removed_callback()); } -TEST_F(IdentityManagerTest, - IdentityManagerGetsTokenUpdateEventBeforeTokenServiceObserver) { +TEST_F( + IdentityManagerTest, + IdentityManagerGivesConsistentValuesFromTokenServiceObserverNotificationOfTokenUpdate) { std::string account_id = signin_manager()->GetAuthenticatedAccountId(); base::RunLoop run_loop; @@ -1503,8 +1514,9 @@ run_loop.Run(); } -TEST_F(IdentityManagerTest, - IdentityManagerGetsTokenRemovalEventBeforeTokenServiceObserver) { +TEST_F( + IdentityManagerTest, + IdentityManagerGivesConsistentValuesFromTokenServiceObserverNotificationOfTokenRemoval) { std::string account_id = signin_manager()->GetAuthenticatedAccountId(); base::RunLoop run_loop;
diff --git a/services/network/test/test_shared_url_loader_factory.cc b/services/network/test/test_shared_url_loader_factory.cc index 729f97b..acfec46 100644 --- a/services/network/test/test_shared_url_loader_factory.cc +++ b/services/network/test/test_shared_url_loader_factory.cc
@@ -42,7 +42,7 @@ } void TestSharedURLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest request) { - NOTREACHED(); + NOTIMPLEMENTED(); } // SharedURLLoaderFactoryInfo implementation
diff --git a/services/resource_coordinator/public/cpp/BUILD.gn b/services/resource_coordinator/public/cpp/BUILD.gn index 5535fec..0108604a 100644 --- a/services/resource_coordinator/public/cpp/BUILD.gn +++ b/services/resource_coordinator/public/cpp/BUILD.gn
@@ -9,7 +9,7 @@ "coordination_unit_types.h", ] - defines = [ "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_IMPLEMENTATION" ] + defines = [ "IS_SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_IMPL" ] deps = [ "//base", @@ -17,56 +17,40 @@ ] } +component("resource_coordinator_cpp_features") { + sources = [ + "resource_coordinator_features.cc", + "resource_coordinator_features.h", + ] + + defines = [ "IS_SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_FEATURES_IMPL" ] + + deps = [ + "//base", + ] +} + component("resource_coordinator_cpp") { sources = [ "frame_resource_coordinator.cc", "frame_resource_coordinator.h", - "memory_instrumentation/client_process_impl.cc", - "memory_instrumentation/client_process_impl.h", - "memory_instrumentation/coordinator.h", - "memory_instrumentation/global_memory_dump.cc", - "memory_instrumentation/global_memory_dump.h", - "memory_instrumentation/memory_instrumentation.cc", - "memory_instrumentation/memory_instrumentation.h", - "memory_instrumentation/os_metrics.cc", - "memory_instrumentation/os_metrics.h", - "memory_instrumentation/os_metrics_linux.cc", - "memory_instrumentation/os_metrics_mac.cc", - "memory_instrumentation/os_metrics_win.cc", - "memory_instrumentation/tracing_observer.cc", - "memory_instrumentation/tracing_observer.h", "page_resource_coordinator.cc", "page_resource_coordinator.h", "process_resource_coordinator.cc", "process_resource_coordinator.h", - "resource_coordinator_features.cc", - "resource_coordinator_features.h", "resource_coordinator_interface.h", "system_resource_coordinator.cc", "system_resource_coordinator.h", ] - if (is_android) { - set_sources_assignment_filter([]) - sources += [ "memory_instrumentation/os_metrics_linux.cc" ] - set_sources_assignment_filter(sources_assignment_filter) - } - - if (is_fuchsia) { - sources += [ "memory_instrumentation/os_metrics_fuchsia.cc" ] - } - - defines = [ "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION" ] - - deps = [] - if (is_win) { - deps += [ "//base/win:pe_image" ] - } + defines = [ "IS_SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPL" ] public_deps = [ ":resource_coordinator_cpp_base", + ":resource_coordinator_cpp_features", "//base", "//mojo/public/cpp/bindings", + "//services/resource_coordinator/public/cpp/memory_instrumentation", "//services/resource_coordinator/public/mojom", "//services/service_manager/public/cpp", ]
diff --git a/services/resource_coordinator/public/cpp/coordination_unit_id.h b/services/resource_coordinator/public/cpp/coordination_unit_id.h index e36f393..a94a2a1 100644 --- a/services/resource_coordinator/public/cpp/coordination_unit_id.h +++ b/services/resource_coordinator/public/cpp/coordination_unit_id.h
@@ -7,8 +7,8 @@ #include <string> #include <tuple> +#include "base/component_export.h" #include "services/resource_coordinator/public/cpp/coordination_unit_types.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_base_export.h" namespace resource_coordinator { @@ -17,7 +17,8 @@ // would like to move it to base/ as easily as possible at that point. // TODO(oysteine): Rename to CoordinationUnitGUID to better differentiate the // class from the internal id -struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_EXPORT CoordinationUnitID { +struct COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE) + CoordinationUnitID { typedef uint64_t CoordinationUnitTypeId; enum RandomID { RANDOM_ID };
diff --git a/services/resource_coordinator/public/cpp/frame_resource_coordinator.h b/services/resource_coordinator/public/cpp/frame_resource_coordinator.h index 0921faff..c452abd 100644 --- a/services/resource_coordinator/public/cpp/frame_resource_coordinator.h +++ b/services/resource_coordinator/public/cpp/frame_resource_coordinator.h
@@ -12,7 +12,8 @@ namespace resource_coordinator { -class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT FrameResourceCoordinator +class COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP) + FrameResourceCoordinator : public ResourceCoordinatorInterface<mojom::FrameCoordinationUnitPtr, mojom::FrameCoordinationUnitRequest> { public:
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/BUILD.gn b/services/resource_coordinator/public/cpp/memory_instrumentation/BUILD.gn new file mode 100644 index 0000000..1a65586 --- /dev/null +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/BUILD.gn
@@ -0,0 +1,47 @@ +# Copyright 2018 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. + +component("memory_instrumentation") { + sources = [ + "client_process_impl.cc", + "client_process_impl.h", + "coordinator.h", + "global_memory_dump.cc", + "global_memory_dump.h", + "memory_instrumentation.cc", + "memory_instrumentation.h", + "os_metrics.cc", + "os_metrics.h", + "os_metrics_linux.cc", + "os_metrics_mac.cc", + "os_metrics_win.cc", + "tracing_observer.cc", + "tracing_observer.h", + ] + + if (is_android) { + # Disable the rule that excludes _linux.cc files from Android builds. + set_sources_assignment_filter([]) + sources += [ "os_metrics_linux.cc" ] + set_sources_assignment_filter(sources_assignment_filter) + } + + if (is_fuchsia) { + sources += [ "os_metrics_fuchsia.cc" ] + } + + defines = [ "IS_RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION_IMPL" ] + + deps = [] + if (is_win) { + deps += [ "//base/win:pe_image" ] + } + + public_deps = [ + "//base", + "//mojo/public/cpp/bindings", + "//services/resource_coordinator/public/mojom", + "//services/service_manager/public/cpp", + ] +}
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h index 4a311711..d672811 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h
@@ -6,13 +6,13 @@ #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_CLIENT_PROCESS_IMPL_H_ #include "base/compiler_specific.h" +#include "base/component_export.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/memory_dump_request_args.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/coordinator.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" #include "services/service_manager/public/cpp/connector.h" @@ -28,10 +28,11 @@ // no Coordinator service in child processes. So, in a child process, the // local dump manager remotely connects to the Coordinator service. In the // browser process, it locally connects to the Coordinator service. -class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ClientProcessImpl - : public mojom::ClientProcess { +class COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION) + ClientProcessImpl : public mojom::ClientProcess { public: - struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT Config { + struct COMPONENT_EXPORT( + RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION) Config { public: Config(service_manager::Connector* connector, const std::string& service_name,
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h b/services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h index ad996fd1..6f5cfdc 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h
@@ -5,17 +5,19 @@ #ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_GLOBAL_MEMORY_DUMP_H_ #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_GLOBAL_MEMORY_DUMP_H_ +#include "base/component_export.h" #include "base/optional.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" namespace memory_instrumentation { // The returned data structure to consumers of the memory_instrumentation // service containing dumps for each process. -class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT GlobalMemoryDump { +class COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION) + GlobalMemoryDump { public: - class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ProcessDump { + class COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION) + ProcessDump { public: ProcessDump(mojom::ProcessMemoryDumpPtr process_memory_dump); ~ProcessDump();
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h index f9a13f6..d449685 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h
@@ -6,12 +6,12 @@ #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_MEMORY_INSTRUMENTATION_H_ #include "base/callback_forward.h" +#include "base/component_export.h" #include "base/memory/ref_counted.h" #include "base/threading/thread_local_storage.h" #include "base/trace_event/memory_dump_request_args.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/coordinator.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" #include "services/service_manager/public/cpp/connector.h" @@ -26,7 +26,8 @@ // memory_instrumentation service and hides away the complexity associated with // having to deal with it (e.g., maintaining service connections, bindings, // handling timeouts). -class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT MemoryInstrumentation { +class COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION) + MemoryInstrumentation { public: using MemoryDumpType = base::trace_event::MemoryDumpType; using MemoryDumpLevelOfDetail = base::trace_event::MemoryDumpLevelOfDetail;
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics.h b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics.h index 7eaec00..53496d5 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics.h
@@ -4,11 +4,11 @@ #ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_OS_METRICS_H_ #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_OS_METRICS_H_ +#include "base/component_export.h" #include "base/gtest_prod_util.h" #include "base/process/process_handle.h" #include "base/trace_event/process_memory_dump.h" #include "build/build_config.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" namespace heap_profiling { @@ -17,7 +17,8 @@ namespace memory_instrumentation { -class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT OSMetrics { +class COMPONENT_EXPORT( + RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION) OSMetrics { public: static bool FillOSMemoryDump(base::ProcessId pid, mojom::RawOSMemDump* dump); static bool FillProcessMemoryMaps(base::ProcessId,
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h index 69503418..dca47ff 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h
@@ -5,10 +5,10 @@ #ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_TRACING_OBSERVER_H #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_TRACING_OBSERVER_H +#include "base/component_export.h" #include "base/macros.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_event.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" namespace memory_instrumentation { @@ -16,8 +16,8 @@ // Observes TraceLog for Enable/Disable events and when they occur Enables and // Disables the MemoryDumpManager with the correct state based on reading the // trace log. Also provides a method for adding a dump to the trace. -class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT TracingObserver - : public base::trace_event::TraceLog::EnabledStateObserver { +class COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION) + TracingObserver : public base::trace_event::TraceLog::EnabledStateObserver { public: TracingObserver(base::trace_event::TraceLog*, base::trace_event::MemoryDumpManager*);
diff --git a/services/resource_coordinator/public/cpp/page_resource_coordinator.h b/services/resource_coordinator/public/cpp/page_resource_coordinator.h index d475e208..d4bc029 100644 --- a/services/resource_coordinator/public/cpp/page_resource_coordinator.h +++ b/services/resource_coordinator/public/cpp/page_resource_coordinator.h
@@ -14,7 +14,8 @@ namespace resource_coordinator { -class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT PageResourceCoordinator +class COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP) + PageResourceCoordinator : public ResourceCoordinatorInterface<mojom::PageCoordinationUnitPtr, mojom::PageCoordinationUnitRequest> { public:
diff --git a/services/resource_coordinator/public/cpp/process_resource_coordinator.h b/services/resource_coordinator/public/cpp/process_resource_coordinator.h index 2abddbb..3831763 100644 --- a/services/resource_coordinator/public/cpp/process_resource_coordinator.h +++ b/services/resource_coordinator/public/cpp/process_resource_coordinator.h
@@ -14,10 +14,10 @@ namespace resource_coordinator { -class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ProcessResourceCoordinator - : public ResourceCoordinatorInterface< - mojom::ProcessCoordinationUnitPtr, - mojom::ProcessCoordinationUnitRequest> { +class COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP) + ProcessResourceCoordinator : public ResourceCoordinatorInterface< + mojom::ProcessCoordinationUnitPtr, + mojom::ProcessCoordinationUnitRequest> { public: ProcessResourceCoordinator(service_manager::Connector* connector); ~ProcessResourceCoordinator() override;
diff --git a/services/resource_coordinator/public/cpp/resource_coordinator_base_export.h b/services/resource_coordinator/public/cpp/resource_coordinator_base_export.h deleted file mode 100644 index 1dd7f905..0000000 --- a/services/resource_coordinator/public/cpp/resource_coordinator_base_export.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_BASE_EXPORT_H_ -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_BASE_EXPORT_H_ - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_IMPLEMENTATION) -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_EXPORT \ - __declspec(dllexport) -#else -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_EXPORT \ - __declspec(dllimport) -#endif // defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_IMPLEMENTATION) -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_EXPORT \ - __attribute__((visibility("default"))) -#else -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_EXPORT -#endif -#endif - -#else // defined(COMPONENT_BUILD) -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_BASE_EXPORT -#endif - -#endif // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_BASE_EXPORT_H_
diff --git a/services/resource_coordinator/public/cpp/resource_coordinator_export.h b/services/resource_coordinator/public/cpp/resource_coordinator_export.h deleted file mode 100644 index c271f97..0000000 --- a/services/resource_coordinator/public/cpp/resource_coordinator_export.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_EXPORT_H_ -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_EXPORT_H_ - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION) -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT __declspec(dllexport) -#else -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT __declspec(dllimport) -#endif // defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION) -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT \ - __attribute__((visibility("default"))) -#else -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT -#endif -#endif - -#else // defined(COMPONENT_BUILD) -#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT -#endif - -#endif // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_EXPORT_H_
diff --git a/services/resource_coordinator/public/cpp/resource_coordinator_features.h b/services/resource_coordinator/public/cpp/resource_coordinator_features.h index 0b1040a..29754640 100644 --- a/services/resource_coordinator/public/cpp/resource_coordinator_features.h +++ b/services/resource_coordinator/public/cpp/resource_coordinator_features.h
@@ -8,29 +8,29 @@ #ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_FEATURES_H_ #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_FEATURES_H_ +#include "base/component_export.h" #include "base/feature_list.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h" namespace features { // The features should be documented alongside the definition of their values // in the .cc file. -extern const SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT base::Feature - kGlobalResourceCoordinator; -extern const SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT base::Feature - kPageAlmostIdle; -extern const SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT base::Feature - kPerformanceMeasurement; +extern const COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_FEATURES) + base::Feature kGlobalResourceCoordinator; +extern const COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_FEATURES) + base::Feature kPageAlmostIdle; +extern const COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_FEATURES) + base::Feature kPerformanceMeasurement; } // namespace features namespace resource_coordinator { -bool SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT -IsPageAlmostIdleSignalEnabled(); +bool COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_FEATURES) + IsPageAlmostIdleSignalEnabled(); -int SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT -GetMainThreadTaskLoadLowThreshold(); +int COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_FEATURES) + GetMainThreadTaskLoadLowThreshold(); } // namespace resource_coordinator
diff --git a/services/resource_coordinator/public/cpp/resource_coordinator_interface.h b/services/resource_coordinator/public/cpp/resource_coordinator_interface.h index 3c7a7ec..c949abe 100644 --- a/services/resource_coordinator/public/cpp/resource_coordinator_interface.h +++ b/services/resource_coordinator/public/cpp/resource_coordinator_interface.h
@@ -7,9 +7,9 @@ #include <stdint.h> +#include "base/component_export.h" #include "base/macros.h" #include "services/resource_coordinator/public/cpp/coordination_unit_id.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h" #include "services/resource_coordinator/public/mojom/coordination_unit_provider.mojom.h" #include "services/resource_coordinator/public/mojom/service_constants.mojom.h" #include "services/service_manager/public/cpp/connector.h"
diff --git a/services/resource_coordinator/public/cpp/system_resource_coordinator.h b/services/resource_coordinator/public/cpp/system_resource_coordinator.h index 3f205ff..2ce3258f 100644 --- a/services/resource_coordinator/public/cpp/system_resource_coordinator.h +++ b/services/resource_coordinator/public/cpp/system_resource_coordinator.h
@@ -10,10 +10,10 @@ namespace resource_coordinator { -class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT SystemResourceCoordinator - : public ResourceCoordinatorInterface< - mojom::SystemCoordinationUnitPtr, - mojom::SystemCoordinationUnitRequest> { +class COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP) + SystemResourceCoordinator : public ResourceCoordinatorInterface< + mojom::SystemCoordinationUnitPtr, + mojom::SystemCoordinationUnitRequest> { public: SystemResourceCoordinator(service_manager::Connector* connector); ~SystemResourceCoordinator() override;
diff --git a/services/service_manager/sandbox/mac/ppapi_v2.sb b/services/service_manager/sandbox/mac/ppapi_v2.sb index 1a5b8e27..341656f0 100644 --- a/services/service_manager/sandbox/mac/ppapi_v2.sb +++ b/services/service_manager/sandbox/mac/ppapi_v2.sb
@@ -14,6 +14,10 @@ ; Needed for Fonts. (allow-font-access) +; Mach lookups. +(allow mach-lookup + (global-name "com.apple.windowserver.active")) + ; IOKit (allow iokit-open (iokit-registry-entry-class "IOSurfaceRootUserClient"))
diff --git a/services/tracing/public/mojom/perfetto_service.mojom b/services/tracing/public/mojom/perfetto_service.mojom index 80a4bac..e76198e 100644 --- a/services/tracing/public/mojom/perfetto_service.mojom +++ b/services/tracing/public/mojom/perfetto_service.mojom
@@ -7,14 +7,13 @@ const string kTraceEventDataSourceName = "org.chromium.trace_event"; const string kMetaDataSourceName = "org.chromium.trace_metadata"; -// Brief description of the flow: There's a per-process ProducerClient -// which connects to the central PerfettoService and establishes a two-way -// connection with a ProducerHost. The latter will then pass a -// SharedMemoryBuffer to the ProducerClient and tell it to start logging -// events of a given type into it. As chunks of the buffer gets filled -// up, the client will communicate this to the ProducerHost which will -// tell Perfetto to copy the finished chunks into its central storage -// and pass to any consumers. +// Brief description of the flow: There's a per-process ProducerClient which +// connects to the central PerfettoService and establishes a two-way connection +// with a ProducerHost. The latter will then pass a SharedMemoryBuffer to the +// ProducerClient and tell it to start logging events of a given type into it. +// As chunks of the buffer get filled up, the client will communicate this to +// the ProducerHost, which will tell Perfetto to copy the finished chunks into +// its central storage and pass them on to its consumers. // For a more complete explanation of a Perfetto tracing session, see // https://android.googlesource.com/platform/external/perfetto/+/master/docs/life-of-a-tracing-session.md @@ -22,22 +21,22 @@ // See https://android.googlesource.com/platform/external/perfetto/ // for the full documentation of Perfetto concepts and its shared memory ABI. -// Used by the CommitDataRequest() method (client process->service) to signal when -// a chunk is (segment/page of the shared memory buffer which is -// owned by a per-thread TraceWriter) the central Perfetto service that it's -// ready for consumption (flushed or fully written). +// Passed by the client process as part of CommitDataRequest() to the central +// Perfetto service. Signals that a chunk (segment/page of the shared memory +// buffer which is owned by a per-thread TraceWriter) is ready for consumption +// (flushed or fully written). struct ChunksToMove { // The page index within the producer:service shared memory buffer. uint32 page; // The chunk index within the given page. uint32 chunk; - // The target ring-buffer in the service where the chunk should be copied into. + // The target ring-buffer in the service that the chunk should be copied into. uint32 target_buffer; }; -// Used by the CommitDataRequest method (client process -> service) to -// patch previously written chunks (to fill in size fields when protos -// span multiple chunks, for example). +// Passed by the client process as part of CommitDataRequest() to the central +// Perfetto service. Used to patch previously written chunks (for example, to +// fill in size fields when protos span multiple chunks). struct ChunkPatch { // Offset relative to the chunk defined in ChunksToPatch. uint32 offset; @@ -45,8 +44,9 @@ }; struct ChunksToPatch { - // The triplet {target_buffer, writer_id, chunk_id} uniquely identified a chunk that has - // been copied over into the main, non-shared, trace buffer owned by the service. + // The triplet {target_buffer, writer_id, chunk_id} uniquely identifies a + // chunk that has been copied over into the main, non-shared, trace buffer + // owned by the service. uint32 target_buffer; uint32 writer_id; uint32 chunk_id; @@ -73,7 +73,7 @@ }; interface ProducerHost { - // Called by a ProducerClient to asks the service to: + // Called by a ProducerClient to ask the service to: // 1) Move data from the shared memory buffer into the final tracing buffer // owned by the service (through the |chunks_to_move|). // 2) Patch data (i.e. apply diff) that has been previously copied into the @@ -82,8 +82,8 @@ // requests. CommitData(CommitDataRequest data_request); - // Called by a ProducerClient to let the Host know it can provide a - // specific datasource. + // Called by a ProducerClient to let the Host know it can provide a specific + // datasource. RegisterDataSource(DataSourceRegistration registration_info); // Called to let the Service know that a flush is complete. @@ -104,5 +104,6 @@ }; interface PerfettoService { - ConnectToProducerHost(ProducerClient producer_client, ProducerHost& producer_host); + ConnectToProducerHost(ProducerClient producer_client, + ProducerHost& producer_host); };
diff --git a/services/ws/client_root.cc b/services/ws/client_root.cc index 5baf778..e351534 100644 --- a/services/ws/client_root.cc +++ b/services/ws/client_root.cc
@@ -237,6 +237,8 @@ ServerWindow* server_window = ServerWindow::GetMayBeNull(window_); if (server_window->local_surface_id().has_value()) { DCHECK(!fallback_surface_info_); + if (!client_surface_embedder_->HasPrimarySurfaceId()) + UpdatePrimarySurfaceId(); client_surface_embedder_->SetFallbackSurfaceInfo(surface_info); } else { fallback_surface_info_ = std::make_unique<viz::SurfaceInfo>(surface_info);
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 750ca67..7414476 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1075,7 +1075,9 @@ "windows", "mac", "chromeos", - "linux" + "linux", + "android", + "ios" ], "experiments": [ { @@ -1486,28 +1488,6 @@ ] } ], - "DelayRequestsOnMultiplexedConnections": [ - { - "platforms": [ - "android", - "windows", - "mac", - "chromeos", - "linux" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "MaxEffectiveConnectionType": "3G" - }, - "enable_features": [ - "DelayRequestsOnMultiplexedConnections" - ] - } - ] - } - ], "DesktopIOSPromotion": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 19f2a1e6..8015de2 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -70,6 +70,7 @@ crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-in-inline-nested-002.xht [ Pass ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-in-inline-remove-006.xht [ Pass ] crbug.com/591099 external/wpt/css/CSS2/text/white-space-mixed-003.xht [ Pass ] +crbug.com/591099 external/wpt/css/css-flexbox/flex-minimum-height-flex-items-009.html [ Pass ] crbug.com/714962 external/wpt/css/css-fonts/font-features-across-space-1.html [ Pass ] crbug.com/714962 external/wpt/css/css-fonts/font-features-across-space-3.html [ Pass ] crbug.com/591099 external/wpt/css/css-multicol/multicol-span-none-001.xht [ Pass ] @@ -189,10 +190,10 @@ crbug.com/591099 external/wpt/css/css-writing-modes/sizing-orthog-vrl-in-htb-004.xht [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/vertical-alignment-003.xht [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/vertical-alignment-009.xht [ Pass ] -crbug.com/591099 external/wpt/css/cssom/cssstyledeclaration-mutationrecord-001.html [ Pass ] crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint-inline-vrl-ltr.html [ Pass ] crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint-inline-vrl-rtl.html [ Pass ] crbug.com/591099 external/wpt/css/cssom-view/offsetTopLeftInline.html [ Pass ] +crbug.com/591099 external/wpt/css/cssom/cssstyledeclaration-mutationrecord-001.html [ Pass ] crbug.com/591099 external/wpt/css/selectors/selector-placeholder-shown-type-change-001.html [ Pass ] crbug.com/591099 external/wpt/css/selectors/selector-read-write-type-change-002.html [ Pass ] crbug.com/591099 external/wpt/css/selectors/selector-required-type-change-002.html [ Pass ] @@ -239,7 +240,7 @@ crbug.com/591099 external/wpt/fetch/api/redirect/redirect-count.any.worker.html [ Pass ] crbug.com/591099 external/wpt/fetch/api/request/request-keepalive-quota.html?include=slow-2 [ Pass ] crbug.com/591099 external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] -crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ] +crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure Pass ] crbug.com/591099 external/wpt/html-media-capture/capture_audio_cancel-manual.html [ Failure ] crbug.com/591099 external/wpt/html-media-capture/capture_image_cancel-manual.html [ Failure ] crbug.com/591099 external/wpt/html-media-capture/capture_video_cancel-manual.html [ Failure ] @@ -356,6 +357,7 @@ crbug.com/591099 fast/events/touch/compositor-touch-hit-rects.html [ Failure ] crbug.com/591099 fast/events/wheel/mainthread-touchpad-fling-latching.html [ Pass ] crbug.com/591099 fast/events/wheel/wheel-scroll-latching-on-scrollbar.html [ Pass ] +crbug.com/591099 fast/events/window-onerror-11.html [ Failure ] crbug.com/591099 fast/forms/placeholder-position.html [ Failure ] crbug.com/835484 fast/inline/continuation-outlines-with-layers.html [ Failure ] crbug.com/835484 fast/inline/continuation-outlines.html [ Failure ] @@ -407,7 +409,7 @@ crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-appcache.https.html [ Crash Failure ] crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.https.html [ Crash Failure Pass ] crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Crash ] -crbug.com/591099 idle-callback/test-runner-run-idle-tasks.html [ Crash Pass ] +crbug.com/591099 idle-callback/test-runner-run-idle-tasks.html [ Crash Pass Timeout ] crbug.com/591099 images/color-profile-image-filter-all.html [ Failure ] crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-pseudo-element.js [ Failure ] crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot.js [ Failure ] @@ -484,11 +486,12 @@ crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/wheel/mainthread-touchpad-fling-latching.html [ Pass ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/wheel/wheel-scroll-latching-on-scrollbar.html [ Pass ] +crbug.com/591099 virtual/mouseevent_fractional/fast/events/window-onerror-11.html [ Failure ] crbug.com/591099 virtual/new-remote-playback-pipeline/ [ Skip ] crbug.com/591099 virtual/outofblink-cors-ns/external/wpt/fetch/api/redirect/redirect-count.any.html [ Pass ] crbug.com/591099 virtual/outofblink-cors-ns/external/wpt/fetch/api/redirect/redirect-count.any.worker.html [ Pass ] crbug.com/591099 virtual/outofblink-cors-ns/external/wpt/fetch/api/request/request-keepalive-quota.html?include=slow-2 [ Pass ] -crbug.com/591099 virtual/outofblink-cors-ns/http/tests/fetch/chromium/release-handle-crash.html [ Pass ] +crbug.com/591099 virtual/outofblink-cors-ns/http/tests/fetch/chromium/release-handle-crash.html [ Crash Pass ] crbug.com/591099 virtual/outofblink-cors-ns/http/tests/security/cors-rfc1918/addressspace-document-appcache.https.html [ Crash Failure ] crbug.com/591099 virtual/outofblink-cors-ns/http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.https.html [ Crash Failure Pass ] crbug.com/591099 virtual/outofblink-cors-ns/http/tests/security/document-domain-canonicalizes.html [ Pass ] @@ -512,5 +515,6 @@ crbug.com/591099 virtual/threaded/ [ Skip ] crbug.com/591099 virtual/user-activation-v2/fast/events/mouse-cursor.html [ Failure ] crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/window-onerror-11.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/video-layer-crash.html [ Crash Pass ] crbug.com/591099 virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index a94b1f6..a7e0c82 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -4616,17 +4616,6 @@ crbug.com/860368 virtual/video-surface-layer/media/controls/modern/singletouch-on-play-button.html [ Timeout Pass ] crbug.com/860368 virtual/video-surface-layer/media/controls/lazy-loaded-style.html [ Pass Failure ] -# TODO(senorblanco): rebaseline after Skia roll -crbug.com/802896 virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill.html [ Failure Pass ] - -# TODO(michaelludwig): rebaseline after Skia roll -crbug.com/888675 virtual/gpu/fast/canvas/fillrect_gradient.html [ Failure Pass ] -crbug.com/888675 virtual/gpu/fast/canvas/gradient-add-second-start-end-stop.html [ Failure Pass ] - -# TODO(bsalomon): Small changes in antialiasing of textured quads in Skia roll -crbug.com/889940 virtual/gpu/fast/canvas/canvas-drawImage-antiAlias.html [ Failure Pass ] -crbug.com/889940 virtual/gpu-rasterization/images/cross-fade-background-size.html [ Failure Pass Timeout ] - crbug.com/813704 http/tests/images/png-partial-load-as-document.html [ Failure Pass ] crbug.com/806645 [ Win7 Mac ] http/tests/devtools/elements/elements-panel-rewrite-href.js [ Failure Pass ] @@ -4761,10 +4750,8 @@ crbug.com/831796 fast/events/autoscroll-in-textfield.html [ Failure Pass ] crbug.com/831685 [ Linux ] external/wpt/2dcontext/compositing/2d.composite.canvas.lighter.html [ Pass Timeout ] crbug.com/831673 http/tests/devtools/reveal-objects.js [ Pass Timeout ] -# TODO(michaelludwig) - Restore after Skia suppression is removed for crbug.com/888675 -# crbug.com/831496 virtual/gpu/fast/canvas/fillrect_gradient.html [ Pass Timeout ] -# TODO(bsalomon) - Restore after more general suppression removed for crbug.com/889940 -# crbug.com/831482 [ Linux ] virtual/gpu-rasterization/images/cross-fade-background-size.html [ Pass Timeout ] +crbug.com/831496 virtual/gpu/fast/canvas/fillrect_gradient.html [ Pass Timeout ] +crbug.com/831482 [ Linux ] virtual/gpu-rasterization/images/cross-fade-background-size.html [ Pass Timeout ] crbug.com/831249 [ Linux ] virtual/gpu/fast/canvas/canvas-filter-svg-inline.html [ Pass Timeout ] crbug.com/829952 fast/webgl/texImage-imageBitmap-from-image-resize.html [ Pass Timeout ] crbug.com/829938 [ Linux ] css3/filters/blur-filter-page-scroll.html [ Pass Timeout ] @@ -5244,10 +5231,6 @@ crbug.com/886566 http/tests/csspaint/invalidation-border-image.html [ Pass Timeout ] crbug.com/886566 http/tests/csspaint/invalidation-content-image.html [ Pass Timeout ] -# Skia roll -crbug.com/884166 virtual/gpu/fast/canvas/canvas-arc-circumference.html [ Failure ] -crbug.com/884166 virtual/gpu/fast/canvas/canvas-ellipse-circumference.html [ Failure ] - # Enable AnimationWorklet tests for mainthread crbug.com/887659 animations/animationworklet/animation-worklet-inside-iframe.html [ Failure ] crbug.com/887659 animations/animationworklet/animator-animate.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/editing/spelling/context_click_select_misspelling.html b/third_party/WebKit/LayoutTests/editing/spelling/context_click_select_misspelling.html index 0f9bbdd2..4598373 100644 --- a/third_party/WebKit/LayoutTests/editing/spelling/context_click_select_misspelling.html +++ b/third_party/WebKit/LayoutTests/editing/spelling/context_click_select_misspelling.html
@@ -97,31 +97,18 @@ title: 'Context click at boundary of misspelled word.', callback: sample => test(() => { const container = sample.document.querySelector('div'); - const shouldSelect = isMac(navigator.platform); - if (shouldSelect) { - // On Mac, right-clicking immediately before a word will select it. - assertContextClickSelection( + assertContextClickSelection( container, 0, 'wellcome', 'Context clicking immediately before "wellcome" selects it'); - // De-select "wellcome"; otherwise, context-clicking immediately after "wellcome" will - // not change the selection (since it would select a space and not another word) - container.ownerDocument.getSelection().removeAllRanges(); + // De-select "wellcome" to ensure that context-clicking immediately after + // "wellcome" will select it again. + container.ownerDocument.getSelection().removeAllRanges(); - // On Mac, right-clicking immediately after a word will select the space after it. - assertContextClickSelection( - container, 8, ' ', - 'Context clicking immediately after "wellcome" selects the space after it'); - return; - } - + // Right-clicking immediately after a word will select the whole word. assertContextClickSelection( - container, 0, '', - 'Context clicking immediately before "wellcome" does not select it'); - - assertContextClickSelection( - container, 8, '', - 'Context clicking immediately after "wellcome" does not select it'); + container, 8, 'wellcome', + 'Context clicking immediately after "wellcome" selects it'); }, 'Context clicking immediately before or after misspelled word in editable DIV does not select it.', {sample: sample, blockHeldTest: true})
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json index 7ec1a9a..499dd30 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json
@@ -163770,11 +163770,6 @@ {} ] ], - "html/webappapis/scripting/events/onerroreventhandler-expected.txt": [ - [ - {} - ] - ], "html/webappapis/scripting/events/onerroreventhandler-frame.html": [ [ {} @@ -163800,21 +163795,6 @@ {} ] ], - "html/webappapis/scripting/processing-model-2/body-onerror-compile-error-data-url-expected.txt": [ - [ - {} - ] - ], - "html/webappapis/scripting/processing-model-2/body-onerror-compile-error-expected.txt": [ - [ - {} - ] - ], - "html/webappapis/scripting/processing-model-2/body-onerror-runtime-error-expected.txt": [ - [ - {} - ] - ], "html/webappapis/scripting/processing-model-2/compile-error-cross-origin-setInterval-expected.txt": [ [ {} @@ -175625,11 +175605,6 @@ {} ] ], - "svg/interfaces-expected.txt": [ - [ - {} - ] - ], "svg/linking/reftests/href-a-element-ref.html": [ [ {} @@ -206579,6 +206554,42 @@ {} ] ], + "css/cssom-view/elementsFromPoint-inline-htb-ltr.html": [ + [ + "/css/cssom-view/elementsFromPoint-inline-htb-ltr.html", + {} + ] + ], + "css/cssom-view/elementsFromPoint-inline-htb-rtl.html": [ + [ + "/css/cssom-view/elementsFromPoint-inline-htb-rtl.html", + {} + ] + ], + "css/cssom-view/elementsFromPoint-inline-vlr-ltr.html": [ + [ + "/css/cssom-view/elementsFromPoint-inline-vlr-ltr.html", + {} + ] + ], + "css/cssom-view/elementsFromPoint-inline-vlr-rtl.html": [ + [ + "/css/cssom-view/elementsFromPoint-inline-vlr-rtl.html", + {} + ] + ], + "css/cssom-view/elementsFromPoint-inline-vrl-ltr.html": [ + [ + "/css/cssom-view/elementsFromPoint-inline-vrl-ltr.html", + {} + ] + ], + "css/cssom-view/elementsFromPoint-inline-vrl-rtl.html": [ + [ + "/css/cssom-view/elementsFromPoint-inline-vrl-rtl.html", + {} + ] + ], "css/cssom-view/elementsFromPoint-invalid-cases.html": [ [ "/css/cssom-view/elementsFromPoint-invalid-cases.html", @@ -359406,6 +359417,30 @@ "3bba161b47d1ff3424b331b69444051af1300d71", "testharness" ], + "css/cssom-view/elementsFromPoint-inline-htb-ltr.html": [ + "5d6f92f3d1ff2e4949f2379b70e283526859c72e", + "testharness" + ], + "css/cssom-view/elementsFromPoint-inline-htb-rtl.html": [ + "3ff7f0139906313c69b8c9a612b86f5fdb622717", + "testharness" + ], + "css/cssom-view/elementsFromPoint-inline-vlr-ltr.html": [ + "c22c0051594c781efaa12422faa57cb662fb8978", + "testharness" + ], + "css/cssom-view/elementsFromPoint-inline-vlr-rtl.html": [ + "e8e600a8b8cc0ad977d9834c194d7e58fadd622a", + "testharness" + ], + "css/cssom-view/elementsFromPoint-inline-vrl-ltr.html": [ + "598d41e41b57606b0b02bac899ecc38025f79edf", + "testharness" + ], + "css/cssom-view/elementsFromPoint-inline-vrl-rtl.html": [ + "4d93bf5210d2f2fe93b5bfe5e26ec1b9b0a14b02", + "testharness" + ], "css/cssom-view/elementsFromPoint-invalid-cases.html": [ "369cffcd31ad9ef8a2946a9974f4030a5798bfed", "testharness" @@ -359547,7 +359582,7 @@ "testharness" ], "css/cssom-view/scroll-behavior-smooth-positions.html": [ - "19e317d5e4b9e65aca7df6becb35481ad8125bac", + "14e4c94886ae0383e4420a2ff916f8a7a0a4e3ef", "testharness" ], "css/cssom-view/scroll-behavior-smooth.html": [ @@ -394934,10 +394969,6 @@ "70b5ff6e568bc3885085f58d07a0b183bf9434ef", "testharness" ], - "html/webappapis/scripting/events/onerroreventhandler-expected.txt": [ - "6d7a7f24ed26e3b027a5b4033fbe3b2899c95ff5", - "support" - ], "html/webappapis/scripting/events/onerroreventhandler-frame.html": [ "79e4af3020681b074345e00f846925762a098acc", "support" @@ -394970,26 +395001,14 @@ "dbb1cdd5a90171f86eb25da035402b1d23467107", "testharness" ], - "html/webappapis/scripting/processing-model-2/body-onerror-compile-error-data-url-expected.txt": [ - "7069faa8b68e27ea90a48a0af4c4c9acf78b4bcc", - "support" - ], "html/webappapis/scripting/processing-model-2/body-onerror-compile-error-data-url.html": [ "66e1dfed4dd182ab33a68d79881d6096fd13ba67", "testharness" ], - "html/webappapis/scripting/processing-model-2/body-onerror-compile-error-expected.txt": [ - "8087429246ccbabd60803fb3ee1292dd7e52a165", - "support" - ], "html/webappapis/scripting/processing-model-2/body-onerror-compile-error.html": [ "0f65f73999172bebf4157e3fddc7313293fba06e", "testharness" ], - "html/webappapis/scripting/processing-model-2/body-onerror-runtime-error-expected.txt": [ - "7a55daf59004eefb18be19f4aa82abb92ca764a5", - "support" - ], "html/webappapis/scripting/processing-model-2/body-onerror-runtime-error.html": [ "faaddd9ed9541766576e084a76a762007dd9a2cb", "testharness" @@ -418383,7 +418402,7 @@ "support" ], "resources/testharness.js": [ - "0a92cf10a3d57f8a38921f316f78f2fccc029fb0", + "867f88b3bcfb6394a548c43d09ff0231ea7abd2a", "support" ], "resources/testharness.js.headers": [ @@ -424526,10 +424545,6 @@ "46e8aaee6afa6b67a2fb515d5155849dea214c00", "testharness" ], - "svg/interfaces-expected.txt": [ - "4e71ea453b6d15851a28d23862635eca3bac4e60", - "support" - ], "svg/linking/reftests/href-a-element-attr-change.html": [ "c74b2e015613a09d1cecb5a0c3136d26f07e2a5b", "reftest"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/abort.https.window.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/abort.https.window.js new file mode 100644 index 0000000..588fcac --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/abort.https.window.js
@@ -0,0 +1,50 @@ +// META: script=/service-workers/service-worker/resources/test-helpers.sub.js +// META: script=resources/utils.js +'use strict'; + +// Covers basic functionality provided by BackgroundFetchManager.abort(). +// https://wicg.github.io/background-fetch/#background-fetch-registration-abort + +backgroundFetchTest(async (test, backgroundFetch) => { + const registration = await backgroundFetch.fetch( + uniqueId(), + ['resources/feature-name.txt', '/serviceworker/resources/slow-response.php']); + + assert_true(await registration.abort()); + assert_false(await registration.abort()); + +}, 'Aborting the same registration twice fails'); + +backgroundFetchTest(async (test, backgroundFetch) => { + const registration = await backgroundFetch.fetch( + uniqueId(), + ['resources/feature-name.txt', '/serviceworker/resources/slow-response.php']); + const resultPromise = getMessageFromServiceWorker(); + + await new Promise(resolve => { + registration.onprogress = async (e) => { + // The size of the first file. + if (e.target.downloaded < 16) + return; + + // At this point the first file is downloaded. + + assert_true(await registration.abort()); + + const {type, eventRegistration, results} = await resultPromise; + + assert_equals(eventRegistration.result, 'failure'); + assert_equals(eventRegistration.failureReason, 'aborted'); + + assert_equals(type, 'backgroundfetchabort'); + assert_equals(results.length, 1); + + assert_true(results[0].url.includes('resources/feature-name.txt')); + assert_equals(results[0].status, 200); + assert_equals(results[0].text, 'Background Fetch'); + + resolve(); + }; + }); + +}, 'Calling BackgroundFetchRegistration.abort sets the correct fields and responses are still available'); \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/get.https.window.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/get.https.window.js index cd1dc3a..cb678e6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/get.https.window.js +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/get.https.window.js
@@ -26,6 +26,7 @@ backgroundFetchTest(async (test, backgroundFetch) => { // The |id| parameter to the BackgroundFetchManager.get() method is required. await promise_rejects(test, new TypeError(), backgroundFetch.get()); + await promise_rejects(test, new TypeError(), backgroundFetch.get('')); const registration = await backgroundFetch.get('my-id'); assert_equals(registration, undefined);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/service_workers/sw.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/service_workers/sw.js index af4655d..2e3fbfff1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/service_workers/sw.js +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/service_workers/sw.js
@@ -27,3 +27,4 @@ self.addEventListener('backgroundfetchsuccess', handleBackgroundFetchUpdateEvent); self.addEventListener('backgroundfetchfail', handleBackgroundFetchUpdateEvent); +self.addEventListener('backgroundfetchabort', handleBackgroundFetchUpdateEvent);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/scroll-behavior-smooth-positions.html b/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/scroll-behavior-smooth-positions.html index 19e317d..14e4c94 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/scroll-behavior-smooth-positions.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/scroll-behavior-smooth-positions.html
@@ -109,7 +109,7 @@ }, "Scroll positions when aborting a smooth scrolling with another smooth scrolling"); promise_test(() => { - return new Promise(function(resolve) { + return new Promise(function(resolve, reject) { resetScroll(overflowNode); var initialScrollAborted = false; var oldLeft = overflowNode.scrollLeft;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js b/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js index 0a92cf1..867f88b3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js
@@ -754,7 +754,7 @@ } if (tests.file_is_test) { // file is test files never have asynchronous cleanup logic, - // meaning the fully-sycnronous `done` funtion can be used here. + // meaning the fully-sycnronous `done` function can be used here. tests.tests[0].done(); } tests.end_wait();
diff --git a/third_party/WebKit/LayoutTests/fast/scrolling/no-hover-during-scroll.html b/third_party/WebKit/LayoutTests/fast/scrolling/no-hover-during-scroll.html new file mode 100644 index 0000000..73d22ca --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/scrolling/no-hover-during-scroll.html
@@ -0,0 +1,101 @@ +<!DOCTYPE html> +<script src='../../resources/testharness.js'></script> +<script src='../../resources/testharnessreport.js'></script> +<script src='../../resources/gesture-util.js'></script> + +<style> + body, html { + margin: 0; + } + div { + height: 50px; + width: 100%; + } + + .hoverme { + background-color: rgb(0, 0, 255); + } + + .hoverme:hover { + background-color: rgb(255, 255, 0); + } + + .message { + width: 100%; + text-align: left; + } +</style> + +<div class="message"> + First move your mouse cursor to the page, you will see the text under the mouse cursor changed to "currently hovered". <br> + Scroll mouse wheel slowly, you should not see any text under the mouse changed to "currently hovered" while the scrolling is in process and finishes. +</div> + +<script> + let array; + const numHoverElements = 30; + const elementHeight = 50; + const textWhenNotHovered = "hover over me"; + const textWhenHovered = "currently hovered"; + const textWhenWasHovered = "was hovered"; + const mouse = GestureSourceType.MOUSE_INPUT; + + function buildPage() { + for (let i = 0; i < numHoverElements; i++) { + let div = document.createElement('div'); + div.className = "hoverme"; + div.innerHTML = textWhenNotHovered; + document.body.appendChild(div); + } + + array = document.getElementsByClassName('hoverme'); + + for (let element of array) { + element.addEventListener('mouseover', function (e) { + this.innerHTML = textWhenHovered; + }); + element.addEventListener('mouseout', function (e) { + this.innerHTML = textWhenWasHovered; + }); + } + } + + window.onload = async () => { + if (window.internals) { + internals.settings.setScrollAnimatorEnabled(false); + internals.runtimeFlags.noHoverDuringScrollEnabled = true; + } + + buildPage(); + await waitForCompositorCommit(); + + promise_test(async () => { + let x = array[0].offsetLeft + 10; + let y = array[0].offsetTop + 10; + // Move cursor to 1st element. + await mouseMoveTo(x, y); + await waitFor( () => { return array[0].innerHTML == textWhenHovered;}, 'wait for move to 1st element'); + assert_equals(array[0].innerHTML, textWhenHovered); + assert_equals(array[1].innerHTML, textWhenNotHovered); + assert_equals(getComputedStyle(array[0]).backgroundColor, 'rgb(255, 255, 0)'); + + // Scroll end up at 4th element. Hover state does not update during scrolling + // so that 2nd, 3rd and 4th elements do not see the mouseover and mouseout events. + assert_equals(document.scrollingElement.scrollTop, 0); + await smoothScroll(3 * elementHeight, x, y, mouse, 'down', SPEED_INSTANT); + // Wait enough time to see if we fire a fake mouse move event to update the hover state. + await waitForAnimationEnd(() => { return document.scrollingElement.scrollTop; }, 200, 60); + assert_approx_equals(document.scrollingElement.scrollTop, 3 * elementHeight, 10); + assert_equals(array[0].innerHTML, textWhenHovered); + assert_equals(array[1].innerHTML, textWhenNotHovered); + assert_equals(array[2].innerHTML, textWhenNotHovered); + assert_equals(array[3].innerHTML, textWhenNotHovered); + assert_equals(array[4].innerHTML, textWhenNotHovered); + assert_equals(getComputedStyle(array[0]).backgroundColor, 'rgb(255, 255, 0)'); + assert_equals(getComputedStyle(array[1]).backgroundColor, 'rgb(0, 0, 255)'); + assert_equals(getComputedStyle(array[2]).backgroundColor, 'rgb(0, 0, 255)'); + assert_equals(getComputedStyle(array[3]).backgroundColor, 'rgb(0, 0, 255)'); + }, 'Mouse wheel scroll on the page, no hover update during scrolling.'); + } + +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/fillrect_gradient-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/fillrect_gradient-expected.png index 611aef1..aa339c7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/fillrect_gradient-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/fillrect_gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png index 9171c78..c0f1235e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/fillrect_gradient-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/fillrect_gradient-expected.png index a8ad1a83..fe14384 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/fillrect_gradient-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/fillrect_gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png index 6ee9054..3855495 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/fillrect_gradient-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/fillrect_gradient-expected.png index d385b870..2ba127b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/fillrect_gradient-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/fillrect_gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png index f9dcd9bd..ae158ca 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-drawImage-antiAlias-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-drawImage-antiAlias-expected.png index 5076f66..6e945b8 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-drawImage-antiAlias-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-drawImage-antiAlias-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png index 5346060..0af0d13 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png new file mode 100644 index 0000000..540a17bf --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/gradient-add-second-start-end-stop-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/gradient-add-second-start-end-stop-expected.png index 069dc3f6..85e0988 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/gradient-add-second-start-end-stop-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/gradient-add-second-start-end-stop-expected.png Binary files differ
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 8df3300..562d3f1c 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -245,7 +245,6 @@ "platform/web_encrypted_media_key_information.h", "platform/web_encrypted_media_request.h", "platform/web_encrypted_media_types.h", - "platform/web_file_system.h", "platform/web_file_system_type.h", "platform/web_file_utilities.h", "platform/web_float_point.h",
diff --git a/third_party/blink/public/mojom/filesystem/file_system.mojom b/third_party/blink/public/mojom/filesystem/file_system.mojom index 8a03eb6..d33a4ee 100644 --- a/third_party/blink/public/mojom/filesystem/file_system.mojom +++ b/third_party/blink/public/mojom/filesystem/file_system.mojom
@@ -219,9 +219,7 @@ // success. // TODO(https://crbug.com/878581): Add more options to this method to support // multiple files, directories, "open" vs "save" dialogs, etc. - // TODO(https://crbug.com/873661): Make interface per frame/worker and remove - // |render_frame_id|. - ChooseEntry(int32 render_frame_id) => + ChooseEntry() => (mojo_base.mojom.FileError error_code, array<FileSystemEntry> entries); };
diff --git a/third_party/blink/public/mojom/service_worker/service_worker_stream_handle.mojom b/third_party/blink/public/mojom/service_worker/service_worker_stream_handle.mojom index 968a6e8a..5b216daf 100644 --- a/third_party/blink/public/mojom/service_worker/service_worker_stream_handle.mojom +++ b/third_party/blink/public/mojom/service_worker/service_worker_stream_handle.mojom
@@ -14,4 +14,4 @@ struct ServiceWorkerStreamHandle { handle<data_pipe_consumer> stream; ServiceWorkerStreamCallback& callback_request; -}; \ No newline at end of file +};
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index 5fb1b09a..cf54bb45 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -106,7 +106,6 @@ class WebCookieJar; class WebCrypto; class WebDatabaseObserver; -class WebFileSystem; class WebGraphicsContext3DProvider; class WebImageCaptureFrameGrabber; class WebLocalFrame; @@ -284,9 +283,6 @@ // FileSystem ---------------------------------------------------------- - // Must return non-null. - virtual WebFileSystem* FileSystem() { return nullptr; } - // Return a filename-friendly identifier for an origin. virtual WebString FileSystemCreateOriginIdentifier( const WebSecurityOrigin& origin) {
diff --git a/third_party/blink/public/platform/web_file_system.h b/third_party/blink/public/platform/web_file_system.h deleted file mode 100644 index 87a373ac..0000000 --- a/third_party/blink/public/platform/web_file_system.h +++ /dev/null
@@ -1,67 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_FILE_SYSTEM_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_FILE_SYSTEM_H_ - -#include "base/files/file.h" -#include "mojo/public/cpp/system/message_pipe.h" -#include "third_party/blink/public/platform/web_callbacks.h" -#include "third_party/blink/public/platform/web_common.h" -#include "third_party/blink/public/platform/web_file_system_type.h" -#include "third_party/blink/public/platform/web_url.h" -#include "third_party/blink/public/platform/web_vector.h" - -namespace blink { - -class WebFrame; - -class WebFileSystem { - public: - struct FileSystemEntry { - WebString file_system_id; - WebString base_name; - }; - - // Prompts the user to select a file from the native filesystem. Returns an - // error code if something failed, or a list of the selected entries on - // success. - using ChooseEntryCallbacks = - WebCallbacks<WebVector<FileSystemEntry>, base::File::Error>; - virtual void ChooseEntry(WebFrame* frame, - std::unique_ptr<ChooseEntryCallbacks>) = 0; - - protected: - virtual ~WebFileSystem() = default; -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/public/platform/web_rtc_dtmf_sender_handler_client.h b/third_party/blink/public/platform/web_rtc_dtmf_sender_handler_client.h index 26cbd03e..37e0e53 100644 --- a/third_party/blink/public/platform/web_rtc_dtmf_sender_handler_client.h +++ b/third_party/blink/public/platform/web_rtc_dtmf_sender_handler_client.h
@@ -36,8 +36,7 @@ public: virtual ~WebRTCDTMFSenderHandlerClient() = default; - virtual void DidPlayTone(const WebString& tone, - const WebString& tone_buffer) = 0; + virtual void DidPlayTone(const WebString& tone) = 0; }; } // namespace blink
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index e53fe60..a0eedbfd 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -114,6 +114,7 @@ BLINK_PLATFORM_EXPORT static void EnableNetInfoDownlinkMax(bool); BLINK_PLATFORM_EXPORT static void EnableNetworkService(bool); BLINK_PLATFORM_EXPORT static void EnableNoHoverAfterLayoutChange(bool); + BLINK_PLATFORM_EXPORT static void EnableNoHoverDuringScroll(bool); BLINK_PLATFORM_EXPORT static void EnableNotificationConstructor(bool); BLINK_PLATFORM_EXPORT static void EnableNotificationContentImage(bool); BLINK_PLATFORM_EXPORT static void EnableNotifications(bool);
diff --git a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h index db8b141..1f212bd 100644 --- a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h +++ b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h
@@ -45,7 +45,6 @@ namespace blink { struct WebCanMakePaymentEventData; -class WebDataConsumerHandle; class WebSecurityOrigin; class WebServiceWorkerRequest; class WebString; @@ -133,7 +132,7 @@ virtual void OnNavigationPreloadResponse( int fetch_event_id, std::unique_ptr<WebURLResponse>, - std::unique_ptr<WebDataConsumerHandle>) = 0; + mojo::ScopedDataPipeConsumerHandle) = 0; virtual void OnNavigationPreloadError( int fetch_event_id, std::unique_ptr<WebServiceWorkerError>) = 0;
diff --git a/third_party/blink/public/web/web_dom_file_system.h b/third_party/blink/public/web/web_dom_file_system.h index 77ed4b6..f277aed 100644 --- a/third_party/blink/public/web/web_dom_file_system.h +++ b/third_party/blink/public/web/web_dom_file_system.h
@@ -31,7 +31,7 @@ #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_DOM_FILE_SYSTEM_H_ #include "third_party/blink/public/platform/web_common.h" -#include "third_party/blink/public/platform/web_file_system.h" +#include "third_party/blink/public/platform/web_file_system_type.h" #include "third_party/blink/public/platform/web_private_ptr.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h"
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index 5acce58e..157eb43 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -47,7 +47,6 @@ #include "third_party/blink/public/platform/web_content_security_policy_struct.h" #include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/public/platform/web_effective_connection_type.h" -#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/public/platform/web_file_system_type.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/public/platform/web_loading_behavior_flag.h" @@ -401,9 +400,6 @@ // hasn't yet had a chance to run (and possibly alter/interrupt the submit.) virtual void WillSendSubmitEvent(const WebFormElement&) {} - // A form submission is about to occur. - virtual void WillSubmitForm(const WebFormElement&) {} - // A datasource has been created for a new navigation. The given // datasource will become the provisional datasource for the frame. virtual void DidCreateDocumentLoader(WebDocumentLoader*) {}
diff --git a/third_party/blink/public/web/web_settings.h b/third_party/blink/public/web/web_settings.h index 01592795..e39112b0 100644 --- a/third_party/blink/public/web/web_settings.h +++ b/third_party/blink/public/web/web_settings.h
@@ -225,7 +225,7 @@ virtual void SetAvailableHoverTypes(int) = 0; virtual void SetPrimaryHoverType(HoverType) = 0; virtual void SetPreferHiddenVolumeControls(bool) = 0; - virtual void SetShouldProtectAgainstIpcFlooding(bool) = 0; + virtual void SetShouldThrottlePushState(bool) = 0; virtual void SetRenderVSyncNotificationEnabled(bool) = 0; virtual void SetReportScreenSizeInPhysicalPixelsQuirk(bool) = 0; virtual void SetRubberBandingOnCompositorThread(bool) = 0;
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 160f1e5..a53c53d 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1850,6 +1850,7 @@ "fetch/bytes_consumer_test_util.h", "fetch/data_consumer_handle_test_util.cc", "fetch/data_consumer_handle_test_util.h", + "fetch/data_pipe_bytes_consumer_test.cc", "fetch/fetch_data_loader_test.cc", "fetch/fetch_header_list_test.cc", "fetch/fetch_response_data_test.cc", @@ -1886,6 +1887,7 @@ "frame/visual_viewport_test.cc", "fullscreen/scoped_allow_fullscreen_test.cc", "geometry/dom_matrix_test.cc", + "html/anchor_element_metrics_sender_test.cc", "html/anchor_element_metrics_test.cc", "html/canvas/canvas_async_blob_creator_test.cc", "html/canvas/canvas_font_cache_test.cc",
diff --git a/third_party/blink/renderer/core/css/font_face_cache.cc b/third_party/blink/renderer/core/css/font_face_cache.cc index 7da80b8..d36412d 100644 --- a/third_party/blink/renderer/core/css/font_face_cache.cc +++ b/third_party/blink/renderer/core/css/font_face_cache.cc
@@ -116,10 +116,13 @@ IncrementVersion(); } -void FontFaceCache::ClearCSSConnected() { +bool FontFaceCache::ClearCSSConnected() { + if (style_rule_to_font_face_.IsEmpty()) + return false; for (const auto& item : style_rule_to_font_face_) RemoveFontFace(item.value.Get(), true); style_rule_to_font_face_.clear(); + return true; } void FontFaceCache::ClearAll() {
diff --git a/third_party/blink/renderer/core/css/font_face_cache.h b/third_party/blink/renderer/core/css/font_face_cache.h index 68be77e3..cfec05ee 100644 --- a/third_party/blink/renderer/core/css/font_face_cache.h +++ b/third_party/blink/renderer/core/css/font_face_cache.h
@@ -50,7 +50,8 @@ void Add(const StyleRuleFontFace*, FontFace*); void Remove(const StyleRuleFontFace*); - void ClearCSSConnected(); + // Returns true if at least one font was removed. + bool ClearCSSConnected(); void ClearAll(); void AddFontFace(FontFace*, bool css_connected); void RemoveFontFace(FontFace*, bool css_connected);
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index fec361a0..acabb56 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -637,12 +637,6 @@ if (style.HasAppearance()) LayoutTheme::GetTheme().AdjustStyle(style, element); - // If we have first-letter pseudo style, transitions, or animations, do not - // share this style. - if (style.HasPseudoStyle(kPseudoIdFirstLetter) || style.Transitions() || - style.Animations()) - style.SetUnique(); - AdjustStyleForEditing(style); bool is_svg_root = false;
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc index ca097214..a214de2f 100644 --- a/third_party/blink/renderer/core/css/selector_checker.cc +++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -911,34 +911,26 @@ context.visited_match_type == kVisitedMatchEnabled; case CSSSelector::kPseudoDrag: if (mode_ == kResolvingStyle) { - if (context.in_rightmost_compound) { + if (context.in_rightmost_compound) element_style_->SetAffectedByDrag(); - } else { - element_style_->SetUnique(); + else element.SetChildrenOrSiblingsAffectedByDrag(); - } } return element.IsDragged(); case CSSSelector::kPseudoFocus: - if (mode_ == kResolvingStyle && !context.in_rightmost_compound) { - element_style_->SetUnique(); + if (mode_ == kResolvingStyle && !context.in_rightmost_compound) element.SetChildrenOrSiblingsAffectedByFocus(); - } return MatchesFocusPseudoClass(element); case CSSSelector::kPseudoFocusVisible: - if (mode_ == kResolvingStyle && !context.in_rightmost_compound) { - element_style_->SetUnique(); + if (mode_ == kResolvingStyle && !context.in_rightmost_compound) element.SetChildrenOrSiblingsAffectedByFocusVisible(); - } return MatchesFocusVisiblePseudoClass(element); case CSSSelector::kPseudoFocusWithin: if (mode_ == kResolvingStyle) { - if (context.in_rightmost_compound) { + if (context.in_rightmost_compound) element_style_->SetAffectedByFocusWithin(); - } else { - element_style_->SetUnique(); + else element.SetChildrenOrSiblingsAffectedByFocusWithin(); - } } probe::forcePseudoState(&element, CSSSelector::kPseudoFocusWithin, &force_pseudo_state); @@ -947,12 +939,10 @@ return element.HasFocusWithin(); case CSSSelector::kPseudoHover: if (mode_ == kResolvingStyle) { - if (context.in_rightmost_compound) { + if (context.in_rightmost_compound) element_style_->SetAffectedByHover(); - } else { - element_style_->SetUnique(); + else element.SetChildrenOrSiblingsAffectedByHover(); - } } if (!ShouldMatchHoverOrActive(context)) return false; @@ -963,12 +953,10 @@ return element.IsHovered(); case CSSSelector::kPseudoActive: if (mode_ == kResolvingStyle) { - if (context.in_rightmost_compound) { + if (context.in_rightmost_compound) element_style_->SetAffectedByActive(); - } else { - element_style_->SetUnique(); + else element.SetChildrenOrSiblingsAffectedByActive(); - } } if (!ShouldMatchHoverOrActive(context)) return false;
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 905593dd..d9c915c 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -343,7 +343,7 @@ } bool StyleEngine::ShouldUpdateDocumentStyleSheetCollection() const { - return all_tree_scopes_dirty_ || document_scope_dirty_ || font_cache_dirty_; + return all_tree_scopes_dirty_ || document_scope_dirty_; } bool StyleEngine::ShouldUpdateShadowTreeStyleSheetCollection() const { @@ -419,9 +419,7 @@ new_active_sheets.push_back(std::make_pair(sheet.second, rule_set)); } - ApplyRuleSetChanges(*document_, active_user_style_sheets_, new_active_sheets, - kInvalidateAllScopes); - + ApplyUserRuleSetChanges(active_user_style_sheets_, new_active_sheets); new_active_sheets.swap(active_user_style_sheets_); } @@ -593,25 +591,17 @@ environment_variables_ = nullptr; } -void StyleEngine::ClearFontCache() { - if (font_selector_) - font_selector_->GetFontFaceCache()->ClearCSSConnected(); - if (resolver_) +void StyleEngine::ClearFontCacheAndAddUserFonts() { + if (font_selector_ && + font_selector_->GetFontFaceCache()->ClearCSSConnected() && resolver_) { resolver_->InvalidateMatchedPropertiesCache(); -} - -void StyleEngine::RefreshFontCache() { - DCHECK(IsFontCacheDirty()); - - ClearFontCache(); + } // Rebuild the font cache with @font-face rules from user style sheets. for (unsigned i = 0; i < active_user_style_sheets_.size(); ++i) { DCHECK(active_user_style_sheets_[i].second); AddFontFaceRules(*active_user_style_sheets_[i].second); } - - font_cache_dirty_ = false; } void StyleEngine::UpdateGenericFontFamilySettings() { @@ -1284,90 +1274,11 @@ } // namespace -void StyleEngine::ApplyRuleSetChanges( +void StyleEngine::InvalidateForRuleSetChanges( TreeScope& tree_scope, - const ActiveStyleSheetVector& old_style_sheets, - const ActiveStyleSheetVector& new_style_sheets, + const HeapHashSet<Member<RuleSet>>& changed_rule_sets, + unsigned changed_rule_flags, InvalidationScope invalidation_scope) { - DCHECK(IsMaster()); - DCHECK(global_rule_set_); - HeapHashSet<Member<RuleSet>> changed_rule_sets; - - ActiveSheetsChange change = CompareActiveStyleSheets( - old_style_sheets, new_style_sheets, changed_rule_sets); - bool append_all_sheets = false; - - if (invalidation_scope == kInvalidateCurrentScope) { - if (ScopedStyleResolver* scoped_resolver = - tree_scope.GetScopedStyleResolver()) - append_all_sheets = scoped_resolver->NeedsAppendAllSheets(); - - // When the font cache is dirty we have to rebuild it and then add all the - // @font-face rules in the document scope. - if (IsFontCacheDirty()) { - DCHECK(tree_scope.RootNode().IsDocumentNode()); - append_all_sheets = true; - } - - if (change == kNoActiveSheetsChanged && !append_all_sheets) - return; - } - - // With rules added or removed, we need to re-aggregate rule meta data. - global_rule_set_->MarkDirty(); - - unsigned changed_rule_flags = GetRuleSetFlags(changed_rule_sets); - bool fonts_changed = tree_scope.RootNode().IsDocumentNode() && - (changed_rule_flags & kFontFaceRules); - bool keyframes_changed = changed_rule_flags & kKeyframesRules; - unsigned append_start_index = 0; - - // We don't need to mark the font cache dirty if new sheets are appended. - if (fonts_changed && (invalidation_scope == kInvalidateAllScopes || - change == kActiveSheetsChanged)) { - MarkFontCacheDirty(); - } - - if (invalidation_scope == kInvalidateAllScopes) { - if (keyframes_changed) { - if (change == kActiveSheetsChanged) - ClearKeyframeRules(); - - for (auto* it = new_style_sheets.begin(); it != new_style_sheets.end(); - it++) { - DCHECK(it->second); - AddKeyframeRules(*it->second); - } - } - } - - if (invalidation_scope == kInvalidateCurrentScope) { - if (IsFontCacheDirty()) { - DCHECK(tree_scope.RootNode().IsDocumentNode()); - DCHECK(change != kActiveSheetsAppended || append_all_sheets); - RefreshFontCache(); - } - - // - If all sheets were removed, we remove the ScopedStyleResolver. - // - If new sheets were appended to existing ones, start appending after the - // common prefix. - // - For other diffs, reset author style and re-add all sheets for the - // TreeScope. - if (tree_scope.GetScopedStyleResolver()) { - if (new_style_sheets.IsEmpty()) - ResetAuthorStyle(tree_scope); - else if (change == kActiveSheetsAppended && !append_all_sheets) - append_start_index = old_style_sheets.size(); - else - tree_scope.GetScopedStyleResolver()->ResetAuthorStyle(); - } - - if (!new_style_sheets.IsEmpty()) { - tree_scope.EnsureScopedStyleResolver().AppendActiveStyleSheets( - append_start_index, new_style_sheets); - } - } - if (tree_scope.GetDocument().HasPendingForcedStyleRecalc()) return; @@ -1382,15 +1293,14 @@ if (changed_rule_sets.IsEmpty()) return; - if (keyframes_changed) - ScopedStyleResolver::KeyframesRulesAdded(tree_scope); - Node& invalidation_root = ScopedStyleResolver::InvalidationRootForTreeScope(tree_scope); if (invalidation_root.GetStyleChangeType() >= kSubtreeStyleChange) return; - if (fonts_changed || (changed_rule_flags & kFullRecalcRules)) { + if (changed_rule_flags & kFullRecalcRules || + ((changed_rule_flags & kFontFaceRules) && + tree_scope.RootNode().IsDocumentNode())) { invalidation_root.SetNeedsStyleRecalc( kSubtreeStyleChange, StyleChangeReasonForTracing::Create( StyleChangeReason::kActiveStylesheetsUpdate)); @@ -1401,6 +1311,111 @@ invalidation_scope); } +void StyleEngine::ApplyUserRuleSetChanges( + const ActiveStyleSheetVector& old_style_sheets, + const ActiveStyleSheetVector& new_style_sheets) { + DCHECK(IsMaster()); + DCHECK(global_rule_set_); + HeapHashSet<Member<RuleSet>> changed_rule_sets; + + ActiveSheetsChange change = CompareActiveStyleSheets( + old_style_sheets, new_style_sheets, changed_rule_sets); + + if (change == kNoActiveSheetsChanged) + return; + + // With rules added or removed, we need to re-aggregate rule meta data. + global_rule_set_->MarkDirty(); + + unsigned changed_rule_flags = GetRuleSetFlags(changed_rule_sets); + if (changed_rule_flags & kFontFaceRules) { + if (ScopedStyleResolver* scoped_resolver = + GetDocument().GetScopedStyleResolver()) { + // User style and document scope author style shares the font cache. If + // @font-face rules are added/removed from user stylesheets, we need to + // reconstruct the font cache because @font-face rules from author style + // need to be added to the cache after user rules. + scoped_resolver->SetNeedsAppendAllSheets(); + MarkDocumentDirty(); + } else { + ClearFontCacheAndAddUserFonts(); + } + } + + if (changed_rule_flags & kKeyframesRules) { + if (change == kActiveSheetsChanged) + ClearKeyframeRules(); + + for (auto* it = new_style_sheets.begin(); it != new_style_sheets.end(); + it++) { + DCHECK(it->second); + AddKeyframeRules(*it->second); + } + ScopedStyleResolver::KeyframesRulesAdded(GetDocument()); + } + + InvalidateForRuleSetChanges(GetDocument(), changed_rule_sets, + changed_rule_flags, kInvalidateAllScopes); +} + +void StyleEngine::ApplyRuleSetChanges( + TreeScope& tree_scope, + const ActiveStyleSheetVector& old_style_sheets, + const ActiveStyleSheetVector& new_style_sheets) { + DCHECK(IsMaster()); + DCHECK(global_rule_set_); + HeapHashSet<Member<RuleSet>> changed_rule_sets; + + ActiveSheetsChange change = CompareActiveStyleSheets( + old_style_sheets, new_style_sheets, changed_rule_sets); + + unsigned changed_rule_flags = GetRuleSetFlags(changed_rule_sets); + + bool rebuild_font_cache = change == kActiveSheetsChanged && + (changed_rule_flags & kFontFaceRules) && + tree_scope.RootNode().IsDocumentNode(); + ScopedStyleResolver* scoped_resolver = tree_scope.GetScopedStyleResolver(); + if (scoped_resolver && scoped_resolver->NeedsAppendAllSheets()) { + rebuild_font_cache = true; + change = kActiveSheetsChanged; + } + + if (change == kNoActiveSheetsChanged) + return; + + // With rules added or removed, we need to re-aggregate rule meta data. + global_rule_set_->MarkDirty(); + + if (changed_rule_flags & kKeyframesRules) + ScopedStyleResolver::KeyframesRulesAdded(tree_scope); + + if (rebuild_font_cache) + ClearFontCacheAndAddUserFonts(); + + unsigned append_start_index = 0; + if (scoped_resolver) { + // - If all sheets were removed, we remove the ScopedStyleResolver. + // - If new sheets were appended to existing ones, start appending after the + // common prefix. + // - For other diffs, reset author style and re-add all sheets for the + // TreeScope. + if (new_style_sheets.IsEmpty()) + ResetAuthorStyle(tree_scope); + else if (change == kActiveSheetsAppended) + append_start_index = old_style_sheets.size(); + else + scoped_resolver->ResetAuthorStyle(); + } + + if (!new_style_sheets.IsEmpty()) { + tree_scope.EnsureScopedStyleResolver().AppendActiveStyleSheets( + append_start_index, new_style_sheets); + } + + InvalidateForRuleSetChanges(tree_scope, changed_rule_sets, changed_rule_flags, + kInvalidateCurrentScope); +} + const MediaQueryEvaluator& StyleEngine::EnsureMediaQueryEvaluator() { if (!media_query_evaluator_) { if (GetDocument().GetFrame()) {
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index 9573adf..5805ffd 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -318,8 +318,9 @@ void ApplyRuleSetChanges(TreeScope&, const ActiveStyleSheetVector& old_style_sheets, - const ActiveStyleSheetVector& new_style_sheets, - InvalidationScope = kInvalidateCurrentScope); + const ActiveStyleSheetVector& new_style_sheets); + void ApplyUserRuleSetChanges(const ActiveStyleSheetVector& old_style_sheets, + const ActiveStyleSheetVector& new_style_sheets); void CollectMatchingUserRules(ElementRuleCollector&) const; @@ -413,6 +414,11 @@ void ScheduleTypeRuleSetInvalidations(ContainerNode&, const HeapHashSet<Member<RuleSet>>&); void InvalidateSlottedElements(HTMLSlotElement&); + void InvalidateForRuleSetChanges( + TreeScope& tree_scope, + const HeapHashSet<Member<RuleSet>>& changed_rule_sets, + unsigned changed_rule_flags, + InvalidationScope invalidation_scope); void UpdateViewport(); void UpdateActiveUserStyleSheets(); @@ -425,11 +431,7 @@ const MediaQueryEvaluator& EnsureMediaQueryEvaluator(); void UpdateStyleSheetList(TreeScope&); - void ClearFontCache(); - void RefreshFontCache(); - void MarkFontCacheDirty() { font_cache_dirty_ = true; } - bool IsFontCacheDirty() const { return font_cache_dirty_; } - + void ClearFontCacheAndAddUserFonts(); void ClearKeyframeRules() { keyframes_rule_map_.clear(); } void AddFontFaceRules(const RuleSet&); @@ -492,7 +494,6 @@ HeapHashSet<Member<Element>> whitespace_reattach_set_; Member<CSSFontSelector> font_selector_; - bool font_cache_dirty_ = false; HeapHashMap<AtomicString, WeakMember<StyleSheetContents>> text_to_sheet_cache_;
diff --git a/third_party/blink/renderer/core/editing/ephemeral_range.h b/third_party/blink/renderer/core/editing/ephemeral_range.h index c247e84e..5a52b5a 100644 --- a/third_party/blink/renderer/core/editing/ephemeral_range.h +++ b/third_party/blink/renderer/core/editing/ephemeral_range.h
@@ -107,7 +107,7 @@ Node* CommonAncestorContainer() const; - // Returns true if |m_startPositoin| == |m_endPosition| or |isNull()|. + // Returns true if |m_startPosition| == |m_endPosition| or |isNull()|. bool IsCollapsed() const; bool IsNull() const { DCHECK(IsValid());
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc index fdf850c..2849df0a 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
@@ -48,6 +48,8 @@ #include "third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.h" #include "third_party/blink/renderer/core/editing/markers/text_match_marker.h" #include "third_party/blink/renderer/core/editing/markers/text_match_marker_list_impl.h" +#include "third_party/blink/renderer/core/editing/position.h" +#include "third_party/blink/renderer/core/editing/visible_position.h" #include "third_party/blink/renderer/core/editing/visible_units.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/layout/layout_object.h" @@ -389,6 +391,79 @@ InvalidatePaintForNode(text); } +DocumentMarker* DocumentMarkerController::FirstMarkerAroundPosition( + const PositionInFlatTree& position, + DocumentMarker::MarkerTypes types) { + if (position.IsNull()) + return nullptr; + + const PositionInFlatTree start_of_word_or_null = + StartOfWord(CreateVisiblePosition(position), kPreviousWordIfOnBoundary) + .DeepEquivalent(); + const PositionInFlatTree start = + start_of_word_or_null.IsNotNull() ? start_of_word_or_null : position; + const PositionInFlatTree end_of_word_or_null = + EndOfWord(CreateVisiblePosition(position), kNextWordIfOnBoundary) + .DeepEquivalent(); + const PositionInFlatTree end = + end_of_word_or_null.IsNotNull() ? end_of_word_or_null : position; + + DCHECK_LE(start, end) << "|start| should be before |end|."; + + const Node* const start_node = start.ComputeContainerNode(); + const unsigned start_offset = start.ComputeOffsetInContainerNode(); + const Node* const end_node = end.ComputeContainerNode(); + const unsigned end_offset = end.ComputeOffsetInContainerNode(); + + for (const Node& node : EphemeralRangeInFlatTree(start, end).Nodes()) { + if (!node.IsTextNode()) + continue; + + const unsigned start_range_offset = node == start_node ? start_offset : 0; + const unsigned end_range_offset = + node == end_node ? end_offset : ToText(node).length(); + + DocumentMarker* const found_marker = FirstMarkerIntersectingOffsetRange( + ToText(node), start_range_offset, end_range_offset, types); + if (found_marker) + return found_marker; + } + + return nullptr; +} + +DocumentMarker* DocumentMarkerController::FirstMarkerIntersectingEphemeralRange( + const EphemeralRange& range, + DocumentMarker::MarkerTypes types) { + if (range.IsNull()) + return nullptr; + + if (range.IsCollapsed()) { + return FirstMarkerAroundPosition( + ToPositionInFlatTree(range.StartPosition()), types); + } + + const Node* const start_container = + range.StartPosition().ComputeContainerNode(); + const Node* const end_container = range.EndPosition().ComputeContainerNode(); + + // We don't currently support the case where a marker spans multiple nodes. + // See crbug.com/720065 + if (start_container != end_container) + return nullptr; + + if (!start_container->IsTextNode()) + return nullptr; + + const unsigned start_offset = + range.StartPosition().ComputeOffsetInContainerNode(); + const unsigned end_offset = + range.EndPosition().ComputeOffsetInContainerNode(); + + return FirstMarkerIntersectingOffsetRange(ToText(*start_container), + start_offset, end_offset, types); +} + DocumentMarker* DocumentMarkerController::FirstMarkerIntersectingOffsetRange( const Text& node, unsigned start_offset,
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h index 1da57c4..63e6b805 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
@@ -29,9 +29,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_DOCUMENT_MARKER_CONTROLLER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_DOCUMENT_MARKER_CONTROLLER_H_ +#include <utility> + #include "base/macros.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h" +#include "third_party/blink/renderer/core/editing/forward.h" #include "third_party/blink/renderer/core/editing/iterators/text_iterator.h" #include "third_party/blink/renderer/core/editing/markers/composition_marker.h" #include "third_party/blink/renderer/core/editing/markers/document_marker.h" @@ -97,6 +100,24 @@ // TODO(rlanday): can these methods for retrieving markers be consolidated // without hurting efficiency? + // If the given position is either at the boundary or inside a word, expands + // the position to the surrounding word and then looks for a marker having the + // specified type. If the position is neither at the boundary or inside a + // word, expands the position to cover the space between the end of the + // previous and the start of the next words. If such a marker exists, this + // method will return one of them (no guarantees are provided as to which + // one). Otherwise, this method will return null. + DocumentMarker* FirstMarkerAroundPosition(const PositionInFlatTree&, + DocumentMarker::MarkerTypes); + // Looks for a marker in the specified EphemeralRange of the specified type + // whose interior has non-empty overlap with the bounds of the range. + // If the range is collapsed, it uses FirstMarkerAroundPosition to expand the + // range to the surrounding word. + // If such a marker exists, this method will return one of them (no guarantees + // are provided as to which one). Otherwise, this method will return null. + DocumentMarker* FirstMarkerIntersectingEphemeralRange( + const EphemeralRange&, + DocumentMarker::MarkerTypes); // Looks for a marker in the specified node of the specified type whose // interior has non-empty overlap with the range [start_offset, end_offset]. // If the range is collapsed, this looks for a marker containing the offset of
diff --git a/third_party/blink/renderer/core/editing/selection_controller.cc b/third_party/blink/renderer/core/editing/selection_controller.cc index 7a774f5b..5ad894e5 100644 --- a/third_party/blink/renderer/core/editing/selection_controller.cc +++ b/third_party/blink/renderer/core/editing/selection_controller.cc
@@ -131,15 +131,9 @@ DocumentMarker* SpellCheckMarkerAtPosition( DocumentMarkerController& document_marker_controller, - const Position& position) { - const Node* const node = position.ComputeContainerNode(); - if (!node->IsTextNode()) - return nullptr; - - const unsigned offset = position.ComputeOffsetInContainerNode(); - return document_marker_controller.FirstMarkerIntersectingOffsetRange( - *ToText(node), offset, offset, - DocumentMarker::MarkerTypes::Misspelling()); + const PositionInFlatTree& position) { + return document_marker_controller.FirstMarkerAroundPosition( + position, DocumentMarker::MarkerTypes::Misspelling()); } } // namespace @@ -674,9 +668,8 @@ const PositionInFlatTree& marker_position = pos.DeepEquivalent().ParentAnchoredEquivalent(); - const DocumentMarker* const marker = - SpellCheckMarkerAtPosition(inner_node->GetDocument().Markers(), - ToPositionInDOMTree(marker_position)); + const DocumentMarker* const marker = SpellCheckMarkerAtPosition( + inner_node->GetDocument().Markers(), marker_position); if (!marker) { UpdateSelectionForMouseDownDispatchingSelectStart( inner_node, SelectionInFlatTree(), @@ -1168,8 +1161,8 @@ inner_node->GetLayoutObject()->PositionForPoint(result.LocalPoint())); if (pos.IsNull()) return false; - const Position& marker_position = - pos.DeepEquivalent().ParentAnchoredEquivalent(); + const PositionInFlatTree& marker_position = + ToPositionInFlatTree(pos.DeepEquivalent().ParentAnchoredEquivalent()); return SpellCheckMarkerAtPosition(inner_node->GetDocument().Markers(), marker_position); }
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc index 2ead505..83d3f34 100644 --- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc +++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
@@ -434,32 +434,14 @@ // Caret and range selections always return valid normalized ranges. const EphemeralRange& selection_range = FirstEphemeralRangeOf(selection); - Node* const selection_start_container = - selection_range.StartPosition().ComputeContainerNode(); - Node* const selection_end_container = - selection_range.EndPosition().ComputeContainerNode(); - - // We don't currently support the case where a misspelling spans multiple - // nodes. See crbug.com/720065 - if (selection_start_container != selection_end_container) - return {}; - - if (!selection_start_container->IsTextNode()) - return {}; - - const unsigned selection_start_offset = - selection_range.StartPosition().ComputeOffsetInContainerNode(); - const unsigned selection_end_offset = - selection_range.EndPosition().ComputeOffsetInContainerNode(); - DocumentMarker* const marker = - GetFrame().GetDocument()->Markers().FirstMarkerIntersectingOffsetRange( - ToText(*selection_start_container), selection_start_offset, - selection_end_offset, DocumentMarker::MarkerTypes::Misspelling()); + GetFrame().GetDocument()->Markers().FirstMarkerIntersectingEphemeralRange( + selection_range, DocumentMarker::MarkerTypes::Misspelling()); if (!marker) return {}; - return std::make_pair(selection_start_container, ToSpellCheckMarker(marker)); + return std::make_pair(selection_range.StartPosition().ComputeContainerNode(), + ToSpellCheckMarker(marker)); } std::pair<String, String> SpellChecker::SelectMisspellingAsync() {
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc index 3489945..022ada6 100644 --- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc +++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
@@ -149,7 +149,10 @@ .GetFrame() ->GetSpellChecker() .GetSpellCheckMarkerUnderSelection(); - EXPECT_NE(nullptr, result.first); + EXPECT_EQ(text, result.first); + ASSERT_NE(nullptr, result.second); + EXPECT_EQ(0u, result.second->StartOffset()); + EXPECT_EQ(8u, result.second->EndOffset()); } TEST_F(SpellCheckerTest, GetSpellCheckMarkerUnderSelection_LastCharSelected) { @@ -173,7 +176,10 @@ .GetFrame() ->GetSpellChecker() .GetSpellCheckMarkerUnderSelection(); - EXPECT_NE(nullptr, result.first); + EXPECT_EQ(text, result.first); + ASSERT_NE(nullptr, result.second); + EXPECT_EQ(0u, result.second->StartOffset()); + EXPECT_EQ(8u, result.second->EndOffset()); } TEST_F(SpellCheckerTest, @@ -198,7 +204,10 @@ .GetFrame() ->GetSpellChecker() .GetSpellCheckMarkerUnderSelection(); - EXPECT_NE(nullptr, result.first); + EXPECT_EQ(text, result.first); + ASSERT_NE(nullptr, result.second); + EXPECT_EQ(0u, result.second->StartOffset()); + EXPECT_EQ(1u, result.second->EndOffset()); } TEST_F(SpellCheckerTest, @@ -223,7 +232,10 @@ .GetFrame() ->GetSpellChecker() .GetSpellCheckMarkerUnderSelection(); - EXPECT_EQ(nullptr, result.first); + EXPECT_EQ(text, result.first); + ASSERT_NE(nullptr, result.second); + EXPECT_EQ(0u, result.second->StartOffset()); + EXPECT_EQ(1u, result.second->EndOffset()); } TEST_F(SpellCheckerTest, @@ -248,7 +260,10 @@ .GetFrame() ->GetSpellChecker() .GetSpellCheckMarkerUnderSelection(); - EXPECT_EQ(nullptr, result.first); + EXPECT_EQ(text, result.first); + ASSERT_NE(nullptr, result.second); + EXPECT_EQ(0u, result.second->StartOffset()); + EXPECT_EQ(1u, result.second->EndOffset()); } TEST_F(SpellCheckerTest, @@ -273,7 +288,10 @@ .GetFrame() ->GetSpellChecker() .GetSpellCheckMarkerUnderSelection(); - EXPECT_EQ(nullptr, result.first); + EXPECT_EQ(text, result.first); + ASSERT_NE(nullptr, result.second); + EXPECT_EQ(0u, result.second->StartOffset()); + EXPECT_EQ(8u, result.second->EndOffset()); } TEST_F(SpellCheckerTest, @@ -298,7 +316,10 @@ .GetFrame() ->GetSpellChecker() .GetSpellCheckMarkerUnderSelection(); - EXPECT_EQ(nullptr, result.first); + EXPECT_EQ(text, result.first); + ASSERT_NE(nullptr, result.second); + EXPECT_EQ(0u, result.second->StartOffset()); + EXPECT_EQ(8u, result.second->EndOffset()); } TEST_F(SpellCheckerTest, GetSpellCheckMarkerUnderSelection_CaretMiddleOfWord) { @@ -322,7 +343,10 @@ .GetFrame() ->GetSpellChecker() .GetSpellCheckMarkerUnderSelection(); - EXPECT_NE(nullptr, result.first); + EXPECT_EQ(text, result.first); + ASSERT_NE(nullptr, result.second); + EXPECT_EQ(0u, result.second->StartOffset()); + EXPECT_EQ(8u, result.second->EndOffset()); } TEST_F(SpellCheckerTest,
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index d222508..e9408193 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -612,11 +612,6 @@ web_frame_->Client()->WillSendSubmitEvent(WebFormElement(form)); } -void LocalFrameClientImpl::DispatchWillSubmitForm(HTMLFormElement* form) { - if (web_frame_->Client()) - web_frame_->Client()->WillSubmitForm(WebFormElement(form)); -} - void LocalFrameClientImpl::DidStartLoading() { if (web_frame_->Client()) { web_frame_->Client()->DidStartLoading();
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h index 7b24ae0..dd6caba6 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -126,7 +126,6 @@ mojom::blink::BlobURLTokenPtr, base::TimeTicks input_start_time) override; void DispatchWillSendSubmitEvent(HTMLFormElement*) override; - void DispatchWillSubmitForm(HTMLFormElement*) override; void DidStartLoading() override; void DidStopLoading() override; void ProgressEstimateChanged(double progress_estimate) override;
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 3c4b739..cdb5cc5 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -81,6 +81,7 @@ #include "third_party/blink/public/web/web_view_client.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h" +#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_node.h" #include "third_party/blink/renderer/core/clipboard/data_transfer.h" @@ -141,6 +142,7 @@ #include "third_party/blink/renderer/core/testing/null_execution_context.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" +#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h" #include "third_party/blink/renderer/platform/bindings/microtask.h" #include "third_party/blink/renderer/platform/cursor.h" #include "third_party/blink/renderer/platform/drag_image.h" @@ -9649,15 +9651,17 @@ KURL destination = ToKURL("data:text/html:destination"); NonThrowableExceptionState exception_state; - main_window->open(destination.GetString(), "frame1", "", main_window, - main_window, exception_state); + main_window->open( + USVStringOrTrustedURL::FromTrustedURL(TrustedURL::Create(destination)), + "frame1", "", main_window, main_window, exception_state); ASSERT_FALSE(remote_client.LastRequest().IsNull()); EXPECT_EQ(remote_client.LastRequest().Url(), WebURL(destination)); // Pointing a named frame to an empty URL should just return a reference to // the frame's window without navigating it. - DOMWindow* result = main_window->open("", "frame1", "", main_window, - main_window, exception_state); + DOMWindow* result = main_window->open( + USVStringOrTrustedURL::FromTrustedURL(TrustedURL::Create(ToKURL(""))), + "frame1", "", main_window, main_window, exception_state); EXPECT_EQ(remote_client.LastRequest().Url(), WebURL(destination)); EXPECT_EQ(result, WebFrame::ToCoreFrame(*remote_frame)->DomWindow());
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.cc b/third_party/blink/renderer/core/exported/web_settings_impl.cc index 1faa0a97..95ddf71 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.cc +++ b/third_party/blink/renderer/core/exported/web_settings_impl.cc
@@ -290,8 +290,8 @@ settings_->SetPreferHiddenVolumeControls(enabled); } -void WebSettingsImpl::SetShouldProtectAgainstIpcFlooding(bool enabled) { - settings_->SetShouldProtectAgainstIpcFlooding(enabled); +void WebSettingsImpl::SetShouldThrottlePushState(bool enabled) { + settings_->SetShouldThrottlePushState(enabled); } void WebSettingsImpl::SetDOMPasteAllowed(bool enabled) {
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.h b/third_party/blink/renderer/core/exported/web_settings_impl.h index 72c2e43..36c9adb 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.h +++ b/third_party/blink/renderer/core/exported/web_settings_impl.h
@@ -138,7 +138,7 @@ void SetAvailableHoverTypes(int) override; void SetPrimaryHoverType(HoverType) override; void SetPreferHiddenVolumeControls(bool) override; - void SetShouldProtectAgainstIpcFlooding(bool) override; + void SetShouldThrottlePushState(bool) override; void SetRenderVSyncNotificationEnabled(bool) override; void SetReportScreenSizeInPhysicalPixelsQuirk(bool) override; void SetRubberBandingOnCompositorThread(bool) override;
diff --git a/third_party/blink/renderer/core/fetch/BUILD.gn b/third_party/blink/renderer/core/fetch/BUILD.gn index cf99b45f..e109ffe2 100644 --- a/third_party/blink/renderer/core/fetch/BUILD.gn +++ b/third_party/blink/renderer/core/fetch/BUILD.gn
@@ -16,6 +16,8 @@ "bytes_consumer.h", "bytes_consumer_for_data_consumer_handle.cc", "bytes_consumer_for_data_consumer_handle.h", + "data_pipe_bytes_consumer.cc", + "data_pipe_bytes_consumer.h", "fetch_data_loader.cc", "fetch_data_loader.h", "fetch_header_list.cc",
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc index aaccc59..1891007 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
@@ -60,6 +60,11 @@ client_->DidFetchDataLoadedString(string); } + void DidFetchDataStartedDataPipe( + mojo::ScopedDataPipeConsumerHandle data_pipe) override { + client_->DidFetchDataStartedDataPipe(std::move(data_pipe)); + } + void DidFetchDataLoadedDataPipe() override { buffer_->EndLoading(); client_->DidFetchDataLoadedDataPipe();
diff --git a/third_party/blink/renderer/core/fetch/bytes_consumer.h b/third_party/blink/renderer/core/fetch/bytes_consumer.h index 96e27de..dac5c5f 100644 --- a/third_party/blink/renderer/core/fetch/bytes_consumer.h +++ b/third_party/blink/renderer/core/fetch/bytes_consumer.h
@@ -129,6 +129,16 @@ // from an EncodedFormData-convertible value. virtual scoped_refptr<EncodedFormData> DrainAsFormData() { return nullptr; } + // Drains the data as a ScopedDataPipeConsumerHandle. + // When this function returns a valid handle, the returned pipe handle + // contains bytes that would be read through the BeginRead and + // EndRead functions without calling this function. In such a case, this + // object becomes closed. + // When this function returns an invalid handle, this function does nothing. + virtual mojo::ScopedDataPipeConsumerHandle DrainAsDataPipe() { + return mojo::ScopedDataPipeConsumerHandle(); + } + // Sets a client. This can be called only when no client is set. When // this object is already closed or errored, this function does nothing. virtual void SetClient(Client*) = 0;
diff --git a/third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.cc b/third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.cc new file mode 100644 index 0000000..518cf9c --- /dev/null +++ b/third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.cc
@@ -0,0 +1,183 @@ +// Copyright 2018 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 "third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.h" + +#include <algorithm> + +#include "base/location.h" +#include "third_party/blink/public/platform/task_type.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/platform/heap/persistent.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" + +namespace blink { + +DataPipeBytesConsumer::DataPipeBytesConsumer( + ExecutionContext* execution_context, + mojo::ScopedDataPipeConsumerHandle data_pipe) + : execution_context_(execution_context), + data_pipe_(std::move(data_pipe)), + watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL, + execution_context->GetTaskRunner(TaskType::kNetworking)) {} + +DataPipeBytesConsumer::~DataPipeBytesConsumer() {} + +BytesConsumer::Result DataPipeBytesConsumer::BeginRead(const char** buffer, + size_t* available) { + DCHECK(!is_in_two_phase_read_); + *buffer = nullptr; + *available = 0; + if (state_ == InternalState::kClosed) + return Result::kDone; + if (state_ == InternalState::kErrored) + return Result::kError; + + uint32_t pipe_available = 0; + MojoResult rv = + data_pipe_->BeginReadData(reinterpret_cast<const void**>(buffer), + &pipe_available, MOJO_READ_DATA_FLAG_NONE); + + switch (rv) { + case MOJO_RESULT_OK: + is_in_two_phase_read_ = true; + *available = pipe_available; + return Result::kOk; + case MOJO_RESULT_SHOULD_WAIT: + MaybeStartWatching(); + watcher_.ArmOrNotify(); + return Result::kShouldWait; + case MOJO_RESULT_FAILED_PRECONDITION: + Close(); + return Result::kDone; + default: + SetError(); + return Result::kError; + } + + NOTREACHED(); +} + +BytesConsumer::Result DataPipeBytesConsumer::EndRead(size_t read) { + DCHECK(is_in_two_phase_read_); + is_in_two_phase_read_ = false; + DCHECK(state_ == InternalState::kReadable || + state_ == InternalState::kWaiting); + MojoResult rv = data_pipe_->EndReadData(read); + if (rv != MOJO_RESULT_OK) { + SetError(); + return Result::kError; + } + total_read_ += read; + if (has_pending_notification_) { + has_pending_notification_ = false; + execution_context_->GetTaskRunner(TaskType::kNetworking) + ->PostTask(FROM_HERE, WTF::Bind(&DataPipeBytesConsumer::Notify, + WrapPersistent(this), MOJO_RESULT_OK)); + } + return Result::kOk; +} + +mojo::ScopedDataPipeConsumerHandle DataPipeBytesConsumer::DrainAsDataPipe() { + DCHECK(!is_in_two_phase_read_); + mojo::ScopedDataPipeConsumerHandle data_pipe = std::move(data_pipe_); + Cancel(); + return data_pipe; +} + +void DataPipeBytesConsumer::SetClient(BytesConsumer::Client* client) { + DCHECK(!client_); + DCHECK(client); + if (state_ == InternalState::kReadable || state_ == InternalState::kWaiting) + client_ = client; +} + +void DataPipeBytesConsumer::ClearClient() { + client_ = nullptr; +} + +void DataPipeBytesConsumer::Cancel() { + if (state_ == InternalState::kReadable || state_ == InternalState::kWaiting) { + // We don't want the client to be notified in this case. + BytesConsumer::Client* client = client_; + client_ = nullptr; + Close(); + client_ = client; + } +} + +BytesConsumer::PublicState DataPipeBytesConsumer::GetPublicState() const { + return GetPublicStateFromInternalState(state_); +} + +void DataPipeBytesConsumer::Trace(blink::Visitor* visitor) { + visitor->Trace(execution_context_); + visitor->Trace(client_); + BytesConsumer::Trace(visitor); +} + +void DataPipeBytesConsumer::Close() { + DCHECK(!is_in_two_phase_read_); + if (state_ == InternalState::kClosed) + return; + DCHECK(state_ == InternalState::kReadable || + state_ == InternalState::kWaiting); + state_ = InternalState::kClosed; + data_pipe_ = mojo::ScopedDataPipeConsumerHandle(); + watcher_.Cancel(); + ClearClient(); +} + +void DataPipeBytesConsumer::SetError() { + DCHECK(!is_in_two_phase_read_); + if (state_ == InternalState::kErrored) + return; + DCHECK(state_ == InternalState::kReadable || + state_ == InternalState::kWaiting); + state_ = InternalState::kErrored; + data_pipe_ = mojo::ScopedDataPipeConsumerHandle(); + watcher_.Cancel(); + error_ = Error("error"); + ClearClient(); +} + +void DataPipeBytesConsumer::Notify(MojoResult) { + if (state_ == InternalState::kClosed || state_ == InternalState::kErrored) { + return; + } + if (is_in_two_phase_read_) { + has_pending_notification_ = true; + return; + } + uint32_t read_size = 0; + MojoResult rv = + data_pipe_->ReadData(nullptr, &read_size, MOJO_READ_DATA_FLAG_NONE); + BytesConsumer::Client* client = client_; + switch (rv) { + case MOJO_RESULT_OK: + case MOJO_RESULT_FAILED_PRECONDITION: + break; + case MOJO_RESULT_SHOULD_WAIT: + watcher_.ArmOrNotify(); + return; + default: + SetError(); + break; + } + if (client) + client->OnStateChange(); +} + +void DataPipeBytesConsumer::MaybeStartWatching() { + if (watcher_.IsWatching()) + return; + + watcher_.Watch( + data_pipe_.get(), + MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + WTF::BindRepeating(&DataPipeBytesConsumer::Notify, WrapPersistent(this))); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.h b/third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.h new file mode 100644 index 0000000..4800170 --- /dev/null +++ b/third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.h
@@ -0,0 +1,62 @@ +// Copyright 2018 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 THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_DATA_PIPE_BYTES_CONSUMER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_DATA_PIPE_BYTES_CONSUMER_H_ + +#include <memory> + +#include "mojo/public/cpp/system/data_pipe.h" +#include "mojo/public/cpp/system/simple_watcher.h" +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/fetch/bytes_consumer.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +class ExecutionContext; + +class CORE_EXPORT DataPipeBytesConsumer final : public BytesConsumer { + public: + DataPipeBytesConsumer(ExecutionContext*, mojo::ScopedDataPipeConsumerHandle); + ~DataPipeBytesConsumer() override; + + Result BeginRead(const char** buffer, size_t* available) override; + Result EndRead(size_t read_size) override; + mojo::ScopedDataPipeConsumerHandle DrainAsDataPipe() override; + void SetClient(BytesConsumer::Client*) override; + void ClearClient() override; + + void Cancel() override; + PublicState GetPublicState() const override; + Error GetError() const override { + DCHECK(state_ == InternalState::kErrored); + return error_; + } + String DebugName() const override { return "DataPipeBytesConsumer"; } + + void Trace(blink::Visitor*) override; + + private: + void Close(); + void SetError(); + void Notify(MojoResult); + + void MaybeStartWatching(); + + Member<ExecutionContext> execution_context_; + mojo::ScopedDataPipeConsumerHandle data_pipe_; + mojo::SimpleWatcher watcher_; + Member<BytesConsumer::Client> client_; + InternalState state_ = InternalState::kWaiting; + Error error_; + bool is_in_two_phase_read_ = false; + bool has_pending_notification_ = false; + uint64_t total_read_ = 0; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_DATA_PIPE_BYTES_CONSUMER_H_
diff --git a/third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer_test.cc b/third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer_test.cc new file mode 100644 index 0000000..b614fe39 --- /dev/null +++ b/third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer_test.cc
@@ -0,0 +1,41 @@ +// Copyright 2018 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 "third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h" +#include "third_party/blink/renderer/core/testing/page_test_base.h" + +namespace blink { +class DataPipeBytesConsumerTest : public PageTestBase { + public: + void SetUp() override { PageTestBase::SetUp(IntSize()); } +}; + +TEST_F(DataPipeBytesConsumerTest, TwoPhaseRead) { + mojo::DataPipe pipe; + ASSERT_TRUE(pipe.producer_handle.is_valid()); + + const std::string kData = "Such hospitality. I'm underwhelmed."; + uint32_t write_size = kData.size(); + + MojoResult rv = pipe.producer_handle->WriteData(kData.c_str(), &write_size, + MOJO_WRITE_DATA_FLAG_NONE); + ASSERT_EQ(MOJO_RESULT_OK, rv); + ASSERT_EQ(kData.size(), write_size); + + // Close the producer so the consumer will reach the kDone state. + pipe.producer_handle.reset(); + + BytesConsumer* consumer = new DataPipeBytesConsumer( + &GetDocument(), std::move(pipe.consumer_handle)); + auto result = (new BytesConsumerTestUtil::TwoPhaseReader(consumer))->Run(); + EXPECT_EQ(BytesConsumer::Result::kDone, result.first); + EXPECT_EQ( + kData, + BytesConsumerTestUtil::CharVectorToString(result.second).Utf8().data()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/fetch_data_loader.cc b/third_party/blink/renderer/core/fetch/fetch_data_loader.cc index 4f20b0f..aead1f4 100644 --- a/third_party/blink/renderer/core/fetch/fetch_data_loader.cc +++ b/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
@@ -485,11 +485,9 @@ USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsDataPipe); public: - FetchDataLoaderAsDataPipe( - mojo::ScopedDataPipeProducerHandle out_data_pipe, + explicit FetchDataLoaderAsDataPipe( scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : out_data_pipe_(std::move(out_data_pipe)), - data_pipe_watcher_(FROM_HERE, + : data_pipe_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, std::move(task_runner)) {} ~FetchDataLoaderAsDataPipe() override {} @@ -498,14 +496,57 @@ FetchDataLoader::Client* client) override { DCHECK(!client_); DCHECK(!consumer_); - data_pipe_watcher_.Watch( - out_data_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, - WTF::BindRepeating(&FetchDataLoaderAsDataPipe::OnWritable, - WrapWeakPersistent(this))); - data_pipe_watcher_.ArmOrNotify(); + client_ = client; consumer_ = consumer; consumer_->SetClient(this); + + // First, try to drain the underlying mojo::DataPipe from the consumer + // directly. If this succeeds, all we need to do here is watch for + // the pipe to be closed to signal completion. + mojo::ScopedDataPipeConsumerHandle pipe_consumer = + consumer->DrainAsDataPipe(); + if (pipe_consumer.is_valid()) { + data_pipe_watcher_.Watch( + pipe_consumer.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED, + WTF::BindRepeating(&FetchDataLoaderAsDataPipe::OnClosed, + WrapWeakPersistent(this))); + } else { + // If we cannot drain the pipe from the consumer then we must copy + // data from the consumer into a new pipe. + MojoCreateDataPipeOptions options; + options.struct_size = sizeof(MojoCreateDataPipeOptions); + options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE; + options.element_num_bytes = 1; + // Use the default pipe capacity since we don't know the total + // data size to target. + options.capacity_num_bytes = 0; + + MojoResult rv = + mojo::CreateDataPipe(&options, &out_data_pipe_, &pipe_consumer); + if (rv != MOJO_RESULT_OK) { + StopInternal(); + client_->DidFetchDataLoadFailed(); + return; + } + DCHECK(out_data_pipe_.is_valid()); + + data_pipe_watcher_.Watch( + out_data_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, + WTF::BindRepeating(&FetchDataLoaderAsDataPipe::OnWritable, + WrapWeakPersistent(this))); + } + + // Give the resulting pipe consumer handle to the client. + DCHECK(pipe_consumer.is_valid()); + client_->DidFetchDataStartedDataPipe(std::move(pipe_consumer)); + + data_pipe_watcher_.ArmOrNotify(); + } + + void OnClosed(MojoResult) { + StopInternal(); + client_->DidFetchDataLoadedDataPipe(); } void OnWritable(MojoResult) { OnStateChange(); } @@ -608,10 +649,8 @@ } FetchDataLoader* FetchDataLoader::CreateLoaderAsDataPipe( - mojo::ScopedDataPipeProducerHandle out_data_pipe, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - return new FetchDataLoaderAsDataPipe(std::move(out_data_pipe), - std::move(task_runner)); + return new FetchDataLoaderAsDataPipe(std::move(task_runner)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/fetch_data_loader.h b/third_party/blink/renderer/core/fetch/fetch_data_loader.h index 4cd84a8..5e96cf2 100644 --- a/third_party/blink/renderer/core/fetch/fetch_data_loader.h +++ b/third_party/blink/renderer/core/fetch/fetch_data_loader.h
@@ -44,6 +44,13 @@ } virtual void DidFetchDataLoadedFormData(FormData*) { NOTREACHED(); } virtual void DidFetchDataLoadedString(const String&) { NOTREACHED(); } + // This is called synchronously from FetchDataLoader::Start() to provide + // the target data pipe. This may be a pipe extracted from the consumer + // or a new pipe that data will be copied into. + virtual void DidFetchDataStartedDataPipe( + mojo::ScopedDataPipeConsumerHandle handle) { + NOTREACHED(); + } // This is called after all data are read from |handle| and written // to |out_data_pipe|, and |out_data_pipe| is closed or aborted. virtual void DidFetchDataLoadedDataPipe() { NOTREACHED(); } @@ -66,8 +73,9 @@ static FetchDataLoader* CreateLoaderAsFormData( const String& multipart_boundary); static FetchDataLoader* CreateLoaderAsString(); + // The mojo::DataPipe consumer handle is provided via the + // Client::DidFetchStartedDataPipe() callback. static FetchDataLoader* CreateLoaderAsDataPipe( - mojo::ScopedDataPipeProducerHandle out_data_pipe, scoped_refptr<base::SingleThreadTaskRunner>); virtual ~FetchDataLoader() {}
diff --git a/third_party/blink/renderer/core/frame/BUILD.gn b/third_party/blink/renderer/core/frame/BUILD.gn index 0377e0a1..3bd04766 100644 --- a/third_party/blink/renderer/core/frame/BUILD.gn +++ b/third_party/blink/renderer/core/frame/BUILD.gn
@@ -95,8 +95,6 @@ "location.cc", "location.h", "message_report_body.h", - "navigation_rate_limiter.cc", - "navigation_rate_limiter.h", "navigator.cc", "navigator.h", "navigator_concurrent_hardware.cc",
diff --git a/third_party/blink/renderer/core/frame/frame.cc b/third_party/blink/renderer/core/frame/frame.cc index 71c6828..c24553a 100644 --- a/third_party/blink/renderer/core/frame/frame.cc +++ b/third_party/blink/renderer/core/frame/frame.cc
@@ -72,7 +72,6 @@ visitor->Trace(window_proxy_manager_); visitor->Trace(dom_window_); visitor->Trace(client_); - visitor->Trace(navigation_rate_limiter_); } void Frame::Detach(FrameDetachType type) { @@ -253,7 +252,6 @@ owner_(owner), client_(client), window_proxy_manager_(window_proxy_manager), - navigation_rate_limiter_(*this), is_loading_(false), devtools_frame_token_(client->GetDevToolsFrameToken()), create_stack_(base::debug::StackTrace()) {
diff --git a/third_party/blink/renderer/core/frame/frame.h b/third_party/blink/renderer/core/frame/frame.h index bb94ac3..5845feb 100644 --- a/third_party/blink/renderer/core/frame/frame.h +++ b/third_party/blink/renderer/core/frame/frame.h
@@ -40,7 +40,6 @@ #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/frame/frame_lifecycle.h" #include "third_party/blink/renderer/core/frame/frame_view.h" -#include "third_party/blink/renderer/core/frame/navigation_rate_limiter.h" #include "third_party/blink/renderer/core/loader/frame_loader_types.h" #include "third_party/blink/renderer/core/page/frame_tree.h" #include "third_party/blink/renderer/platform/graphics/touch_action.h" @@ -57,9 +56,9 @@ class FrameClient; class FrameOwner; class HTMLFrameOwnerElement; -class KURL; class LayoutEmbeddedContent; class LocalFrame; +class KURL; class Page; class SecurityContext; class Settings; @@ -232,10 +231,6 @@ return detach_stack_; } - NavigationRateLimiter& navigation_rate_limiter() { - return navigation_rate_limiter_; - } - protected: Frame(FrameClient*, Page&, FrameOwner*, WindowProxyManager*); @@ -272,9 +267,6 @@ Member<FrameClient> client_; const Member<WindowProxyManager> window_proxy_manager_; FrameLifecycle lifecycle_; - - NavigationRateLimiter navigation_rate_limiter_; - // TODO(sashab): Investigate if this can be represented with m_lifecycle. bool is_loading_; base::UnguessableToken devtools_frame_token_;
diff --git a/third_party/blink/renderer/core/frame/history.cc b/third_party/blink/renderer/core/frame/history.cc index a235dd3..b1d17d8 100644 --- a/third_party/blink/renderer/core/frame/history.cc +++ b/third_party/blink/renderer/core/frame/history.cc
@@ -151,6 +151,36 @@ return history_item->ScrollRestorationType(); } +// TODO(crbug.com/394296): This is not the long-term fix to IPC flooding that we +// need. However, it does somewhat mitigate the immediate concern of |pushState| +// and |replaceState| DoS (assuming the renderer has not been compromised). +bool History::ShouldThrottleStateObjectChanges() { + if (!GetFrame()->GetSettings()->GetShouldThrottlePushState()) + return false; + + // The aim is to enable 8 'frames' (history updates) per second, but we + // express it as 80 frames per 10 seconds because some use cases (including + // tests) do more than 8 updates in 1 second. But over time, applications + // shooting for 8 FPS should work. If necessary to support legitimate + // applications, we can increase this threshold somewhat. + const int kStateUpdateLimit = 80; + + if (state_flood_guard.count > kStateUpdateLimit) { + static constexpr auto kStateUpdateLimitResetInterval = + TimeDelta::FromSeconds(10); + const auto now = CurrentTimeTicks(); + if (now - state_flood_guard.last_updated > kStateUpdateLimitResetInterval) { + state_flood_guard.count = 0; + state_flood_guard.last_updated = now; + return false; + } + return true; + } + + state_flood_guard.count++; + return false; +} + bool History::stateChanged() const { return last_state_object_requested_ != StateInternal(); } @@ -191,9 +221,6 @@ return; } - if (!GetFrame()->navigation_rate_limiter().CanProceed()) - return; - if (delta) { GetFrame()->Client()->NavigateBackForward(delta); } else { @@ -281,7 +308,7 @@ return; } - if (!GetFrame()->navigation_rate_limiter().CanProceed()) { + if (ShouldThrottleStateObjectChanges()) { // TODO(769592): Get an API spec change so that we can throw an exception: // // exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError, @@ -289,6 +316,11 @@ // "prevent the browser from hanging."); // // instead of merely warning. + + GetFrame()->Console().AddMessage( + ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel, + "Throttling history state changes to prevent " + "the browser from hanging.")); return; }
diff --git a/third_party/blink/renderer/core/frame/history.h b/third_party/blink/renderer/core/frame/history.h index 2ba91ea..95e5a638 100644 --- a/third_party/blink/renderer/core/frame/history.h +++ b/third_party/blink/renderer/core/frame/history.h
@@ -103,7 +103,13 @@ SerializedScriptValue* StateInternal() const; HistoryScrollRestorationType ScrollRestorationInternal() const; + bool ShouldThrottleStateObjectChanges(); + scoped_refptr<SerializedScriptValue> last_state_object_requested_; + struct { + int count; + TimeTicks last_updated; + } state_flood_guard; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index 1996ac95..b4b1e22 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1476,22 +1476,6 @@ DOMWindow* LocalDOMWindow::open(ExecutionContext* executionContext, LocalDOMWindow* current_window, LocalDOMWindow* entered_window, - const String& url, - const AtomicString& target, - const String& features, - ExceptionState& exception_state) { - if (document_->RequireTrustedTypes()) { - exception_state.ThrowTypeError( - "This document requires `TrustedURL` assignment."); - return nullptr; - } - return openFromString(executionContext, current_window, entered_window, url, - target, features, exception_state); -} - -DOMWindow* LocalDOMWindow::open(ExecutionContext* executionContext, - LocalDOMWindow* current_window, - LocalDOMWindow* entered_window, const USVStringOrTrustedURL& stringOrUrl, const AtomicString& target, const String& features, @@ -1525,21 +1509,6 @@ exception_state); } -DOMWindow* LocalDOMWindow::open(const String& url, - const AtomicString& frame_name, - const String& window_features_string, - LocalDOMWindow* calling_window, - LocalDOMWindow* entered_window, - ExceptionState& exception_state) { - if (document_->RequireTrustedTypes()) { - exception_state.ThrowTypeError( - "This document requires `TrustedURL` assignment."); - return nullptr; - } - return openFromString(url, frame_name, window_features_string, calling_window, - entered_window, exception_state); -} - DOMWindow* LocalDOMWindow::open(const USVStringOrTrustedURL& stringOrUrl, const AtomicString& frame_name, const String& window_features_string,
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h index 8043f0b..aac28b0 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.h +++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -288,21 +288,6 @@ LocalDOMWindow* entered_window, ExceptionState&); - DOMWindow* open(ExecutionContext*, - LocalDOMWindow* current_window, - LocalDOMWindow* entered_window, - const String& str_url, - const AtomicString& target, - const String& features, - ExceptionState&); - - DOMWindow* open(const String& str_url, - const AtomicString& frame_name, - const String& window_features_string, - LocalDOMWindow* calling_window, - LocalDOMWindow* entered_window, - ExceptionState&); - FrameConsole* GetFrameConsole() const; void PrintErrorMessage(const String&) const;
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 45639ed..bd2cb91 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -273,16 +273,12 @@ const KURL& url, WebFrameLoadType frame_load_type, UserGestureStatus user_gesture_status) { - if (!navigation_rate_limiter().CanProceed()) - return; navigation_scheduler_->ScheduleFrameNavigation(&origin_document, url, frame_load_type); } void LocalFrame::Navigate(const FrameLoadRequest& request, WebFrameLoadType frame_load_type) { - if (!navigation_rate_limiter().CanProceed()) - return; loader_.StartNavigation(request, frame_load_type); }
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h index fe2d45c..48eb2c9 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -163,7 +163,6 @@ base::TimeTicks input_start_time) = 0; virtual void DispatchWillSendSubmitEvent(HTMLFormElement*) = 0; - virtual void DispatchWillSubmitForm(HTMLFormElement*) = 0; virtual void DidStartLoading() = 0; virtual void ProgressEstimateChanged(double progress_estimate) = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc index 2c1a07d..8b3f761 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
@@ -166,15 +166,7 @@ primary_metric_.total_duration += duration; ++primary_metric_.sample_count; - // Compute all the dependent metrics, after finding which bucket we're in - // for UMA data. - size_t bucket_index = bucket_thresholds_.size(); - for (size_t i = 0; i < bucket_index; ++i) { - if (duration < bucket_thresholds_[i]) { - bucket_index = i; - } - } - + // Compute all the dependent metrics for (auto& record : ratio_metric_records_) { double ratio = record.interval_duration.InMicrosecondsF() / duration.InMicrosecondsF(); @@ -182,7 +174,6 @@ record.worst_case_ratio = ratio; record.total_ratio += ratio; ++record.sample_count; - record.uma_counters_per_bucket[bucket_index]->Count(floor(ratio * 100.0)); record.interval_duration = TimeDelta(); } @@ -203,9 +194,11 @@ ukm::UkmEntryBuilder builder(source_id_, event_name_.Utf8().data()); builder.SetMetric(primary_metric_.worst_case_metric_name.Utf8().data(), primary_metric_.worst_case_duration.InMicroseconds()); + double average_frame_duration = + primary_metric_.total_duration.InMicroseconds() / + static_cast<int64_t>(primary_metric_.sample_count); builder.SetMetric(primary_metric_.average_metric_name.Utf8().data(), - primary_metric_.total_duration.InMicroseconds() / - static_cast<int64_t>(primary_metric_.sample_count)); + average_frame_duration); for (auto& record : absolute_metric_records_) { if (record.sample_count == 0) continue; @@ -215,15 +208,29 @@ record.total_duration.InMicroseconds() / static_cast<int64_t>(record.sample_count)); } + for (auto& record : ratio_metric_records_) { if (record.sample_count == 0) continue; builder.SetMetric(record.worst_case_metric_name.Utf8().data(), record.worst_case_ratio); - builder.SetMetric( - record.average_metric_name.Utf8().data(), - record.total_ratio / static_cast<float>(record.sample_count)); + double average_ratio = + record.total_ratio / static_cast<float>(record.sample_count); + builder.SetMetric(record.average_metric_name.Utf8().data(), average_ratio); record.reset(); + + // Send ratio UMA data only when flushed to reduce overhead from metrics. + // Find which bucket we're in for UMA data. We need to do this separately + // for each metric because not every metric records on every frame. + size_t bucket_index = bucket_thresholds_.size(); + for (size_t i = 0; i < bucket_index; ++i) { + if (average_frame_duration < bucket_thresholds_[i].InMicroseconds()) { + bucket_index = i; + } + } + + record.uma_counters_per_bucket[bucket_index]->Count( + floor(average_ratio * 100.0)); } builder.Record(recorder_); has_data_ = false;
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h index bb8ed23a..7b424690 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
@@ -16,7 +16,7 @@ namespace blink { class CustomCountHistogram; -// This class aggregaties and records time based UKM and UMA metrics +// This class aggregates and records time based UKM and UMA metrics // for LocalFrameView. The simplest way to use it is via the // SCOPED_UMA_AND_UKM_HIERARCHICAL_TIMER macro in LocalFrameView combined // with LocalFrameView::RecordEndOfFrameMetrics. @@ -42,12 +42,14 @@ // // When the primary timed execution completes, this aggregator stores the // primary time and computes metrics that depend on it. The results are -// aggregated. UMA metrics are updated at this time. A UKM event is +// aggregated. A UKM event is // generated in one of two situations: // - If a sample is added that lies in the next event frequency interval (this // will generate an event for the previous interval) // - If the aggregator is destroyed (this will generate an event for any // remaining samples in the aggregator) +// UMA ratio-related metrics are only reported when an event is generated to +// reduce the overhead of metric gathering. // // Note that no event is generated if there were no primary samples in an // interval.
diff --git a/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc b/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc deleted file mode 100644 index aa3e5628..0000000 --- a/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright (c) 2018 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 "third_party/blink/renderer/core/frame/navigation_rate_limiter.h" -#include "third_party/blink/renderer/core/frame/frame.h" -#include "third_party/blink/renderer/core/frame/frame_console.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/frame/settings.h" -#include "third_party/blink/renderer/core/inspector/console_message.h" - -namespace blink { - -NavigationRateLimiter::NavigationRateLimiter(Frame& frame) - : frame_(frame), - time_first_count_(base::TimeTicks::Now()), - enabled(frame_->GetSettings()->GetShouldProtectAgainstIpcFlooding()) {} - -void NavigationRateLimiter::Trace(blink::Visitor* visitor) { - visitor->Trace(frame_); -} - -bool NavigationRateLimiter::CanProceed() { - if (!enabled) - return true; - - // The aim is to roughly enable 20 same-document navigation per second, but we - // express it as 200 per 10 seconds because some use cases (including tests) - // do more than 20 updates in 1 second. But over time, applications shooting - // for more should work. If necessary to support legitimate applications, we - // can increase this threshold somewhat. - static constexpr int kStateUpdateLimit = 200; - static constexpr base::TimeDelta kStateUpdateLimitResetInterval = - base::TimeDelta::FromSeconds(10); - - if (++count_ <= kStateUpdateLimit) - return true; - - const base::TimeTicks now = base::TimeTicks::Now(); - if (now - time_first_count_ > kStateUpdateLimitResetInterval) { - time_first_count_ = now; - count_ = 1; - error_message_sent_ = false; - return true; - } - - // Display an error message. Do it only once in a while, else it will flood - // the browser process with the FrameHostMsg_DidAddMessageToConsole IPC. - if (!error_message_sent_) { - error_message_sent_ = true; - if (frame_->IsLocalFrame()) { - ToLocalFrame(frame_)->Console().AddMessage(ConsoleMessage::Create( - kJSMessageSource, kWarningMessageLevel, - "Throttling navigation to prevent the browser from " - "hanging. See https://crbug.com/882238 and " - "chrome://flags/#disable-ipc-flooding-protection")); - } - } - - return false; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/navigation_rate_limiter.h b/third_party/blink/renderer/core/frame/navigation_rate_limiter.h deleted file mode 100644 index 0250fc2..0000000 --- a/third_party/blink/renderer/core/frame/navigation_rate_limiter.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright (c) 2018 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 THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATION_RATE_LIMITER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATION_RATE_LIMITER_H_ - -#include "base/time/time.h" -#include "third_party/blink/renderer/platform/heap/member.h" - -namespace blink { -class Visitor; -class Frame; - -// TODO(https://crbug.com/394296, https://crbug.com/882238) -// Prevent the renderer process to flood the browser process by sending IPC for -// same-document navigations. -// This is not the long-term fix to IPC flooding. However, it mitigate the -// immediate concern assuming the renderer has not been compromised. -class NavigationRateLimiter final { - DISALLOW_NEW(); - - public: - explicit NavigationRateLimiter(Frame&); - - // Notify this object a new navigation is requested. Return true if this one - // is allowed to proceed. - bool CanProceed(); - - void Trace(blink::Visitor*); - - private: - Member<Frame> frame_; - base::TimeTicks time_first_count_; - int count_ = 0; - bool enabled; - - bool error_message_sent_ = false; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATION_RATE_LIMITER_H_
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc index e8526b4..e1358d8 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.cc +++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -71,9 +71,6 @@ void RemoteFrame::Navigate(const FrameLoadRequest& passed_request, WebFrameLoadType frame_load_type) { - if (!navigation_rate_limiter().CanProceed()) - return; - FrameLoadRequest frame_request(passed_request); // The process where this frame actually lives won't have sufficient
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5 index d7d4d5c8..db9341b93 100644 --- a/third_party/blink/renderer/core/frame/settings.json5 +++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -947,7 +947,7 @@ type: "WebEffectiveConnectionType", }, { - name: "shouldProtectAgainstIpcFlooding", + name: "shouldThrottlePushState", initial: true, },
diff --git a/third_party/blink/renderer/core/html/anchor_element_metrics.cc b/third_party/blink/renderer/core/html/anchor_element_metrics.cc index 7a2ec806..9666026 100644 --- a/third_party/blink/renderer/core/html/anchor_element_metrics.cc +++ b/third_party/blink/renderer/core/html/anchor_element_metrics.cc
@@ -167,6 +167,7 @@ // Limit the element size to the viewport size. float ratio_area = std::min(1.0f, target.Height() / base_height) * std::min(1.0f, target.Width() / base_width); + DCHECK_GE(1.0, ratio_area); float ratio_distance_top_to_visible_top = target.Y() / base_height; float ratio_distance_center_to_visible_top = (target.Y() + target.Height() / 2.0) / base_height; @@ -197,6 +198,7 @@ // It guarantees to be less or equal to 1. float ratio_visible_area = (target_visible.Height() / base_height) * (target_visible.Width() / base_width); + DCHECK_GE(1.0, ratio_visible_area); return AnchorElementMetrics( anchor_element, ratio_area, ratio_visible_area, @@ -274,7 +276,9 @@ const { auto metrics = mojom::blink::AnchorElementMetrics::New(); metrics->ratio_area = ratio_area_; + DCHECK_GE(1.0, metrics->ratio_area); metrics->ratio_visible_area = ratio_visible_area_; + DCHECK_GE(1.0, metrics->ratio_visible_area); metrics->ratio_distance_top_to_visible_top = ratio_distance_top_to_visible_top_; metrics->ratio_distance_center_to_visible_top =
diff --git a/third_party/blink/renderer/core/html/anchor_element_metrics.h b/third_party/blink/renderer/core/html/anchor_element_metrics.h index 5efa25b..da5949eb 100644 --- a/third_party/blink/renderer/core/html/anchor_element_metrics.h +++ b/third_party/blink/renderer/core/html/anchor_element_metrics.h
@@ -128,7 +128,12 @@ is_in_iframe_(is_in_iframe), contains_image_(contains_image), is_same_host_(is_same_host), - is_url_incremented_by_one_(is_url_incremented_by_one) {} + is_url_incremented_by_one_(is_url_incremented_by_one) { + DCHECK_LE(0, ratio_area_); + DCHECK_GE(1, ratio_area_); + DCHECK_LE(0, ratio_visible_area_); + DCHECK_GE(1, ratio_visible_area_); + } }; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc index c6c2002..04a32b6 100644 --- a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc +++ b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc
@@ -64,10 +64,10 @@ void AnchorElementMetricsSender::AddAnchorElement(HTMLAnchorElement& element) { if (has_onload_report_sent_) return; - anchor_elements_.push_back(element); + anchor_elements_.insert(&element); } -const HeapVector<Member<HTMLAnchorElement>>& +const HeapHashSet<Member<HTMLAnchorElement>>& AnchorElementMetricsSender::GetAnchorElements() const { return anchor_elements_; }
diff --git a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h index fd75667..17a34d1 100644 --- a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h +++ b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h
@@ -7,8 +7,10 @@ #include "base/macros.h" #include "third_party/blink/public/mojom/loader/navigation_predictor.mojom-blink.h" +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/supplementable.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -18,7 +20,7 @@ // AnchorElementMetricsSender is responsible to send anchor element metrics to // the browser process for a given document. -class AnchorElementMetricsSender final +class CORE_EXPORT AnchorElementMetricsSender final : public GarbageCollectedFinalized<AnchorElementMetricsSender>, public Supplement<Document> { USING_GARBAGE_COLLECTED_MIXIN(AnchorElementMetricsSender); @@ -48,7 +50,7 @@ void AddAnchorElement(HTMLAnchorElement& element); // Returns the stored |anchor_elements_|. - const HeapVector<Member<HTMLAnchorElement>>& GetAnchorElements() const; + const HeapHashSet<Member<HTMLAnchorElement>>& GetAnchorElements() const; void Trace(blink::Visitor*) override; @@ -62,8 +64,9 @@ // Browser host to which the anchor element metrics are sent. mojom::blink::AnchorElementMetricsHostPtr metrics_host_; - // Collection of anchor elements in the document. - HeapVector<Member<HTMLAnchorElement>> anchor_elements_; + // Collection of anchor elements in the document. Use a HashSet to ensure that + // an element is inserted at most once. + HeapHashSet<Member<HTMLAnchorElement>> anchor_elements_; // If |has_onload_report_sent_| is true, |anchor_elements_| will not accept // new anchor elements.
diff --git a/third_party/blink/renderer/core/html/anchor_element_metrics_sender_test.cc b/third_party/blink/renderer/core/html/anchor_element_metrics_sender_test.cc new file mode 100644 index 0000000..8c38c5c --- /dev/null +++ b/third_party/blink/renderer/core/html/anchor_element_metrics_sender_test.cc
@@ -0,0 +1,55 @@ +// Copyright 2018 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 "third_party/blink/renderer/core/html/anchor_element_metrics_sender.h" + +#include "base/test/scoped_feature_list.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/html/html_anchor_element.h" +#include "third_party/blink/renderer/core/testing/sim/sim_request.h" +#include "third_party/blink/renderer/core/testing/sim/sim_test.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" + +namespace blink { + +class AnchorElementMetricsSenderTest : public SimTest { + protected: + AnchorElementMetricsSenderTest() = default; + + void SetUp() override { + SimTest::SetUp(); + feature_list_.InitAndEnableFeature(features::kRecordAnchorMetricsClicked); + } + + base::test::ScopedFeatureList feature_list_; +}; + +// Test that duplicate anchor elements are not added to +// AnchorElementMetricsSender. +TEST_F(AnchorElementMetricsSenderTest, AddAnhcorElement) { + String source("http://example.com/p1"); + + SimRequest main_resource(source, "text/html"); + LoadURL(source); + main_resource.Complete( + "<a id='anchor1' href=''>example</a><a id='anchor2' href=''>example</a>"); + HTMLAnchorElement* anchor_element_1 = + ToHTMLAnchorElement(GetDocument().getElementById("anchor1")); + HTMLAnchorElement* anchor_element_2 = + ToHTMLAnchorElement(GetDocument().getElementById("anchor2")); + + AnchorElementMetricsSender* sender = + AnchorElementMetricsSender::From(GetDocument()); + EXPECT_EQ(2u, sender->GetAnchorElements().size()); + + // Adding the anchor elements again should not change the size. + sender->AddAnchorElement(*anchor_element_1); + EXPECT_EQ(2u, sender->GetAnchorElements().size()); + sender->AddAnchorElement(*anchor_element_2); + EXPECT_EQ(2u, sender->GetAnchorElements().size()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc index 953ba5f..1077580 100644 --- a/third_party/blink/renderer/core/input/mouse_event_manager.cc +++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -620,8 +620,10 @@ if (update_hover_reason == MouseEventManager::UpdateHoverReason::kScrollOffsetChanged && - mouse_pressed_) + (RuntimeEnabledFeatures::NoHoverDuringScrollEnabled() || + mouse_pressed_)) { return; + } // TODO(lanwei): When the mouse position is unknown, we do not send the fake // mousemove event for now, so we cannot update the hover states and mouse
diff --git a/third_party/blink/renderer/core/loader/empty_clients.cc b/third_party/blink/renderer/core/loader/empty_clients.cc index 7e5edfa..69254e3 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.cc +++ b/third_party/blink/renderer/core/loader/empty_clients.cc
@@ -114,8 +114,6 @@ void EmptyLocalFrameClient::DispatchWillSendSubmitEvent(HTMLFormElement*) {} -void EmptyLocalFrameClient::DispatchWillSubmitForm(HTMLFormElement*) {} - DocumentLoader* EmptyLocalFrameClient::CreateDocumentLoader( LocalFrame* frame, const ResourceRequest& request,
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h index bab778108..cec382ce 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.h +++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -281,7 +281,6 @@ base::TimeTicks) override; void DispatchWillSendSubmitEvent(HTMLFormElement*) override; - void DispatchWillSubmitForm(HTMLFormElement*) override; void DidStartLoading() override {} void ProgressEstimateChanged(double) override {}
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 96600c4..140c3a7 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -936,9 +936,6 @@ if (policy == kNavigationPolicyIgnore) return; - if (request.Form()) - Client()->DispatchWillSubmitForm(request.Form()); - if (policy == kNavigationPolicyCurrentTab) { CommitNavigation(resource_request, SubstituteData(), request.ClientRedirect(), base::UnguessableToken::Create(),
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index f7550a5..49ca8d8 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -120,18 +120,22 @@ class ImageLoader::Task { public: static std::unique_ptr<Task> Create(ImageLoader* loader, + const KURL& request_url, UpdateFromElementBehavior update_behavior, ReferrerPolicy referrer_policy) { - return std::make_unique<Task>(loader, update_behavior, referrer_policy); + return std::make_unique<Task>(loader, request_url, update_behavior, + referrer_policy); } Task(ImageLoader* loader, + const KURL& request_url, UpdateFromElementBehavior update_behavior, ReferrerPolicy referrer_policy) : loader_(loader), should_bypass_main_world_csp_(ShouldBypassMainWorldCSP(loader)), update_behavior_(update_behavior), referrer_policy_(referrer_policy), + request_url_(request_url), weak_factory_(this) { ExecutionContext& context = loader_->GetElement()->GetDocument(); probe::AsyncTaskScheduled(&context, "Image", this); @@ -146,8 +150,6 @@ loader->GetElement()->GetDocument().GetFrame()); DCHECK(script_state_); } - request_url_ = - loader->ImageSourceToKURL(loader->GetElement()->ImageSourceURL()); } void Run() { @@ -388,10 +390,11 @@ } inline void ImageLoader::EnqueueImageLoadingMicroTask( + const KURL& request_url, UpdateFromElementBehavior update_behavior, ReferrerPolicy referrer_policy) { std::unique_ptr<Task> task = - Task::Create(this, update_behavior, referrer_policy); + Task::Create(this, request_url, update_behavior, referrer_policy); pending_task_ = task->GetWeakPtr(); Microtask::EnqueueMicrotask( WTF::Bind(&Task::Run, WTF::Passed(std::move(task)))); @@ -576,13 +579,15 @@ ClearImage(); } + KURL url = ImageSourceToKURL(image_source_url); + // Prevent the creation of a ResourceLoader (and therefore a network request) // for ImageDocument loads. In this case, the image contents have already been // requested as a main resource and ImageDocumentParser will take care of // funneling the main resource bytes into |image_content_|, so just create an // ImageResource to be populated later. if (loading_image_document_) { - ResourceRequest request(ImageSourceToKURL(element_->ImageSourceURL())); + ResourceRequest request(url); request.SetFetchCredentialsMode( network::mojom::FetchCredentialsMode::kOmit); ImageResource* image_resource = ImageResource::Create(request); @@ -601,7 +606,6 @@ delay_until_do_update_from_element_ = nullptr; } - KURL url = ImageSourceToKURL(image_source_url); if (ShouldLoadImmediately(url)) { DoUpdateFromElement(kDoNotBypassMainWorldCSP, update_behavior, url, referrer_policy, UpdateType::kSync); @@ -627,7 +631,7 @@ // raw HTML parsing case by loading images we don't intend to display. Document& document = element_->GetDocument(); if (document.IsActive()) - EnqueueImageLoadingMicroTask(update_behavior, referrer_policy); + EnqueueImageLoadingMicroTask(url, update_behavior, referrer_policy); } KURL ImageLoader::ImageSourceToKURL(AtomicString image_source_url) const {
diff --git a/third_party/blink/renderer/core/loader/image_loader.h b/third_party/blink/renderer/core/loader/image_loader.h index 6719ef2..b8e39112 100644 --- a/third_party/blink/renderer/core/loader/image_loader.h +++ b/third_party/blink/renderer/core/loader/image_loader.h
@@ -177,7 +177,9 @@ void ClearFailedLoadURL(); void DispatchErrorEvent(); void CrossSiteOrCSPViolationOccurred(AtomicString); - void EnqueueImageLoadingMicroTask(UpdateFromElementBehavior, ReferrerPolicy); + void EnqueueImageLoadingMicroTask(const KURL&, + UpdateFromElementBehavior, + ReferrerPolicy); KURL ImageSourceToKURL(AtomicString) const;
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc index 7b07f93..c96d56d4 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
@@ -344,6 +344,15 @@ if (!registration_->active()) return ScriptPromise::CastUndefined(script_state); + ScriptState::Scope scope(script_state); + + if (id.IsEmpty()) { + return ScriptPromise::Reject( + script_state, + V8ThrowException::CreateTypeError(script_state->GetIsolate(), + "The provided id is invalid.")); + } + ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise promise = resolver->Promise();
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system.cc index 34cd458..9d079872 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system.cc
@@ -33,7 +33,6 @@ #include <memory> #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/modules/filesystem/directory_entry.h" @@ -150,7 +149,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks = FileWriterCallbacks::Create(file_writer, success_callback, error_callback, context_); - FileSystemDispatcher::GetThreadSpecificInstance().InitializeFileWriter( + FileSystemDispatcher::From(context_).InitializeFileWriter( CreateFileSystemURL(file_entry), std::move(callbacks)); } @@ -160,7 +159,7 @@ ErrorCallbackBase* error_callback) { KURL file_system_url = CreateFileSystemURL(file_entry); - FileSystemDispatcher::GetThreadSpecificInstance().CreateSnapshotFile( + FileSystemDispatcher::From(context_).CreateSnapshotFile( file_system_url, SnapshotFileCallback::Create(this, file_entry->name(), file_system_url, success_callback, error_callback, context_));
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc index 0dc350b..98e1a65 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
@@ -32,7 +32,6 @@ #include <memory> #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/fileapi/file.h" @@ -73,13 +72,6 @@ ScriptWrappable::Trace(visitor); } -WebFileSystem* DOMFileSystemBase::FileSystem() const { - Platform* platform = Platform::Current(); - if (!platform) - return nullptr; - return platform->FileSystem(); -} - const SecurityOrigin* DOMFileSystemBase::GetSecurityOrigin() const { return context_->GetSecurityOrigin(); } @@ -219,8 +211,7 @@ SynchronousType synchronous_type) { std::unique_ptr<AsyncFileSystemCallbacks> callbacks(MetadataCallbacks::Create( success_callback, error_callback, context_, this)); - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); if (synchronous_type == kSynchronous) { dispatcher.ReadMetadataSync(CreateFileSystemURL(entry), @@ -285,8 +276,7 @@ success_callback, error_callback, context_, parent->filesystem(), destination_path, source->isDirectory())); - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); const KURL& src = CreateFileSystemURL(source); const KURL& dest = parent->filesystem()->CreateFileSystemURL(destination_path); @@ -317,8 +307,7 @@ const KURL& src = CreateFileSystemURL(source); const KURL& dest = parent->filesystem()->CreateFileSystemURL(destination_path); - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); if (synchronous_type == kSynchronous) dispatcher.CopySync(src, dest, std::move(callbacks)); else @@ -340,8 +329,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks( VoidCallbacks::Create(success_callback, error_callback, context_, this)); const KURL& url = CreateFileSystemURL(entry); - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); if (synchronous_type == kSynchronous) dispatcher.RemoveSync(url, /*recursive=*/false, std::move(callbacks)); else @@ -364,8 +352,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks( VoidCallbacks::Create(success_callback, error_callback, context_, this)); const KURL& url = CreateFileSystemURL(entry); - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); if (synchronous_type == kSynchronous) dispatcher.RemoveSync(url, /*recursive=*/true, std::move(callbacks)); else @@ -379,7 +366,7 @@ DCHECK(entry); String path = DOMFilePath::GetDirectory(entry->fullPath()); - FileSystemDispatcher::GetThreadSpecificInstance().Exists( + FileSystemDispatcher::From(context_).Exists( CreateFileSystemURL(path), /*is_directory=*/true, EntryCallbacks::Create(success_callback, error_callback, context_, this, path, true)); @@ -401,8 +388,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntryCallbacks::Create( success_callback, error_callback, context_, this, absolute_path, false)); const KURL& url = CreateFileSystemURL(absolute_path); - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); if (flags.createFlag()) { if (synchronous_type == kSynchronous) @@ -434,8 +420,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntryCallbacks::Create( success_callback, error_callback, context_, this, absolute_path, true)); const KURL& url = CreateFileSystemURL(absolute_path); - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); if (flags.createFlag()) { if (synchronous_type == kSynchronous) { @@ -464,8 +449,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntriesCallbacks::Create( success_callback, error_callback, context_, reader, path)); - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); const KURL& url = CreateFileSystemURL(path); if (synchronous_type == kSynchronous) { dispatcher.ReadDirectorySync(url, std::move(callbacks));
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h index 643929f..83452e2 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
@@ -42,10 +42,6 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { -class WebFileSystem; -} // namespace blink - -namespace blink { class DirectoryReaderBase; class EntryBase; @@ -83,7 +79,6 @@ const String& name() const { return name_; } mojom::blink::FileSystemType GetType() const { return type_; } KURL RootURL() const { return filesystem_root_url_; } - WebFileSystem* FileSystem() const; const SecurityOrigin* GetSecurityOrigin() const; // The clonable flag is used in the structured clone algorithm to test
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc index 08b3747..1d1b6e1 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc
@@ -33,7 +33,6 @@ #include <memory> #include "base/memory/ptr_util.h" -#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/renderer/core/fileapi/file.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" #include "third_party/blink/renderer/modules/filesystem/directory_entry_sync.h" @@ -140,7 +139,7 @@ KURL file_system_url = CreateFileSystemURL(file_entry); CreateFileHelper::CreateFileResult* result( CreateFileHelper::CreateFileResult::Create()); - FileSystemDispatcher::GetThreadSpecificInstance().CreateSnapshotFileSync( + FileSystemDispatcher::From(context_).CreateSnapshotFileSync( file_system_url, CreateFileHelper::Create(result, file_entry->name(), file_system_url, GetType())); if (result->failed_) { @@ -157,7 +156,7 @@ ExceptionState& exception_state) { DCHECK(file_entry); - FileWriterSync* file_writer = FileWriterSync::Create(); + FileWriterSync* file_writer = FileWriterSync::Create(context_); FileWriterCallbacksSyncHelper* sync_helper = FileWriterCallbacksSyncHelper::Create(); @@ -166,7 +165,7 @@ sync_helper->GetSuccessCallback(), sync_helper->GetErrorCallback(), context_); - FileSystemDispatcher::GetThreadSpecificInstance().InitializeFileWriterSync( + FileSystemDispatcher::From(context_).InitializeFileWriterSync( CreateFileSystemURL(file_entry), std::move(callbacks)); FileWriterBase* success = sync_helper->GetResultOrThrow(exception_state);
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc index 1130460b..4c99f50 100644 --- a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc +++ b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc
@@ -5,9 +5,10 @@ #include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h" #include "build/build_config.h" +#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/platform/file_path_conversion.h" -#include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -68,23 +69,34 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks_; }; -FileSystemDispatcher::FileSystemDispatcher() : next_operation_id_(1) {} +FileSystemDispatcher::FileSystemDispatcher(ExecutionContext& context) + : Supplement<ExecutionContext>(context), next_operation_id_(1) {} // static -FileSystemDispatcher& FileSystemDispatcher::GetThreadSpecificInstance() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<FileSystemDispatcher>, - file_system_dispatcher, ()); - return *file_system_dispatcher; +const char FileSystemDispatcher::kSupplementName[] = "FileSystemDispatcher"; + +// static +FileSystemDispatcher& FileSystemDispatcher::From(ExecutionContext* context) { + DCHECK(context); + FileSystemDispatcher* dispatcher = + Supplement<ExecutionContext>::From<FileSystemDispatcher>(context); + if (!dispatcher) { + dispatcher = new FileSystemDispatcher(*context); + Supplement<ExecutionContext>::ProvideTo(*context, dispatcher); + } + return *dispatcher; } +FileSystemDispatcher::~FileSystemDispatcher() = default; + void FileSystemDispatcher::OpenFileSystem( const KURL& origin_url, mojom::blink::FileSystemType type, std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Open( origin_url, type, - WTF::Bind(&FileSystemDispatcher::DidOpenFileSystem, WTF::Unretained(this), - std::move(callbacks))); + WTF::Bind(&FileSystemDispatcher::DidOpenFileSystem, + WrapWeakPersistent(this), std::move(callbacks))); } void FileSystemDispatcher::OpenFileSystemSync( @@ -103,8 +115,9 @@ const KURL& filesystem_url, std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().ResolveURL( - filesystem_url, WTF::Bind(&FileSystemDispatcher::DidResolveURL, - WTF::Unretained(this), std::move(callbacks))); + filesystem_url, + WTF::Bind(&FileSystemDispatcher::DidResolveURL, WrapWeakPersistent(this), + std::move(callbacks))); } void FileSystemDispatcher::ResolveURLSync( @@ -126,7 +139,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Move( src_path, dest_path, - WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), std::move(callbacks))); } @@ -145,7 +158,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Copy( src_path, dest_path, - WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), std::move(callbacks))); } @@ -164,7 +177,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Remove( path, recursive, - WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), std::move(callbacks))); } @@ -182,7 +195,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().ReadMetadata( path, WTF::Bind(&FileSystemDispatcher::DidReadMetadata, - WTF::Unretained(this), std::move(callbacks))); + WrapWeakPersistent(this), std::move(callbacks))); } void FileSystemDispatcher::ReadMetadataSync( @@ -200,7 +213,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Create( path, exclusive, /*is_directory=*/false, /*is_recursive=*/false, - WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), std::move(callbacks))); } @@ -221,7 +234,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Create( path, exclusive, /*is_directory=*/true, recursive, - WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), std::move(callbacks))); } @@ -242,7 +255,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Exists( path, is_directory, - WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), std::move(callbacks))); } @@ -284,7 +297,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().ReadMetadata( path, WTF::Bind(&FileSystemDispatcher::InitializeFileWriterCallback, - WTF::Unretained(this), path, std::move(callbacks))); + WrapWeakPersistent(this), path, std::move(callbacks))); } void FileSystemDispatcher::InitializeFileWriterSync( @@ -307,11 +320,11 @@ int operation_id = next_operation_id_++; op_ptr.set_connection_error_handler( WTF::Bind(&FileSystemDispatcher::RemoveOperationPtr, - WTF::Unretained(this), operation_id)); + WrapWeakPersistent(this), operation_id)); cancellable_operations_.insert(operation_id, std::move(op_ptr)); GetFileSystemManager().Truncate( path, offset, std::move(op_request), - WTF::Bind(&FileSystemDispatcher::DidTruncate, WTF::Unretained(this), + WTF::Bind(&FileSystemDispatcher::DidTruncate, WrapWeakPersistent(this), operation_id, std::move(callback))); if (request_id_out) @@ -338,7 +351,7 @@ int operation_id = next_operation_id_++; op_ptr.set_connection_error_handler( WTF::Bind(&FileSystemDispatcher::RemoveOperationPtr, - WTF::Unretained(this), operation_id)); + WrapWeakPersistent(this), operation_id)); cancellable_operations_.insert(operation_id, std::move(op_ptr)); mojom::blink::FileSystemOperationListenerPtr listener_ptr; @@ -379,7 +392,7 @@ } cancellable_operations_.find(request_id_to_cancel) ->value->Cancel(WTF::Bind(&FileSystemDispatcher::DidCancel, - WTF::Unretained(this), std::move(callback), + WrapWeakPersistent(this), std::move(callback), request_id_to_cancel)); } @@ -388,7 +401,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().CreateSnapshotFile( file_path, WTF::Bind(&FileSystemDispatcher::DidCreateSnapshotFile, - WTF::Unretained(this), std::move(callbacks))); + WrapWeakPersistent(this), std::move(callbacks))); } void FileSystemDispatcher::CreateSnapshotFileSync( @@ -422,11 +435,33 @@ std::move(callbacks))); } +void FileSystemDispatcher::ChooseEntry( + std::unique_ptr<ChooseEntryCallbacks> callbacks) { + GetFileSystemManager().ChooseEntry(WTF::Bind( + [](std::unique_ptr<ChooseEntryCallbacks> callbacks, + base::File::Error result, + Vector<mojom::blink::FileSystemEntryPtr> entries) { + if (result != base::File::FILE_OK) { + callbacks->OnError(result); + } else { + callbacks->OnSuccess(std::move(entries)); + } + }, + std::move(callbacks))); +} + mojom::blink::FileSystemManager& FileSystemDispatcher::GetFileSystemManager() { if (!file_system_manager_ptr_) { - Platform::Current()->GetInterfaceProvider()->GetInterface( - mojo::MakeRequest(&file_system_manager_ptr_)); + mojom::blink::FileSystemManagerRequest request = + mojo::MakeRequest(&file_system_manager_ptr_); + // Document::GetInterfaceProvider() can return null if the frame is + // detached. + if (GetSupplementable()->GetInterfaceProvider()) { + GetSupplementable()->GetInterfaceProvider()->GetInterface( + std::move(request)); + } } + DCHECK(file_system_manager_ptr_); return *file_system_manager_ptr_; }
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h index 2b3b33a..d8a899a 100644 --- a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h +++ b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h
@@ -10,6 +10,7 @@ #include "third_party/blink/public/platform/web_callbacks.h" #include "third_party/blink/renderer/platform/async_file_system_callbacks.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/supplementable.h" namespace WTF { class String; @@ -18,18 +19,25 @@ namespace blink { class KURL; +class ExecutionContext; // Sends messages via mojo to the blink::mojom::FileSystemManager service -// running in the browser process. It is currently created and stored in a -// thread local variable. A thread specific instance can be obtained using -// GetThreadSpecificInstance(). -class FileSystemDispatcher { +// running in the browser process. It is owned by ExecutionContext, and +// instances are created lazily by calling FileSystemDispatcher::From(). +class FileSystemDispatcher + : public GarbageCollectedFinalized<FileSystemDispatcher>, + public Supplement<ExecutionContext> { + USING_GARBAGE_COLLECTED_MIXIN(FileSystemDispatcher); + public: using StatusCallback = base::OnceCallback<void(base::File::Error error)>; using WriteCallback = base::RepeatingCallback<void(int64_t bytes, bool complete)>; - static FileSystemDispatcher& GetThreadSpecificInstance(); + static const char kSupplementName[]; + + static FileSystemDispatcher& From(ExecutionContext* context); + virtual ~FileSystemDispatcher(); void OpenFileSystem(const KURL& url, mojom::blink::FileSystemType type, @@ -133,12 +141,15 @@ void CreateFileWriter(const KURL& file_path, std::unique_ptr<CreateFileWriterCallbacks>); + using ChooseEntryCallbacks = + WebCallbacks<Vector<mojom::blink::FileSystemEntryPtr>, base::File::Error>; + void ChooseEntry(std::unique_ptr<ChooseEntryCallbacks> callbacks); + private: class WriteListener; class ReadDirectoryListener; - friend class WTF::ThreadSpecific<FileSystemDispatcher>; - FileSystemDispatcher(); + explicit FileSystemDispatcher(ExecutionContext& context); mojom::blink::FileSystemManager& GetFileSystemManager();
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc b/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc index 5775e5c..2b66212 100644 --- a/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc +++ b/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
@@ -60,9 +60,9 @@ ScriptPromise FileSystemFileHandle::createWriter(ScriptState* script_state) { auto* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise result = resolver->Promise(); - FileSystemDispatcher::GetThreadSpecificInstance().CreateFileWriter( - filesystem()->CreateFileSystemURL(this), - std::make_unique<CreateWriterCallbacks>(resolver)); + FileSystemDispatcher::From(ExecutionContext::From(script_state)) + .CreateFileWriter(filesystem()->CreateFileSystemURL(this), + std::make_unique<CreateWriterCallbacks>(resolver)); return result; } @@ -70,12 +70,13 @@ auto* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise result = resolver->Promise(); KURL file_system_url = filesystem()->CreateFileSystemURL(this); - FileSystemDispatcher::GetThreadSpecificInstance().CreateSnapshotFile( - file_system_url, - SnapshotFileCallback::Create(filesystem(), name(), file_system_url, - new OnDidCreateSnapshotFilePromise(resolver), - new PromiseErrorCallback(resolver), - ExecutionContext::From(script_state))); + FileSystemDispatcher::From(ExecutionContext::From(script_state)) + .CreateSnapshotFile(file_system_url, + SnapshotFileCallback::Create( + filesystem(), name(), file_system_url, + new OnDidCreateSnapshotFilePromise(resolver), + new PromiseErrorCallback(resolver), + ExecutionContext::From(script_state))); return result; }
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_writer.cc b/third_party/blink/renderer/modules/filesystem/file_system_writer.cc index a29a28b..89ec9b3 100644 --- a/third_party/blink/renderer/modules/filesystem/file_system_writer.cc +++ b/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
@@ -64,6 +64,16 @@ public: explicit StreamWriterClient(FileSystemWriter* writer) : writer_(writer) {} + void DidFetchDataStartedDataPipe( + mojo::ScopedDataPipeConsumerHandle data_pipe) override { + data_pipe_ = std::move(data_pipe); + } + + mojo::ScopedDataPipeConsumerHandle TakeDataPipe() { + DCHECK(data_pipe_); + return std::move(data_pipe_); + } + void DidFetchDataLoadedDataPipe() override { // WriteComplete could have been called with an error before we reach this // point, in that case just return. @@ -126,6 +136,7 @@ } Member<FileSystemWriter> writer_; + mojo::ScopedDataPipeConsumerHandle data_pipe_; bool did_finish_writing_to_pipe_ = false; bool did_complete_ = false; }; @@ -147,14 +158,7 @@ return ScriptPromise(); auto* consumer = new ReadableStreamBytesConsumer(script_state, reader); - mojo::DataPipe pipe; - if (!pipe.consumer_handle.is_valid()) { - return ScriptPromise::RejectWithDOMException( - script_state, DOMException::Create(DOMExceptionCode::kInvalidStateError, - "Failed to create data pipe")); - } stream_loader_ = FetchDataLoader::CreateLoaderAsDataPipe( - std::move(pipe.producer_handle), ExecutionContext::From(script_state) ->GetTaskRunner(TaskType::kInternalDefault)); pending_operation_ = ScriptPromiseResolver::Create(script_state); @@ -162,7 +166,7 @@ auto* client = new StreamWriterClient(this); stream_loader_->Start(consumer, client); writer_->WriteStream( - position, std::move(pipe.consumer_handle), + position, client->TakeDataPipe(), WTF::Bind(&StreamWriterClient::WriteComplete, WrapPersistent(client))); return result; }
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer.cc b/third_party/blink/renderer/modules/filesystem/file_writer.cc index 6e0cc06..5ad31e6 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer.cc +++ b/third_party/blink/renderer/modules/filesystem/file_writer.cc
@@ -225,23 +225,25 @@ } void FileWriter::DoTruncate(const KURL& path, int64_t offset) { - FileSystemDispatcher::GetThreadSpecificInstance().Truncate( - path, offset, &request_id_, - WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); + FileSystemDispatcher::From(GetExecutionContext()) + .Truncate(path, offset, &request_id_, + WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); } void FileWriter::DoWrite(const KURL& path, const String& blob_id, int64_t offset) { - FileSystemDispatcher::GetThreadSpecificInstance().Write( - path, blob_id, offset, &request_id_, - WTF::BindRepeating(&FileWriter::DidWrite, WrapWeakPersistent(this)), - WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); + FileSystemDispatcher::From(GetExecutionContext()) + .Write( + path, blob_id, offset, &request_id_, + WTF::BindRepeating(&FileWriter::DidWrite, WrapWeakPersistent(this)), + WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); } void FileWriter::DoCancel() { - FileSystemDispatcher::GetThreadSpecificInstance().Cancel( - request_id_, WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); + FileSystemDispatcher::From(GetExecutionContext()) + .Cancel(request_id_, + WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); } void FileWriter::CompleteAbort() { @@ -328,6 +330,8 @@ DoOperation(kOperationAbort); ready_state_ = kDone; } + // Prevents any queued operations from running after abort completes. + queued_operation_ = kOperationNone; } void FileWriter::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc b/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc index 3242da55..e9c20b16 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc +++ b/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
@@ -98,26 +98,33 @@ } void FileWriterSync::DoTruncate(const KURL& path, int64_t offset) { - FileSystemDispatcher::GetThreadSpecificInstance().TruncateSync( - path, offset, - WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this))); + if (!GetExecutionContext()) + return; + FileSystemDispatcher::From(GetExecutionContext()) + .TruncateSync( + path, offset, + WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this))); } void FileWriterSync::DoWrite(const KURL& path, const String& blob_id, int64_t offset) { - FileSystemDispatcher::GetThreadSpecificInstance().WriteSync( - path, blob_id, offset, - WTF::BindRepeating(&FileWriterSync::DidWrite, WrapWeakPersistent(this)), - WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this))); + if (!GetExecutionContext()) + return; + FileSystemDispatcher::From(GetExecutionContext()) + .WriteSync( + path, blob_id, offset, + WTF::BindRepeating(&FileWriterSync::DidWrite, + WrapWeakPersistent(this)), + WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this))); } void FileWriterSync::DoCancel() { NOTREACHED(); } -FileWriterSync::FileWriterSync() - : error_(base::File::FILE_OK), complete_(true) {} +FileWriterSync::FileWriterSync(ExecutionContext* context) + : ContextClient(context), error_(base::File::FILE_OK), complete_(true) {} void FileWriterSync::PrepareForWrite() { DCHECK(complete_); @@ -130,6 +137,7 @@ void FileWriterSync::Trace(blink::Visitor* visitor) { ScriptWrappable::Trace(visitor); FileWriterBase::Trace(visitor); + ContextClient::Trace(visitor); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer_sync.h b/third_party/blink/renderer/modules/filesystem/file_writer_sync.h index 4a8002a..6561606 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer_sync.h +++ b/third_party/blink/renderer/modules/filesystem/file_writer_sync.h
@@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_SYNC_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_SYNC_H_ +#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" #include "third_party/blink/renderer/modules/filesystem/file_writer_base.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -41,12 +42,16 @@ class Blob; class ExceptionState; -class FileWriterSync final : public ScriptWrappable, public FileWriterBase { +class FileWriterSync final : public ScriptWrappable, + public FileWriterBase, + public ContextClient { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(FileWriterSync); public: - static FileWriterSync* Create() { return new FileWriterSync(); } + static FileWriterSync* Create(ExecutionContext* context) { + return new FileWriterSync(context); + } ~FileWriterSync() override; void Trace(blink::Visitor*) override; @@ -65,7 +70,7 @@ void DoCancel() override; private: - FileWriterSync(); + explicit FileWriterSync(ExecutionContext* context); void PrepareForWrite(); base::File::Error error_;
diff --git a/third_party/blink/renderer/modules/filesystem/local_file_system.cc b/third_party/blink/renderer/modules/filesystem/local_file_system.cc index 3ead0c3e..0951745 100644 --- a/third_party/blink/renderer/modules/filesystem/local_file_system.cc +++ b/third_party/blink/renderer/modules/filesystem/local_file_system.cc
@@ -35,7 +35,6 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" -#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -117,12 +116,14 @@ namespace { -class ChooseEntryCallbacks : public WebFileSystem::ChooseEntryCallbacks { +class ChooseEntryCallbacks + : public WebCallbacks<Vector<mojom::blink::FileSystemEntryPtr>, + base::File::Error> { public: ChooseEntryCallbacks(ScriptPromiseResolver* resolver, bool return_multiple) : resolver_(resolver), return_multiple_(return_multiple) {} - void OnSuccess(WebVector<WebFileSystem::FileSystemEntry> entries) override { + void OnSuccess(Vector<mojom::blink::FileSystemEntryPtr> entries) override { ScriptState::Scope scope(resolver_->GetScriptState()); if (return_multiple_) { Vector<ScriptPromise> result; @@ -142,15 +143,16 @@ } private: - ScriptPromise CreateFileHandle(const WebFileSystem::FileSystemEntry& entry) { + ScriptPromise CreateFileHandle( + const mojom::blink::FileSystemEntryPtr& entry) { auto* new_resolver = ScriptPromiseResolver::Create(resolver_->GetScriptState()); ScriptPromise result = new_resolver->Promise(); auto* fs = DOMFileSystem::CreateIsolatedFileSystem( - resolver_->GetExecutionContext(), entry.file_system_id); + resolver_->GetExecutionContext(), entry->file_system_id); // TODO(mek): Try to create handle directly rather than having to do more // IPCs to get the actual entries. - fs->GetFile(fs->root(), entry.base_name, FileSystemFlags(), + fs->GetFile(fs->root(), entry->base_name, FileSystemFlags(), new EntryCallbacks::OnDidGetEntryPromiseImpl(new_resolver), new PromiseErrorCallback(new_resolver)); return result; @@ -169,24 +171,8 @@ return; } - WebFileSystem* file_system = GetFileSystem(); - if (!file_system) { - resolver->Reject( - FileError::CreateDOMException(base::File::FILE_ERROR_ABORT)); - return; - } - - file_system->ChooseEntry( - Supplement<LocalFrame>::GetSupplementable()->Client()->GetWebFrame(), - std::make_unique<ChooseEntryCallbacks>(resolver, false)); -} - -WebFileSystem* LocalFileSystem::GetFileSystem() const { - Platform* platform = Platform::Current(); - if (!platform) - return nullptr; - - return platform->FileSystem(); + FileSystemDispatcher::From(resolver->GetExecutionContext()) + .ChooseEntry(std::make_unique<ChooseEntryCallbacks>(resolver, false)); } void LocalFileSystem::RequestFileSystemAccessInternal( @@ -231,8 +217,7 @@ KURL(NullURL(), context->GetSecurityOrigin()->ToString()); std::unique_ptr<AsyncFileSystemCallbacks> async_callbacks = callbacks->Release(); - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context); if (sync_type == kSynchronous) { dispatcher.OpenFileSystemSync(storage_partition, type, std::move(async_callbacks)); @@ -246,8 +231,7 @@ const KURL& file_system_url, CallbackWrapper* callbacks, SynchronousType sync_type) { - FileSystemDispatcher& dispatcher = - FileSystemDispatcher::GetThreadSpecificInstance(); + FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context); std::unique_ptr<AsyncFileSystemCallbacks> async_callbacks = callbacks->Release(); if (sync_type == kSynchronous) {
diff --git a/third_party/blink/renderer/modules/filesystem/local_file_system.h b/third_party/blink/renderer/modules/filesystem/local_file_system.h index b3e2823b..b137d0e9 100644 --- a/third_party/blink/renderer/modules/filesystem/local_file_system.h +++ b/third_party/blink/renderer/modules/filesystem/local_file_system.h
@@ -49,7 +49,6 @@ class ExecutionContext; class KURL; class ScriptPromiseResolver; -class WebFileSystem; class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>, public Supplement<LocalFrame>, @@ -87,7 +86,6 @@ const char* NameInHeapSnapshot() const override { return "LocalFileSystem"; } private: - WebFileSystem* GetFileSystem() const; void FileSystemNotAvailable(ExecutionContext*, CallbackWrapper*); void RequestFileSystemAccessInternal(ExecutionContext*,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc index 771f3e5..d312c80 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
@@ -154,8 +154,7 @@ DispatchEvent(*event.Release()); } -void RTCDTMFSender::DidPlayTone(const WebString& tone, - const WebString& tone_buffer) { +void RTCDTMFSender::DidPlayTone(const WebString& tone) { // We're using the DidPlayTone with an empty buffer to signal the // end of the tone. if (tone.IsEmpty()) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h index 38980cde..1ee1ead6 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
@@ -76,9 +76,8 @@ void Dispose(); // WebRTCDTMFSenderHandlerClient - void DidPlayTone(const WebString& tone, - const WebString& tone_buffer) override; void PlayoutTask(); + void DidPlayTone(const WebString&) override; std::unique_ptr<WebRTCDTMFSenderHandler> handler_;
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_event.cc b/third_party/blink/renderer/modules/service_worker/fetch_event.cc index a499d4c..b4745aa4 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_event.cc +++ b/third_party/blink/renderer/modules/service_worker/fetch_event.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/core/fetch/bytes_consumer_for_data_consumer_handle.h" +#include "third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.h" #include "third_party/blink/renderer/core/fetch/request.h" #include "third_party/blink/renderer/core/fetch/response.h" #include "third_party/blink/renderer/core/frame/use_counter.h" @@ -107,7 +107,7 @@ void FetchEvent::OnNavigationPreloadResponse( ScriptState* script_state, std::unique_ptr<WebURLResponse> response, - std::unique_ptr<WebDataConsumerHandle> data_consume_handle) { + mojo::ScopedDataPipeConsumerHandle data_pipe) { if (!script_state->ContextIsValid()) return; DCHECK(preload_response_property_); @@ -116,12 +116,11 @@ preload_response_ = std::move(response); // TODO(ricea): Verify that this response can't be aborted from JS. FetchResponseData* response_data = - data_consume_handle + data_pipe.is_valid() ? FetchResponseData::CreateWithBuffer(new BodyStreamBuffer( script_state, - new BytesConsumerForDataConsumerHandle( - ExecutionContext::From(script_state), - std::move(data_consume_handle)), + new DataPipeBytesConsumer(ExecutionContext::From(script_state), + std::move(data_pipe)), new AbortSignal(ExecutionContext::From(script_state)))) : FetchResponseData::Create(); Vector<KURL> url_list(1);
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_event.h b/third_party/blink/renderer/modules/service_worker/fetch_event.h index 1bf70d44..362f6cf 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_event.h +++ b/third_party/blink/renderer/modules/service_worker/fetch_event.h
@@ -27,7 +27,6 @@ class Request; class Response; class ScriptState; -class WebDataConsumerHandle; struct WebServiceWorkerError; class WebURLResponse; class WorkerGlobalScope; @@ -67,7 +66,7 @@ void OnNavigationPreloadResponse(ScriptState*, std::unique_ptr<WebURLResponse>, - std::unique_ptr<WebDataConsumerHandle>); + mojo::ScopedDataPipeConsumerHandle); void OnNavigationPreloadError(ScriptState*, std::unique_ptr<WebServiceWorkerError>); void OnNavigationPreloadComplete(WorkerGlobalScope*,
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc b/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc index ea7bafb6..7c1d04a 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc +++ b/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "base/feature_list.h" #include "base/metrics/histogram_macros.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "services/network/public/mojom/request_context_frame_type.mojom-blink.h" @@ -128,19 +129,31 @@ USING_GARBAGE_COLLECTED_MIXIN(FetchLoaderClient); public: - explicit FetchLoaderClient( - std::unique_ptr<WebServiceWorkerStreamHandle> handle) - : handle_(std::move(handle)) {} + FetchLoaderClient() {} - void DidFetchDataLoadedDataPipe() override { handle_->Completed(); } - void DidFetchDataLoadFailed() override { handle_->Aborted(); } + void DidFetchDataStartedDataPipe( + mojo::ScopedDataPipeConsumerHandle pipe) override { + DCHECK(!handle_); + handle_ = std::make_unique<WebServiceWorkerStreamHandle>(std::move(pipe)); + } + void DidFetchDataLoadedDataPipe() override { + DCHECK(handle_); + handle_->Completed(); + } + void DidFetchDataLoadFailed() override { + if (handle_) + handle_->Aborted(); + } void Abort() override { // A fetch() aborted via AbortSignal in the ServiceWorker will just look // like an ordinary failure to the page. // TODO(ricea): Should a fetch() on the page get an AbortError instead? - handle_->Aborted(); + if (handle_) + handle_->Aborted(); } + WebServiceWorkerStreamHandle* Handle() const { return handle_.get(); } + void Trace(blink::Visitor* visitor) override { FetchDataLoader::Client::Trace(visitor); } @@ -289,33 +302,21 @@ base::TimeTicks::Now()); return; } - // Handle the stream response body. - base::TimeTicks start_pipe_creation = base::TimeTicks::Now(); - mojo::DataPipe pipe; - if (!pipe.consumer_handle.is_valid()) { - OnResponseRejected(ServiceWorkerResponseError::kDataPipeCreationFailed); - return; - } - DCHECK(pipe.producer_handle.is_valid()); - UMA_HISTOGRAM_TIMES("ServiceWorker.FetchRespondWithDataPipeCreation.Time", - base::TimeTicks::Now() - start_pipe_creation); - std::unique_ptr<WebServiceWorkerStreamHandle> body_stream_handle = - std::make_unique<WebServiceWorkerStreamHandle>( - std::move(pipe.consumer_handle)); - ServiceWorkerGlobalScopeClient::From(GetExecutionContext()) - ->RespondToFetchEventWithResponseStream( - event_id_, web_response, body_stream_handle.get(), - event_dispatch_time_, base::TimeTicks::Now()); - - buffer->StartLoading(FetchDataLoader::CreateLoaderAsDataPipe( - std::move(pipe.producer_handle), task_runner_), - new FetchLoaderClient(std::move(body_stream_handle)), - exception_state); + // Load the Response as a mojo::DataPipe. The resulting pipe consumer + // handle will be passed to the FetchLoaderClient on start. + FetchLoaderClient* fetch_loader_client = new FetchLoaderClient(); + buffer->StartLoading(FetchDataLoader::CreateLoaderAsDataPipe(task_runner_), + fetch_loader_client, exception_state); if (exception_state.HadException()) { OnResponseRejected(ServiceWorkerResponseError::kResponseBodyBroken); return; } + + ServiceWorkerGlobalScopeClient::From(GetExecutionContext()) + ->RespondToFetchEventWithResponseStream( + event_id_, web_response, fetch_loader_client->Handle(), + event_dispatch_time_, base::TimeTicks::Now()); return; } ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc index 2778cbf..dc86e1c 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
@@ -418,7 +418,7 @@ void ServiceWorkerGlobalScopeProxy::OnNavigationPreloadResponse( int fetch_event_id, std::unique_ptr<WebURLResponse> response, - std::unique_ptr<WebDataConsumerHandle> data_consume_handle) { + mojo::ScopedDataPipeConsumerHandle data_pipe) { DCHECK(WorkerGlobalScope()->IsContextThread()); auto it = pending_preload_fetch_events_.find(fetch_event_id); DCHECK(it != pending_preload_fetch_events_.end()); @@ -426,7 +426,7 @@ DCHECK(fetch_event); fetch_event->OnNavigationPreloadResponse( WorkerGlobalScope()->ScriptController()->GetScriptState(), - std::move(response), std::move(data_consume_handle)); + std::move(response), std::move(data_pipe)); } void ServiceWorkerGlobalScopeProxy::OnNavigationPreloadError(
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h index 09b4b56..8d0437a0 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
@@ -48,7 +48,6 @@ class FetchEvent; class ParentExecutionContextTaskRunners; class ServiceWorkerGlobalScope; -class WebDataConsumerHandle; class WebEmbeddedWorkerImpl; class WebServiceWorkerContextClient; struct WebServiceWorkerError; @@ -134,7 +133,7 @@ void OnNavigationPreloadResponse( int fetch_event_id, std::unique_ptr<WebURLResponse>, - std::unique_ptr<WebDataConsumerHandle>) override; + mojo::ScopedDataPipeConsumerHandle data_pipe) override; void OnNavigationPreloadError( int fetch_event_id, std::unique_ptr<WebServiceWorkerError>) override;
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 6ad1e48..3632baa 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -179,7 +179,7 @@ "//services/network/public/cpp:cpp", "//services/network/public/mojom", "//services/network/public/mojom:mojom_blink", - "//services/resource_coordinator/public/cpp:resource_coordinator_cpp", + "//services/resource_coordinator/public/cpp:resource_coordinator_cpp_features", "//services/resource_coordinator/public/mojom:mojom_blink", "//services/service_manager/public/mojom:mojom_blink", "//skia",
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index dea745c..26310e8 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -220,6 +220,10 @@ RuntimeEnabledFeatures::SetNoHoverAfterLayoutChangeEnabled(enable); } +void WebRuntimeFeatures::EnableNoHoverDuringScroll(bool enable) { + RuntimeEnabledFeatures::SetNoHoverDuringScrollEnabled(enable); +} + void WebRuntimeFeatures::EnableNotificationConstructor(bool enable) { RuntimeEnabledFeatures::SetNotificationConstructorEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 26167ce..124bfee3 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -821,6 +821,10 @@ settable_from_internals: true, }, { + name: "NoHoverDuringScroll", + settable_from_internals: true, + }, + { name: "NoIdleEncodingForLayoutTests", status: "test", },
diff --git a/third_party/blink/tools/blinkpy/w3c/local_wpt.py b/third_party/blink/tools/blinkpy/w3c/local_wpt.py index 2ac6563d..4ab3b9e 100644 --- a/third_party/blink/tools/blinkpy/w3c/local_wpt.py +++ b/third_party/blink/tools/blinkpy/w3c/local_wpt.py
@@ -94,12 +94,11 @@ # Remove Chromium WPT directory prefix. patch = patch.replace(CHROMIUM_WPT_DIR, '') + _log.info('Author: %s', author) if '<' in author: author_str = author else: author_str = '%s <%s>' % (author, author) - _log.info('Author: %s', repr(author_str)) - _log.debug('Message:\n%s', repr(message)) # TODO(jeffcarp): Use git am -p<n> where n is len(CHROMIUM_WPT_DIR.split(/')) # or something not off-by-one.
diff --git a/third_party/blink/tools/blinkpy/w3c/test_exporter.py b/third_party/blink/tools/blinkpy/w3c/test_exporter.py index 136a68a..1d726249 100644 --- a/third_party/blink/tools/blinkpy/w3c/test_exporter.py +++ b/third_party/blink/tools/blinkpy/w3c/test_exporter.py
@@ -6,7 +6,6 @@ import argparse import logging -import sys from blinkpy.common.system.log_utils import configure_logging from blinkpy.w3c.local_wpt import LocalWPT @@ -58,10 +57,6 @@ 'your credentials up.') return False - # TODO(crbug.com/891831): temporary debug logging; remove afterwards. - _log.debug("LANG=%s", self.host.environ.get('LANG', '')) - _log.debug("filesystemencoding=%s", sys.getfilesystemencoding()) - self.wpt_github = self.wpt_github or WPTGitHub(self.host, credentials['GH_USER'], credentials['GH_TOKEN']) self.gerrit = self.gerrit or GerritAPI(self.host, credentials['GERRIT_USER'], credentials['GERRIT_TOKEN']) self.local_wpt = self.local_wpt or LocalWPT(self.host, credentials['GH_TOKEN'])
diff --git a/third_party/d3/OWNERS b/third_party/d3/OWNERS deleted file mode 100644 index b8901db6..0000000 --- a/third_party/d3/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -andrewhayden@chromium.org
diff --git a/third_party/d3/README.chromium b/third_party/d3/README.chromium deleted file mode 100644 index 7697762..0000000 --- a/third_party/d3/README.chromium +++ /dev/null
@@ -1,31 +0,0 @@ -Name: d3 -Short Name: d3 -URL: https://github.com/mbostock/d3 -Version: 3.4.4 -Date: Mon Mar 24 20:45:44 2014 -0700 -Revision: fa55eead411a3c1b01703cb1ddfd59ccc0b23124 -License: BSD 3-Clause -License File: src/LICENSE -Security Critical: No -License Android Compatible: Yes - -Description: -A JavaScript library for manipulating documents based on data. - -Subject to the security patch(es) described below, you MAY include d3 in web-facing content, such -as in pages generated by bots or tools. - - -Local Modifications: -1. Deleted everything except for: -* d3.js the standalone non-minified library -* LICENSE the BSD-style 3-Clause license -* README.md the readme file from github, for basic information - -2. Applied the following patches at the request of security: -patches/001_no_html.patch Disables the html() convenience functions, which could be used to - inject arbitrary content into the page. Instead of using html(), - programmatically create the individual nodes and/or text that you - require. - The html() methods have been modified to throw exceptions that - make it obvious that this feature is disabled for security.
diff --git a/third_party/d3/patches/001_no_html.patch b/third_party/d3/patches/001_no_html.patch deleted file mode 100644 index 3c976b0b..0000000 --- a/third_party/d3/patches/001_no_html.patch +++ /dev/null
@@ -1,24 +0,0 @@ -diff --git a/third_party/d3/src/d3.js b/third_party/d3/src/d3.js -index a3e4b95..8a98c4d 100644 ---- a/third_party/d3/src/d3.js -+++ b/third_party/d3/src/d3.js -@@ -713,6 +713,7 @@ - }) : this.node().textContent; - }; - d3_selectionPrototype.html = function(value) { -+ throw "disallowed by chromium security"; - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; -@@ -9274,9 +9275,11 @@ - return JSON.parse(request.responseText); - } - d3.html = function(url, callback) { -+ throw "disallowed by chromium security"; - return d3_xhr(url, "text/html", d3_html, callback); - }; - function d3_html(request) { -+ throw "disallowed by chromium security"; - var range = d3_document.createRange(); - range.selectNode(d3_document.body); - return range.createContextualFragment(request.responseText);
diff --git a/third_party/d3/src/LICENSE b/third_party/d3/src/LICENSE deleted file mode 100644 index 8301346..0000000 --- a/third_party/d3/src/LICENSE +++ /dev/null
@@ -1,26 +0,0 @@ -Copyright (c) 2010-2014, Michael Bostock -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* The name Michael Bostock may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/d3/src/README.md b/third_party/d3/src/README.md deleted file mode 100644 index eb334e27..0000000 --- a/third_party/d3/src/README.md +++ /dev/null
@@ -1,9 +0,0 @@ -# Data-Driven Documents - -<a href="http://d3js.org"><img src="http://d3js.org/logo.svg" align="left" hspace="10" vspace="6"></a> - -**D3.js** is a JavaScript library for manipulating documents based on data. **D3** helps you bring data to life using HTML, SVG and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation. - -Want to learn more? [See the wiki.](https://github.com/mbostock/d3/wiki) - -For examples, [see the gallery](https://github.com/mbostock/d3/wiki/Gallery) and [mbostock’s bl.ocks](http://bl.ocks.org/mbostock).
diff --git a/third_party/d3/src/d3.js b/third_party/d3/src/d3.js deleted file mode 100644 index 6dcabdf..0000000 --- a/third_party/d3/src/d3.js +++ /dev/null
@@ -1,9297 +0,0 @@ -!function() { - var d3 = { - version: "3.4.4" - }; - if (!Date.now) Date.now = function() { - return +new Date(); - }; - var d3_arraySlice = [].slice, d3_array = function(list) { - return d3_arraySlice.call(list); - }; - var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window; - try { - d3_array(d3_documentElement.childNodes)[0].nodeType; - } catch (e) { - d3_array = function(list) { - var i = list.length, array = new Array(i); - while (i--) array[i] = list[i]; - return array; - }; - } - try { - d3_document.createElement("div").style.setProperty("opacity", 0, ""); - } catch (error) { - var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; - d3_element_prototype.setAttribute = function(name, value) { - d3_element_setAttribute.call(this, name, value + ""); - }; - d3_element_prototype.setAttributeNS = function(space, local, value) { - d3_element_setAttributeNS.call(this, space, local, value + ""); - }; - d3_style_prototype.setProperty = function(name, value, priority) { - d3_style_setProperty.call(this, name, value + "", priority); - }; - } - d3.ascending = d3_ascending; - function d3_ascending(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - } - d3.descending = function(a, b) { - return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; - }; - d3.min = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && a > b) a = b; - } else { - while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; - } - return a; - }; - d3.max = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && b > a) a = b; - } else { - while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; - } - return a; - }; - d3.extent = function(array, f) { - var i = -1, n = array.length, a, b, c; - if (arguments.length === 1) { - while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined; - while (++i < n) if ((b = array[i]) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } else { - while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } - return [ a, c ]; - }; - d3.sum = function(array, f) { - var s = 0, n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (!isNaN(a = +array[i])) s += a; - } else { - while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; - } - return s; - }; - function d3_number(x) { - return x != null && !isNaN(x); - } - d3.mean = function(array, f) { - var n = array.length, a, m = 0, i = -1, j = 0; - if (arguments.length === 1) { - while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j; - } else { - while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j; - } - return j ? m : undefined; - }; - d3.quantile = function(values, p) { - var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; - return e ? v + e * (values[h] - v) : v; - }; - d3.median = function(array, f) { - if (arguments.length > 1) array = array.map(f); - array = array.filter(d3_number); - return array.length ? d3.quantile(array.sort(d3_ascending), .5) : undefined; - }; - function d3_bisector(compare) { - return { - left: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; - } - return lo; - }, - right: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; - } - return lo; - } - }; - } - var d3_bisect = d3_bisector(d3_ascending); - d3.bisectLeft = d3_bisect.left; - d3.bisect = d3.bisectRight = d3_bisect.right; - d3.bisector = function(f) { - return d3_bisector(f.length === 1 ? function(d, x) { - return d3_ascending(f(d), x); - } : f); - }; - d3.shuffle = function(array) { - var m = array.length, t, i; - while (m) { - i = Math.random() * m-- | 0; - t = array[m], array[m] = array[i], array[i] = t; - } - return array; - }; - d3.permute = function(array, indexes) { - var i = indexes.length, permutes = new Array(i); - while (i--) permutes[i] = array[indexes[i]]; - return permutes; - }; - d3.pairs = function(array) { - var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); - while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; - return pairs; - }; - d3.zip = function() { - if (!(n = arguments.length)) return []; - for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { - for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { - zip[j] = arguments[j][i]; - } - } - return zips; - }; - function d3_zipLength(d) { - return d.length; - } - d3.transpose = function(matrix) { - return d3.zip.apply(d3, matrix); - }; - d3.keys = function(map) { - var keys = []; - for (var key in map) keys.push(key); - return keys; - }; - d3.values = function(map) { - var values = []; - for (var key in map) values.push(map[key]); - return values; - }; - d3.entries = function(map) { - var entries = []; - for (var key in map) entries.push({ - key: key, - value: map[key] - }); - return entries; - }; - d3.merge = function(arrays) { - var n = arrays.length, m, i = -1, j = 0, merged, array; - while (++i < n) j += arrays[i].length; - merged = new Array(j); - while (--n >= 0) { - array = arrays[n]; - m = array.length; - while (--m >= 0) { - merged[--j] = array[m]; - } - } - return merged; - }; - var abs = Math.abs; - d3.range = function(start, stop, step) { - if (arguments.length < 3) { - step = 1; - if (arguments.length < 2) { - stop = start; - start = 0; - } - } - if ((stop - start) / step === Infinity) throw new Error("infinite range"); - var range = [], k = d3_range_integerScale(abs(step)), i = -1, j; - start *= k, stop *= k, step *= k; - if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); - return range; - }; - function d3_range_integerScale(x) { - var k = 1; - while (x * k % 1) k *= 10; - return k; - } - function d3_class(ctor, properties) { - try { - for (var key in properties) { - Object.defineProperty(ctor.prototype, key, { - value: properties[key], - enumerable: false - }); - } - } catch (e) { - ctor.prototype = properties; - } - } - d3.map = function(object) { - var map = new d3_Map(); - if (object instanceof d3_Map) object.forEach(function(key, value) { - map.set(key, value); - }); else for (var key in object) map.set(key, object[key]); - return map; - }; - function d3_Map() {} - d3_class(d3_Map, { - has: d3_map_has, - get: function(key) { - return this[d3_map_prefix + key]; - }, - set: function(key, value) { - return this[d3_map_prefix + key] = value; - }, - remove: d3_map_remove, - keys: d3_map_keys, - values: function() { - var values = []; - this.forEach(function(key, value) { - values.push(value); - }); - return values; - }, - entries: function() { - var entries = []; - this.forEach(function(key, value) { - entries.push({ - key: key, - value: value - }); - }); - return entries; - }, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) f.call(this, key.substring(1), this[key]); - } - }); - var d3_map_prefix = "\x00", d3_map_prefixCode = d3_map_prefix.charCodeAt(0); - function d3_map_has(key) { - return d3_map_prefix + key in this; - } - function d3_map_remove(key) { - key = d3_map_prefix + key; - return key in this && delete this[key]; - } - function d3_map_keys() { - var keys = []; - this.forEach(function(key) { - keys.push(key); - }); - return keys; - } - function d3_map_size() { - var size = 0; - for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) ++size; - return size; - } - function d3_map_empty() { - for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) return false; - return true; - } - d3.nest = function() { - var nest = {}, keys = [], sortKeys = [], sortValues, rollup; - function map(mapType, array, depth) { - if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; - var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; - while (++i < n) { - if (values = valuesByKey.get(keyValue = key(object = array[i]))) { - values.push(object); - } else { - valuesByKey.set(keyValue, [ object ]); - } - } - if (mapType) { - object = mapType(); - setter = function(keyValue, values) { - object.set(keyValue, map(mapType, values, depth)); - }; - } else { - object = {}; - setter = function(keyValue, values) { - object[keyValue] = map(mapType, values, depth); - }; - } - valuesByKey.forEach(setter); - return object; - } - function entries(map, depth) { - if (depth >= keys.length) return map; - var array = [], sortKey = sortKeys[depth++]; - map.forEach(function(key, keyMap) { - array.push({ - key: key, - values: entries(keyMap, depth) - }); - }); - return sortKey ? array.sort(function(a, b) { - return sortKey(a.key, b.key); - }) : array; - } - nest.map = function(array, mapType) { - return map(mapType, array, 0); - }; - nest.entries = function(array) { - return entries(map(d3.map, array, 0), 0); - }; - nest.key = function(d) { - keys.push(d); - return nest; - }; - nest.sortKeys = function(order) { - sortKeys[keys.length - 1] = order; - return nest; - }; - nest.sortValues = function(order) { - sortValues = order; - return nest; - }; - nest.rollup = function(f) { - rollup = f; - return nest; - }; - return nest; - }; - d3.set = function(array) { - var set = new d3_Set(); - if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); - return set; - }; - function d3_Set() {} - d3_class(d3_Set, { - has: d3_map_has, - add: function(value) { - this[d3_map_prefix + value] = true; - return value; - }, - remove: function(value) { - value = d3_map_prefix + value; - return value in this && delete this[value]; - }, - values: d3_map_keys, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var value in this) if (value.charCodeAt(0) === d3_map_prefixCode) f.call(this, value.substring(1)); - } - }); - d3.behavior = {}; - d3.rebind = function(target, source) { - var i = 1, n = arguments.length, method; - while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); - return target; - }; - function d3_rebind(target, source, method) { - return function() { - var value = method.apply(source, arguments); - return value === source ? target : value; - }; - } - function d3_vendorSymbol(object, name) { - if (name in object) return name; - name = name.charAt(0).toUpperCase() + name.substring(1); - for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { - var prefixName = d3_vendorPrefixes[i] + name; - if (prefixName in object) return prefixName; - } - } - var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; - function d3_noop() {} - d3.dispatch = function() { - var dispatch = new d3_dispatch(), i = -1, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - return dispatch; - }; - function d3_dispatch() {} - d3_dispatch.prototype.on = function(type, listener) { - var i = type.indexOf("."), name = ""; - if (i >= 0) { - name = type.substring(i + 1); - type = type.substring(0, i); - } - if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); - if (arguments.length === 2) { - if (listener == null) for (type in this) { - if (this.hasOwnProperty(type)) this[type].on(name, null); - } - return this; - } - }; - function d3_dispatch_event(dispatch) { - var listeners = [], listenerByName = new d3_Map(); - function event() { - var z = listeners, i = -1, n = z.length, l; - while (++i < n) if (l = z[i].on) l.apply(this, arguments); - return dispatch; - } - event.on = function(name, listener) { - var l = listenerByName.get(name), i; - if (arguments.length < 2) return l && l.on; - if (l) { - l.on = null; - listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); - listenerByName.remove(name); - } - if (listener) listeners.push(listenerByName.set(name, { - on: listener - })); - return dispatch; - }; - return event; - } - d3.event = null; - function d3_eventPreventDefault() { - d3.event.preventDefault(); - } - function d3_eventSource() { - var e = d3.event, s; - while (s = e.sourceEvent) e = s; - return e; - } - function d3_eventDispatch(target) { - var dispatch = new d3_dispatch(), i = 0, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - dispatch.of = function(thiz, argumentz) { - return function(e1) { - try { - var e0 = e1.sourceEvent = d3.event; - e1.target = target; - d3.event = e1; - dispatch[e1.type].apply(thiz, argumentz); - } finally { - d3.event = e0; - } - }; - }; - return dispatch; - } - d3.requote = function(s) { - return s.replace(d3_requote_re, "\\$&"); - }; - var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; - var d3_subclass = {}.__proto__ ? function(object, prototype) { - object.__proto__ = prototype; - } : function(object, prototype) { - for (var property in prototype) object[property] = prototype[property]; - }; - function d3_selection(groups) { - d3_subclass(groups, d3_selectionPrototype); - return groups; - } - var d3_select = function(s, n) { - return n.querySelector(s); - }, d3_selectAll = function(s, n) { - return n.querySelectorAll(s); - }, d3_selectMatcher = d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) { - return d3_selectMatcher.call(n, s); - }; - if (typeof Sizzle === "function") { - d3_select = function(s, n) { - return Sizzle(s, n)[0] || null; - }; - d3_selectAll = Sizzle; - d3_selectMatches = Sizzle.matchesSelector; - } - d3.selection = function() { - return d3_selectionRoot; - }; - var d3_selectionPrototype = d3.selection.prototype = []; - d3_selectionPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, group, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(subnode = selector.call(node, node.__data__, i, j)); - if (subnode && "__data__" in node) subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selector(selector) { - return typeof selector === "function" ? selector : function() { - return d3_select(selector, this); - }; - } - d3_selectionPrototype.selectAll = function(selector) { - var subgroups = [], subgroup, node; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); - subgroup.parentNode = node; - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selectorAll(selector) { - return typeof selector === "function" ? selector : function() { - return d3_selectAll(selector, this); - }; - } - var d3_nsPrefix = { - svg: "http://www.w3.org/2000/svg", - xhtml: "http://www.w3.org/1999/xhtml", - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" - }; - d3.ns = { - prefix: d3_nsPrefix, - qualify: function(name) { - var i = name.indexOf(":"), prefix = name; - if (i >= 0) { - prefix = name.substring(0, i); - name = name.substring(i + 1); - } - return d3_nsPrefix.hasOwnProperty(prefix) ? { - space: d3_nsPrefix[prefix], - local: name - } : name; - } - }; - d3_selectionPrototype.attr = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(); - name = d3.ns.qualify(name); - return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); - } - for (value in name) this.each(d3_selection_attr(value, name[value])); - return this; - } - return this.each(d3_selection_attr(name, value)); - }; - function d3_selection_attr(name, value) { - name = d3.ns.qualify(name); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrConstant() { - this.setAttribute(name, value); - } - function attrConstantNS() { - this.setAttributeNS(name.space, name.local, value); - } - function attrFunction() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); - } - function attrFunctionNS() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); - } - return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; - } - function d3_collapse(s) { - return s.trim().replace(/\s+/g, " "); - } - d3_selectionPrototype.classed = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1; - if (value = node.classList) { - while (++i < n) if (!value.contains(name[i])) return false; - } else { - value = node.getAttribute("class"); - while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; - } - return true; - } - for (value in name) this.each(d3_selection_classed(value, name[value])); - return this; - } - return this.each(d3_selection_classed(name, value)); - }; - function d3_selection_classedRe(name) { - return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); - } - function d3_selection_classes(name) { - return name.trim().split(/^|\s+/); - } - function d3_selection_classed(name, value) { - name = d3_selection_classes(name).map(d3_selection_classedName); - var n = name.length; - function classedConstant() { - var i = -1; - while (++i < n) name[i](this, value); - } - function classedFunction() { - var i = -1, x = value.apply(this, arguments); - while (++i < n) name[i](this, x); - } - return typeof value === "function" ? classedFunction : classedConstant; - } - function d3_selection_classedName(name) { - var re = d3_selection_classedRe(name); - return function(node, value) { - if (c = node.classList) return value ? c.add(name) : c.remove(name); - var c = node.getAttribute("class") || ""; - if (value) { - re.lastIndex = 0; - if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); - } else { - node.setAttribute("class", d3_collapse(c.replace(re, " "))); - } - }; - } - d3_selectionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); - return this; - } - if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); - priority = ""; - } - return this.each(d3_selection_style(name, value, priority)); - }; - function d3_selection_style(name, value, priority) { - function styleNull() { - this.style.removeProperty(name); - } - function styleConstant() { - this.style.setProperty(name, value, priority); - } - function styleFunction() { - var x = value.apply(this, arguments); - if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); - } - return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; - } - d3_selectionPrototype.property = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") return this.node()[name]; - for (value in name) this.each(d3_selection_property(value, name[value])); - return this; - } - return this.each(d3_selection_property(name, value)); - }; - function d3_selection_property(name, value) { - function propertyNull() { - delete this[name]; - } - function propertyConstant() { - this[name] = value; - } - function propertyFunction() { - var x = value.apply(this, arguments); - if (x == null) delete this[name]; else this[name] = x; - } - return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; - } - d3_selectionPrototype.text = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - } : value == null ? function() { - this.textContent = ""; - } : function() { - this.textContent = value; - }) : this.node().textContent; - }; - d3_selectionPrototype.html = function(value) { - throw "disallowed by chromium security"; - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - } : value == null ? function() { - this.innerHTML = ""; - } : function() { - this.innerHTML = value; - }) : this.node().innerHTML; - }; - d3_selectionPrototype.append = function(name) { - name = d3_selection_creator(name); - return this.select(function() { - return this.appendChild(name.apply(this, arguments)); - }); - }; - function d3_selection_creator(name) { - return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() { - return this.ownerDocument.createElementNS(name.space, name.local); - } : function() { - return this.ownerDocument.createElementNS(this.namespaceURI, name); - }; - } - d3_selectionPrototype.insert = function(name, before) { - name = d3_selection_creator(name); - before = d3_selection_selector(before); - return this.select(function() { - return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null); - }); - }; - d3_selectionPrototype.remove = function() { - return this.each(function() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); - }); - }; - d3_selectionPrototype.data = function(value, key) { - var i = -1, n = this.length, group, node; - if (!arguments.length) { - value = new Array(n = (group = this[0]).length); - while (++i < n) { - if (node = group[i]) { - value[i] = node.__data__; - } - } - return value; - } - function bind(group, groupData) { - var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; - if (key) { - var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue; - for (i = -1; ++i < n; ) { - keyValue = key.call(node = group[i], node.__data__, i); - if (nodeByKeyValue.has(keyValue)) { - exitNodes[i] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } - keyValues.push(keyValue); - } - for (i = -1; ++i < m; ) { - keyValue = key.call(groupData, nodeData = groupData[i], i); - if (node = nodeByKeyValue.get(keyValue)) { - updateNodes[i] = node; - node.__data__ = nodeData; - } else if (!dataByKeyValue.has(keyValue)) { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - dataByKeyValue.set(keyValue, nodeData); - nodeByKeyValue.remove(keyValue); - } - for (i = -1; ++i < n; ) { - if (nodeByKeyValue.has(keyValues[i])) { - exitNodes[i] = group[i]; - } - } - } else { - for (i = -1; ++i < n0; ) { - node = group[i]; - nodeData = groupData[i]; - if (node) { - node.__data__ = nodeData; - updateNodes[i] = node; - } else { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - } - for (;i < m; ++i) { - enterNodes[i] = d3_selection_dataNode(groupData[i]); - } - for (;i < n; ++i) { - exitNodes[i] = group[i]; - } - } - enterNodes.update = updateNodes; - enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; - enter.push(enterNodes); - update.push(updateNodes); - exit.push(exitNodes); - } - var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); - if (typeof value === "function") { - while (++i < n) { - bind(group = this[i], value.call(group, group.parentNode.__data__, i)); - } - } else { - while (++i < n) { - bind(group = this[i], value); - } - } - update.enter = function() { - return enter; - }; - update.exit = function() { - return exit; - }; - return update; - }; - function d3_selection_dataNode(data) { - return { - __data__: data - }; - } - d3_selectionPrototype.datum = function(value) { - return arguments.length ? this.property("__data__", value) : this.property("__data__"); - }; - d3_selectionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_filter(selector) { - return function() { - return d3_selectMatches(this, selector); - }; - } - d3_selectionPrototype.order = function() { - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - return this; - }; - d3_selectionPrototype.sort = function(comparator) { - comparator = d3_selection_sortComparator.apply(this, arguments); - for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); - return this.order(); - }; - function d3_selection_sortComparator(comparator) { - if (!arguments.length) comparator = d3_ascending; - return function(a, b) { - return a && b ? comparator(a.__data__, b.__data__) : !a - !b; - }; - } - d3_selectionPrototype.each = function(callback) { - return d3_selection_each(this, function(node, i, j) { - callback.call(node, node.__data__, i, j); - }); - }; - function d3_selection_each(groups, callback) { - for (var j = 0, m = groups.length; j < m; j++) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { - if (node = group[i]) callback(node, i, j); - } - } - return groups; - } - d3_selectionPrototype.call = function(callback) { - var args = d3_array(arguments); - callback.apply(args[0] = this, args); - return this; - }; - d3_selectionPrototype.empty = function() { - return !this.node(); - }; - d3_selectionPrototype.node = function() { - for (var j = 0, m = this.length; j < m; j++) { - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - var node = group[i]; - if (node) return node; - } - } - return null; - }; - d3_selectionPrototype.size = function() { - var n = 0; - this.each(function() { - ++n; - }); - return n; - }; - function d3_selection_enter(selection) { - d3_subclass(selection, d3_selection_enterPrototype); - return selection; - } - var d3_selection_enterPrototype = []; - d3.selection.enter = d3_selection_enter; - d3.selection.enter.prototype = d3_selection_enterPrototype; - d3_selection_enterPrototype.append = d3_selectionPrototype.append; - d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; - d3_selection_enterPrototype.node = d3_selectionPrototype.node; - d3_selection_enterPrototype.call = d3_selectionPrototype.call; - d3_selection_enterPrototype.size = d3_selectionPrototype.size; - d3_selection_enterPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, upgroup, group, node; - for (var j = -1, m = this.length; ++j < m; ) { - upgroup = (group = this[j]).update; - subgroups.push(subgroup = []); - subgroup.parentNode = group.parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); - subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - d3_selection_enterPrototype.insert = function(name, before) { - if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); - return d3_selectionPrototype.insert.call(this, name, before); - }; - function d3_selection_enterInsertBefore(enter) { - var i0, j0; - return function(d, i, j) { - var group = enter[j].update, n = group.length, node; - if (j != j0) j0 = j, i0 = 0; - if (i >= i0) i0 = i + 1; - while (!(node = group[i0]) && ++i0 < n) ; - return node; - }; - } - d3_selectionPrototype.transition = function() { - var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = d3_transitionInherit || { - time: Date.now(), - ease: d3_ease_cubicInOut, - delay: 0, - duration: 250 - }; - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) d3_transitionNode(node, i, id, transition); - subgroup.push(node); - } - } - return d3_transition(subgroups, id); - }; - d3_selectionPrototype.interrupt = function() { - return this.each(d3_selection_interrupt); - }; - function d3_selection_interrupt() { - var lock = this.__transition__; - if (lock) ++lock.active; - } - d3.select = function(node) { - var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ]; - group.parentNode = d3_documentElement; - return d3_selection([ group ]); - }; - d3.selectAll = function(nodes) { - var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes); - group.parentNode = d3_documentElement; - return d3_selection([ group ]); - }; - var d3_selectionRoot = d3.select(d3_documentElement); - d3_selectionPrototype.on = function(type, listener, capture) { - var n = arguments.length; - if (n < 3) { - if (typeof type !== "string") { - if (n < 2) listener = false; - for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); - return this; - } - if (n < 2) return (n = this.node()["__on" + type]) && n._; - capture = false; - } - return this.each(d3_selection_on(type, listener, capture)); - }; - function d3_selection_on(type, listener, capture) { - var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; - if (i > 0) type = type.substring(0, i); - var filter = d3_selection_onFilters.get(type); - if (filter) type = filter, wrap = d3_selection_onFilter; - function onRemove() { - var l = this[name]; - if (l) { - this.removeEventListener(type, l, l.$); - delete this[name]; - } - } - function onAdd() { - var l = wrap(listener, d3_array(arguments)); - onRemove.call(this); - this.addEventListener(type, this[name] = l, l.$ = capture); - l._ = listener; - } - function removeAll() { - var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; - for (var name in this) { - if (match = name.match(re)) { - var l = this[name]; - this.removeEventListener(match[1], l, l.$); - delete this[name]; - } - } - } - return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; - } - var d3_selection_onFilters = d3.map({ - mouseenter: "mouseover", - mouseleave: "mouseout" - }); - d3_selection_onFilters.forEach(function(k) { - if ("on" + k in d3_document) d3_selection_onFilters.remove(k); - }); - function d3_selection_onListener(listener, argumentz) { - return function(e) { - var o = d3.event; - d3.event = e; - argumentz[0] = this.__data__; - try { - listener.apply(this, argumentz); - } finally { - d3.event = o; - } - }; - } - function d3_selection_onFilter(listener, argumentz) { - var l = d3_selection_onListener(listener, argumentz); - return function(e) { - var target = this, related = e.relatedTarget; - if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { - l.call(target, e); - } - }; - } - var d3_event_dragSelect = "onselectstart" in d3_document ? null : d3_vendorSymbol(d3_documentElement.style, "userSelect"), d3_event_dragId = 0; - function d3_event_dragSuppress() { - var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault); - if (d3_event_dragSelect) { - var style = d3_documentElement.style, select = style[d3_event_dragSelect]; - style[d3_event_dragSelect] = "none"; - } - return function(suppressClick) { - w.on(name, null); - if (d3_event_dragSelect) style[d3_event_dragSelect] = select; - if (suppressClick) { - function off() { - w.on(click, null); - } - w.on(click, function() { - d3_eventPreventDefault(); - off(); - }, true); - setTimeout(off, 0); - } - }; - } - d3.mouse = function(container) { - return d3_mousePoint(container, d3_eventSource()); - }; - function d3_mousePoint(container, e) { - if (e.changedTouches) e = e.changedTouches[0]; - var svg = container.ownerSVGElement || container; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - point.x = e.clientX, point.y = e.clientY; - point = point.matrixTransform(container.getScreenCTM().inverse()); - return [ point.x, point.y ]; - } - var rect = container.getBoundingClientRect(); - return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; - } - d3.touches = function(container, touches) { - if (arguments.length < 2) touches = d3_eventSource().touches; - return touches ? d3_array(touches).map(function(touch) { - var point = d3_mousePoint(container, touch); - point.identifier = touch.identifier; - return point; - }) : []; - }; - d3.behavior.drag = function() { - var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_behavior_dragMouseSubject, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_behavior_dragTouchSubject, "touchmove", "touchend"); - function drag() { - this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); - } - function dragstart(id, position, subject, move, end) { - return function() { - var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject()).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(), position0 = position(parent, dragId); - if (origin) { - dragOffset = origin.apply(that, arguments); - dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ]; - } else { - dragOffset = [ 0, 0 ]; - } - dispatch({ - type: "dragstart" - }); - function moved() { - var position1 = position(parent, dragId), dx, dy; - if (!position1) return; - dx = position1[0] - position0[0]; - dy = position1[1] - position0[1]; - dragged |= dx | dy; - position0 = position1; - dispatch({ - type: "drag", - x: position1[0] + dragOffset[0], - y: position1[1] + dragOffset[1], - dx: dx, - dy: dy - }); - } - function ended() { - if (!position(parent, dragId)) return; - dragSubject.on(move + dragName, null).on(end + dragName, null); - dragRestore(dragged && d3.event.target === target); - dispatch({ - type: "dragend" - }); - } - }; - } - drag.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return drag; - }; - return d3.rebind(drag, event, "on"); - }; - function d3_behavior_dragTouchId() { - return d3.event.changedTouches[0].identifier; - } - function d3_behavior_dragTouchSubject() { - return d3.event.target; - } - function d3_behavior_dragMouseSubject() { - return d3_window; - } - var π = Math.PI, τ = 2 * π, halfπ = π / 2, ε = 1e-6, ε2 = ε * ε, d3_radians = π / 180, d3_degrees = 180 / π; - function d3_sgn(x) { - return x > 0 ? 1 : x < 0 ? -1 : 0; - } - function d3_cross2d(a, b, c) { - return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); - } - function d3_acos(x) { - return x > 1 ? 0 : x < -1 ? π : Math.acos(x); - } - function d3_asin(x) { - return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x); - } - function d3_sinh(x) { - return ((x = Math.exp(x)) - 1 / x) / 2; - } - function d3_cosh(x) { - return ((x = Math.exp(x)) + 1 / x) / 2; - } - function d3_tanh(x) { - return ((x = Math.exp(2 * x)) - 1) / (x + 1); - } - function d3_haversin(x) { - return (x = Math.sin(x / 2)) * x; - } - var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4; - d3.interpolateZoom = function(p0, p1) { - var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; - var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ; - function interpolate(t) { - var s = t * S; - if (dr) { - var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0)); - return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ]; - } - return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ]; - } - interpolate.duration = S * 1e3; - return interpolate; - }; - d3.behavior.zoom = function() { - var view = { - x: 0, - y: 0, - k: 1 - }, translate0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; - function zoom(g) { - g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); - } - zoom.event = function(g) { - g.each(function() { - var dispatch = event.of(this, arguments), view1 = view; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.zoom", function() { - view = this.__chart__ || { - x: 0, - y: 0, - k: 1 - }; - zoomstarted(dispatch); - }).tween("zoom:zoom", function() { - var dx = size[0], dy = size[1], cx = dx / 2, cy = dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); - return function(t) { - var l = i(t), k = dx / l[2]; - this.__chart__ = view = { - x: cx - l[0] * k, - y: cy - l[1] * k, - k: k - }; - zoomed(dispatch); - }; - }).each("end.zoom", function() { - zoomended(dispatch); - }); - } else { - this.__chart__ = view; - zoomstarted(dispatch); - zoomed(dispatch); - zoomended(dispatch); - } - }); - }; - zoom.translate = function(_) { - if (!arguments.length) return [ view.x, view.y ]; - view = { - x: +_[0], - y: +_[1], - k: view.k - }; - rescale(); - return zoom; - }; - zoom.scale = function(_) { - if (!arguments.length) return view.k; - view = { - x: view.x, - y: view.y, - k: +_ - }; - rescale(); - return zoom; - }; - zoom.scaleExtent = function(_) { - if (!arguments.length) return scaleExtent; - scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; - return zoom; - }; - zoom.center = function(_) { - if (!arguments.length) return center; - center = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.size = function(_) { - if (!arguments.length) return size; - size = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.x = function(z) { - if (!arguments.length) return x1; - x1 = z; - x0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - zoom.y = function(z) { - if (!arguments.length) return y1; - y1 = z; - y0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - function location(p) { - return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; - } - function point(l) { - return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; - } - function scaleTo(s) { - view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); - } - function translateTo(p, l) { - l = point(l); - view.x += p[0] - l[0]; - view.y += p[1] - l[1]; - } - function rescale() { - if (x1) x1.domain(x0.range().map(function(x) { - return (x - view.x) / view.k; - }).map(x0.invert)); - if (y1) y1.domain(y0.range().map(function(y) { - return (y - view.y) / view.k; - }).map(y0.invert)); - } - function zoomstarted(dispatch) { - dispatch({ - type: "zoomstart" - }); - } - function zoomed(dispatch) { - rescale(); - dispatch({ - type: "zoom", - scale: view.k, - translate: [ view.x, view.y ] - }); - } - function zoomended(dispatch) { - dispatch({ - type: "zoomend" - }); - } - function mousedowned() { - var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(); - d3_selection_interrupt.call(that); - zoomstarted(dispatch); - function moved() { - dragged = 1; - translateTo(d3.mouse(that), location0); - zoomed(dispatch); - } - function ended() { - subject.on(mousemove, d3_window === that ? mousewheelreset : null).on(mouseup, null); - dragRestore(dragged && d3.event.target === target); - zoomended(dispatch); - } - } - function touchstarted() { - var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, target = d3.select(d3.event.target).on(touchmove, moved).on(touchend, ended), subject = d3.select(that).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress(); - d3_selection_interrupt.call(that); - started(); - zoomstarted(dispatch); - function relocate() { - var touches = d3.touches(that); - scale0 = view.k; - touches.forEach(function(t) { - if (t.identifier in locations0) locations0[t.identifier] = location(t); - }); - return touches; - } - function started() { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - locations0[changed[i].identifier] = null; - } - var touches = relocate(), now = Date.now(); - if (touches.length === 1) { - if (now - touchtime < 500) { - var p = touches[0], l = locations0[p.identifier]; - scaleTo(view.k * 2); - translateTo(p, l); - d3_eventPreventDefault(); - zoomed(dispatch); - } - touchtime = now; - } else if (touches.length > 1) { - var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; - distance0 = dx * dx + dy * dy; - } - } - function moved() { - var touches = d3.touches(that), p0, l0, p1, l1; - for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { - p1 = touches[i]; - if (l1 = locations0[p1.identifier]) { - if (l0) break; - p0 = p1, l0 = l1; - } - } - if (l1) { - var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); - p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; - l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; - scaleTo(scale1 * scale0); - } - touchtime = null; - translateTo(p0, l0); - zoomed(dispatch); - } - function ended() { - if (d3.event.touches.length) { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - delete locations0[changed[i].identifier]; - } - for (var identifier in locations0) { - return void relocate(); - } - } - target.on(zoomName, null); - subject.on(mousedown, mousedowned).on(touchstart, touchstarted); - dragRestore(); - zoomended(dispatch); - } - } - function mousewheeled() { - var dispatch = event.of(this, arguments); - if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), - zoomstarted(dispatch); - mousewheelTimer = setTimeout(function() { - mousewheelTimer = null; - zoomended(dispatch); - }, 50); - d3_eventPreventDefault(); - var point = center || d3.mouse(this); - if (!translate0) translate0 = location(point); - scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); - translateTo(point, translate0); - zoomed(dispatch); - } - function mousewheelreset() { - translate0 = null; - } - function dblclicked() { - var dispatch = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2; - zoomstarted(dispatch); - scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1)); - translateTo(p, l); - zoomed(dispatch); - zoomended(dispatch); - } - return d3.rebind(zoom, event, "on"); - }; - var d3_behavior_zoomInfinity = [ 0, Infinity ]; - var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); - }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return d3.event.wheelDelta; - }, "mousewheel") : (d3_behavior_zoomDelta = function() { - return -d3.event.detail; - }, "MozMousePixelScroll"); - function d3_Color() {} - d3_Color.prototype.toString = function() { - return this.rgb() + ""; - }; - d3.hsl = function(h, s, l) { - return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l); - }; - function d3_hsl(h, s, l) { - return new d3_Hsl(h, s, l); - } - function d3_Hsl(h, s, l) { - this.h = h; - this.s = s; - this.l = l; - } - var d3_hslPrototype = d3_Hsl.prototype = new d3_Color(); - d3_hslPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, this.l / k); - }; - d3_hslPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, k * this.l); - }; - d3_hslPrototype.rgb = function() { - return d3_hsl_rgb(this.h, this.s, this.l); - }; - function d3_hsl_rgb(h, s, l) { - var m1, m2; - h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; - s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; - l = l < 0 ? 0 : l > 1 ? 1 : l; - m2 = l <= .5 ? l * (1 + s) : l + s - l * s; - m1 = 2 * l - m2; - function v(h) { - if (h > 360) h -= 360; else if (h < 0) h += 360; - if (h < 60) return m1 + (m2 - m1) * h / 60; - if (h < 180) return m2; - if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; - return m1; - } - function vv(h) { - return Math.round(v(h) * 255); - } - return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); - } - d3.hcl = function(h, c, l) { - return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l); - }; - function d3_hcl(h, c, l) { - return new d3_Hcl(h, c, l); - } - function d3_Hcl(h, c, l) { - this.h = h; - this.c = c; - this.l = l; - } - var d3_hclPrototype = d3_Hcl.prototype = new d3_Color(); - d3_hclPrototype.brighter = function(k) { - return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.darker = function(k) { - return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.rgb = function() { - return d3_hcl_lab(this.h, this.c, this.l).rgb(); - }; - function d3_hcl_lab(h, c, l) { - if (isNaN(h)) h = 0; - if (isNaN(c)) c = 0; - return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); - } - d3.lab = function(l, a, b) { - return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b); - }; - function d3_lab(l, a, b) { - return new d3_Lab(l, a, b); - } - function d3_Lab(l, a, b) { - this.l = l; - this.a = a; - this.b = b; - } - var d3_lab_K = 18; - var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; - var d3_labPrototype = d3_Lab.prototype = new d3_Color(); - d3_labPrototype.brighter = function(k) { - return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.darker = function(k) { - return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.rgb = function() { - return d3_lab_rgb(this.l, this.a, this.b); - }; - function d3_lab_rgb(l, a, b) { - var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; - x = d3_lab_xyz(x) * d3_lab_X; - y = d3_lab_xyz(y) * d3_lab_Y; - z = d3_lab_xyz(z) * d3_lab_Z; - return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); - } - function d3_lab_hcl(l, a, b) { - return l > 0 ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : d3_hcl(NaN, NaN, l); - } - function d3_lab_xyz(x) { - return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; - } - function d3_xyz_lab(x) { - return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; - } - function d3_xyz_rgb(r) { - return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); - } - d3.rgb = function(r, g, b) { - return arguments.length === 1 ? r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : d3_rgb(~~r, ~~g, ~~b); - }; - function d3_rgbNumber(value) { - return d3_rgb(value >> 16, value >> 8 & 255, value & 255); - } - function d3_rgbString(value) { - return d3_rgbNumber(value) + ""; - } - function d3_rgb(r, g, b) { - return new d3_Rgb(r, g, b); - } - function d3_Rgb(r, g, b) { - this.r = r; - this.g = g; - this.b = b; - } - var d3_rgbPrototype = d3_Rgb.prototype = new d3_Color(); - d3_rgbPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - var r = this.r, g = this.g, b = this.b, i = 30; - if (!r && !g && !b) return d3_rgb(i, i, i); - if (r && r < i) r = i; - if (g && g < i) g = i; - if (b && b < i) b = i; - return d3_rgb(Math.min(255, ~~(r / k)), Math.min(255, ~~(g / k)), Math.min(255, ~~(b / k))); - }; - d3_rgbPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_rgb(~~(k * this.r), ~~(k * this.g), ~~(k * this.b)); - }; - d3_rgbPrototype.hsl = function() { - return d3_rgb_hsl(this.r, this.g, this.b); - }; - d3_rgbPrototype.toString = function() { - return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); - }; - function d3_rgb_hex(v) { - return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); - } - function d3_rgb_parse(format, rgb, hsl) { - var r = 0, g = 0, b = 0, m1, m2, color; - m1 = /([a-z]+)\((.*)\)/i.exec(format); - if (m1) { - m2 = m1[2].split(","); - switch (m1[1]) { - case "hsl": - { - return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); - } - - case "rgb": - { - return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); - } - } - } - if (color = d3_rgb_names.get(format)) return rgb(color.r, color.g, color.b); - if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.substring(1), 16))) { - if (format.length === 4) { - r = (color & 3840) >> 4; - r = r >> 4 | r; - g = color & 240; - g = g >> 4 | g; - b = color & 15; - b = b << 4 | b; - } else if (format.length === 7) { - r = (color & 16711680) >> 16; - g = (color & 65280) >> 8; - b = color & 255; - } - } - return rgb(r, g, b); - } - function d3_rgb_hsl(r, g, b) { - var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; - if (d) { - s = l < .5 ? d / (max + min) : d / (2 - max - min); - if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; - h *= 60; - } else { - h = NaN; - s = l > 0 && l < 1 ? 0 : h; - } - return d3_hsl(h, s, l); - } - function d3_rgb_lab(r, g, b) { - r = d3_rgb_xyz(r); - g = d3_rgb_xyz(g); - b = d3_rgb_xyz(b); - var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); - return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); - } - function d3_rgb_xyz(r) { - return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); - } - function d3_rgb_parseNumber(c) { - var f = parseFloat(c); - return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; - } - var d3_rgb_names = d3.map({ - aliceblue: 15792383, - antiquewhite: 16444375, - aqua: 65535, - aquamarine: 8388564, - azure: 15794175, - beige: 16119260, - bisque: 16770244, - black: 0, - blanchedalmond: 16772045, - blue: 255, - blueviolet: 9055202, - brown: 10824234, - burlywood: 14596231, - cadetblue: 6266528, - chartreuse: 8388352, - chocolate: 13789470, - coral: 16744272, - cornflowerblue: 6591981, - cornsilk: 16775388, - crimson: 14423100, - cyan: 65535, - darkblue: 139, - darkcyan: 35723, - darkgoldenrod: 12092939, - darkgray: 11119017, - darkgreen: 25600, - darkgrey: 11119017, - darkkhaki: 12433259, - darkmagenta: 9109643, - darkolivegreen: 5597999, - darkorange: 16747520, - darkorchid: 10040012, - darkred: 9109504, - darksalmon: 15308410, - darkseagreen: 9419919, - darkslateblue: 4734347, - darkslategray: 3100495, - darkslategrey: 3100495, - darkturquoise: 52945, - darkviolet: 9699539, - deeppink: 16716947, - deepskyblue: 49151, - dimgray: 6908265, - dimgrey: 6908265, - dodgerblue: 2003199, - firebrick: 11674146, - floralwhite: 16775920, - forestgreen: 2263842, - fuchsia: 16711935, - gainsboro: 14474460, - ghostwhite: 16316671, - gold: 16766720, - goldenrod: 14329120, - gray: 8421504, - green: 32768, - greenyellow: 11403055, - grey: 8421504, - honeydew: 15794160, - hotpink: 16738740, - indianred: 13458524, - indigo: 4915330, - ivory: 16777200, - khaki: 15787660, - lavender: 15132410, - lavenderblush: 16773365, - lawngreen: 8190976, - lemonchiffon: 16775885, - lightblue: 11393254, - lightcoral: 15761536, - lightcyan: 14745599, - lightgoldenrodyellow: 16448210, - lightgray: 13882323, - lightgreen: 9498256, - lightgrey: 13882323, - lightpink: 16758465, - lightsalmon: 16752762, - lightseagreen: 2142890, - lightskyblue: 8900346, - lightslategray: 7833753, - lightslategrey: 7833753, - lightsteelblue: 11584734, - lightyellow: 16777184, - lime: 65280, - limegreen: 3329330, - linen: 16445670, - magenta: 16711935, - maroon: 8388608, - mediumaquamarine: 6737322, - mediumblue: 205, - mediumorchid: 12211667, - mediumpurple: 9662683, - mediumseagreen: 3978097, - mediumslateblue: 8087790, - mediumspringgreen: 64154, - mediumturquoise: 4772300, - mediumvioletred: 13047173, - midnightblue: 1644912, - mintcream: 16121850, - mistyrose: 16770273, - moccasin: 16770229, - navajowhite: 16768685, - navy: 128, - oldlace: 16643558, - olive: 8421376, - olivedrab: 7048739, - orange: 16753920, - orangered: 16729344, - orchid: 14315734, - palegoldenrod: 15657130, - palegreen: 10025880, - paleturquoise: 11529966, - palevioletred: 14381203, - papayawhip: 16773077, - peachpuff: 16767673, - peru: 13468991, - pink: 16761035, - plum: 14524637, - powderblue: 11591910, - purple: 8388736, - red: 16711680, - rosybrown: 12357519, - royalblue: 4286945, - saddlebrown: 9127187, - salmon: 16416882, - sandybrown: 16032864, - seagreen: 3050327, - seashell: 16774638, - sienna: 10506797, - silver: 12632256, - skyblue: 8900331, - slateblue: 6970061, - slategray: 7372944, - slategrey: 7372944, - snow: 16775930, - springgreen: 65407, - steelblue: 4620980, - tan: 13808780, - teal: 32896, - thistle: 14204888, - tomato: 16737095, - turquoise: 4251856, - violet: 15631086, - wheat: 16113331, - white: 16777215, - whitesmoke: 16119285, - yellow: 16776960, - yellowgreen: 10145074 - }); - d3_rgb_names.forEach(function(key, value) { - d3_rgb_names.set(key, d3_rgbNumber(value)); - }); - function d3_functor(v) { - return typeof v === "function" ? v : function() { - return v; - }; - } - d3.functor = d3_functor; - function d3_identity(d) { - return d; - } - d3.xhr = d3_xhrType(d3_identity); - function d3_xhrType(response) { - return function(url, mimeType, callback) { - if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, - mimeType = null; - return d3_xhr(url, mimeType, response, callback); - }; - } - function d3_xhr(url, mimeType, response, callback) { - var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; - if (d3_window.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); - "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { - request.readyState > 3 && respond(); - }; - function respond() { - var status = request.status, result; - if (!status && request.responseText || status >= 200 && status < 300 || status === 304) { - try { - result = response.call(xhr, request); - } catch (e) { - dispatch.error.call(xhr, e); - return; - } - dispatch.load.call(xhr, result); - } else { - dispatch.error.call(xhr, request); - } - } - request.onprogress = function(event) { - var o = d3.event; - d3.event = event; - try { - dispatch.progress.call(xhr, request); - } finally { - d3.event = o; - } - }; - xhr.header = function(name, value) { - name = (name + "").toLowerCase(); - if (arguments.length < 2) return headers[name]; - if (value == null) delete headers[name]; else headers[name] = value + ""; - return xhr; - }; - xhr.mimeType = function(value) { - if (!arguments.length) return mimeType; - mimeType = value == null ? null : value + ""; - return xhr; - }; - xhr.responseType = function(value) { - if (!arguments.length) return responseType; - responseType = value; - return xhr; - }; - xhr.response = function(value) { - response = value; - return xhr; - }; - [ "get", "post" ].forEach(function(method) { - xhr[method] = function() { - return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); - }; - }); - xhr.send = function(method, data, callback) { - if (arguments.length === 2 && typeof data === "function") callback = data, data = null; - request.open(method, url, true); - if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; - if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); - if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); - if (responseType != null) request.responseType = responseType; - if (callback != null) xhr.on("error", callback).on("load", function(request) { - callback(null, request); - }); - dispatch.beforesend.call(xhr, request); - request.send(data == null ? null : data); - return xhr; - }; - xhr.abort = function() { - request.abort(); - return xhr; - }; - d3.rebind(xhr, dispatch, "on"); - return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); - } - function d3_xhr_fixCallback(callback) { - return callback.length === 1 ? function(error, request) { - callback(error == null ? request : null); - } : callback; - } - d3.dsv = function(delimiter, mimeType) { - var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); - function dsv(url, row, callback) { - if (arguments.length < 3) callback = row, row = null; - var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback); - xhr.row = function(_) { - return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; - }; - return xhr; - } - function response(request) { - return dsv.parse(request.responseText); - } - function typedResponse(f) { - return function(request) { - return dsv.parse(request.responseText, f); - }; - } - dsv.parse = function(text, f) { - var o; - return dsv.parseRows(text, function(row, i) { - if (o) return o(row, i - 1); - var a = new Function("d", "return {" + row.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "]"; - }).join(",") + "}"); - o = f ? function(row, i) { - return f(a(row), i); - } : a; - }); - }; - dsv.parseRows = function(text, f) { - var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; - function token() { - if (I >= N) return EOF; - if (eol) return eol = false, EOL; - var j = I; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - var c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.substring(j + 1, i).replace(/""/g, '"'); - } - while (I < N) { - var c = text.charCodeAt(I++), k = 1; - if (c === 10) eol = true; else if (c === 13) { - eol = true; - if (text.charCodeAt(I) === 10) ++I, ++k; - } else if (c !== delimiterCode) continue; - return text.substring(j, I - k); - } - return text.substring(j); - } - while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && !(a = f(a, n++))) continue; - rows.push(a); - } - return rows; - }; - dsv.format = function(rows) { - if (Array.isArray(rows[0])) return dsv.formatRows(rows); - var fieldSet = new d3_Set(), fields = []; - rows.forEach(function(row) { - for (var field in row) { - if (!fieldSet.has(field)) { - fields.push(fieldSet.add(field)); - } - } - }); - return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { - return fields.map(function(field) { - return formatValue(row[field]); - }).join(delimiter); - })).join("\n"); - }; - dsv.formatRows = function(rows) { - return rows.map(formatRow).join("\n"); - }; - function formatRow(row) { - return row.map(formatValue).join(delimiter); - } - function formatValue(text) { - return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; - } - return dsv; - }; - d3.csv = d3.dsv(",", "text/csv"); - d3.tsv = d3.dsv(" ", "text/tab-separated-values"); - d3.touch = function(container, touches, identifier) { - if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches; - if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) { - if ((touch = touches[i]).identifier === identifier) { - return d3_mousePoint(container, touch); - } - } - }; - var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = d3_window[d3_vendorSymbol(d3_window, "requestAnimationFrame")] || function(callback) { - setTimeout(callback, 17); - }; - d3.timer = function(callback, delay, then) { - var n = arguments.length; - if (n < 2) delay = 0; - if (n < 3) then = Date.now(); - var time = then + delay, timer = { - c: callback, - t: time, - f: false, - n: null - }; - if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer; - d3_timer_queueTail = timer; - if (!d3_timer_interval) { - d3_timer_timeout = clearTimeout(d3_timer_timeout); - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - }; - function d3_timer_step() { - var now = d3_timer_mark(), delay = d3_timer_sweep() - now; - if (delay > 24) { - if (isFinite(delay)) { - clearTimeout(d3_timer_timeout); - d3_timer_timeout = setTimeout(d3_timer_step, delay); - } - d3_timer_interval = 0; - } else { - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - } - d3.timer.flush = function() { - d3_timer_mark(); - d3_timer_sweep(); - }; - function d3_timer_mark() { - var now = Date.now(); - d3_timer_active = d3_timer_queueHead; - while (d3_timer_active) { - if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t); - d3_timer_active = d3_timer_active.n; - } - return now; - } - function d3_timer_sweep() { - var t0, t1 = d3_timer_queueHead, time = Infinity; - while (t1) { - if (t1.f) { - t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n; - } else { - if (t1.t < time) time = t1.t; - t1 = (t0 = t1).n; - } - } - d3_timer_queueTail = t0; - return time; - } - function d3_format_precision(x, p) { - return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); - } - d3.round = function(x, n) { - return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); - }; - var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); - d3.formatPrefix = function(value, precision) { - var i = 0; - if (value) { - if (value < 0) value *= -1; - if (precision) value = d3.round(value, d3_format_precision(value, precision)); - i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); - i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3)); - } - return d3_formatPrefixes[8 + i / 3]; - }; - function d3_formatPrefix(d, i) { - var k = Math.pow(10, abs(8 - i) * 3); - return { - scale: i > 8 ? function(d) { - return d / k; - } : function(d) { - return d * k; - }, - symbol: d - }; - } - function d3_locale_numberFormat(locale) { - var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping ? function(value) { - var i = value.length, t = [], j = 0, g = locale_grouping[0]; - while (i > 0 && g > 0) { - t.push(value.substring(i -= g, i + g)); - g = locale_grouping[j = (j + 1) % locale_grouping.length]; - } - return t.reverse().join(locale_thousands); - } : d3_identity; - return function(specifier) { - var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false; - if (precision) precision = +precision.substring(1); - if (zfill || fill === "0" && align === "=") { - zfill = fill = "0"; - align = "="; - if (comma) width -= Math.floor((width - 1) / 4); - } - switch (type) { - case "n": - comma = true; - type = "g"; - break; - - case "%": - scale = 100; - suffix = "%"; - type = "f"; - break; - - case "p": - scale = 100; - suffix = "%"; - type = "r"; - break; - - case "b": - case "o": - case "x": - case "X": - if (symbol === "#") prefix = "0" + type.toLowerCase(); - - case "c": - case "d": - integer = true; - precision = 0; - break; - - case "s": - scale = -1; - type = "r"; - break; - } - if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1]; - if (type == "r" && !precision) type = "g"; - if (precision != null) { - if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); - } - type = d3_format_types.get(type) || d3_format_typeDefault; - var zcomma = zfill && comma; - return function(value) { - var fullSuffix = suffix; - if (integer && value % 1) return ""; - var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; - if (scale < 0) { - var unit = d3.formatPrefix(value, precision); - value = unit.scale(value); - fullSuffix = unit.symbol + suffix; - } else { - value *= scale; - } - value = type(value, precision); - var i = value.lastIndexOf("."), before = i < 0 ? value : value.substring(0, i), after = i < 0 ? "" : locale_decimal + value.substring(i + 1); - if (!zfill && comma) before = formatGroup(before); - var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; - if (zcomma) before = formatGroup(padding + before); - negative += prefix; - value = before + after; - return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix; - }; - }; - } - var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; - var d3_format_types = d3.map({ - b: function(x) { - return x.toString(2); - }, - c: function(x) { - return String.fromCharCode(x); - }, - o: function(x) { - return x.toString(8); - }, - x: function(x) { - return x.toString(16); - }, - X: function(x) { - return x.toString(16).toUpperCase(); - }, - g: function(x, p) { - return x.toPrecision(p); - }, - e: function(x, p) { - return x.toExponential(p); - }, - f: function(x, p) { - return x.toFixed(p); - }, - r: function(x, p) { - return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); - } - }); - function d3_format_typeDefault(x) { - return x + ""; - } - var d3_time = d3.time = {}, d3_date = Date; - function d3_date_utc() { - this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); - } - d3_date_utc.prototype = { - getDate: function() { - return this._.getUTCDate(); - }, - getDay: function() { - return this._.getUTCDay(); - }, - getFullYear: function() { - return this._.getUTCFullYear(); - }, - getHours: function() { - return this._.getUTCHours(); - }, - getMilliseconds: function() { - return this._.getUTCMilliseconds(); - }, - getMinutes: function() { - return this._.getUTCMinutes(); - }, - getMonth: function() { - return this._.getUTCMonth(); - }, - getSeconds: function() { - return this._.getUTCSeconds(); - }, - getTime: function() { - return this._.getTime(); - }, - getTimezoneOffset: function() { - return 0; - }, - valueOf: function() { - return this._.valueOf(); - }, - setDate: function() { - d3_time_prototype.setUTCDate.apply(this._, arguments); - }, - setDay: function() { - d3_time_prototype.setUTCDay.apply(this._, arguments); - }, - setFullYear: function() { - d3_time_prototype.setUTCFullYear.apply(this._, arguments); - }, - setHours: function() { - d3_time_prototype.setUTCHours.apply(this._, arguments); - }, - setMilliseconds: function() { - d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); - }, - setMinutes: function() { - d3_time_prototype.setUTCMinutes.apply(this._, arguments); - }, - setMonth: function() { - d3_time_prototype.setUTCMonth.apply(this._, arguments); - }, - setSeconds: function() { - d3_time_prototype.setUTCSeconds.apply(this._, arguments); - }, - setTime: function() { - d3_time_prototype.setTime.apply(this._, arguments); - } - }; - var d3_time_prototype = Date.prototype; - function d3_time_interval(local, step, number) { - function round(date) { - var d0 = local(date), d1 = offset(d0, 1); - return date - d0 < d1 - date ? d0 : d1; - } - function ceil(date) { - step(date = local(new d3_date(date - 1)), 1); - return date; - } - function offset(date, k) { - step(date = new d3_date(+date), k); - return date; - } - function range(t0, t1, dt) { - var time = ceil(t0), times = []; - if (dt > 1) { - while (time < t1) { - if (!(number(time) % dt)) times.push(new Date(+time)); - step(time, 1); - } - } else { - while (time < t1) times.push(new Date(+time)), step(time, 1); - } - return times; - } - function range_utc(t0, t1, dt) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = t0; - return range(utc, t1, dt); - } finally { - d3_date = Date; - } - } - local.floor = local; - local.round = round; - local.ceil = ceil; - local.offset = offset; - local.range = range; - var utc = local.utc = d3_time_interval_utc(local); - utc.floor = utc; - utc.round = d3_time_interval_utc(round); - utc.ceil = d3_time_interval_utc(ceil); - utc.offset = d3_time_interval_utc(offset); - utc.range = range_utc; - return local; - } - function d3_time_interval_utc(method) { - return function(date, k) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = date; - return method(utc, k)._; - } finally { - d3_date = Date; - } - }; - } - d3_time.year = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setMonth(0, 1); - return date; - }, function(date, offset) { - date.setFullYear(date.getFullYear() + offset); - }, function(date) { - return date.getFullYear(); - }); - d3_time.years = d3_time.year.range; - d3_time.years.utc = d3_time.year.utc.range; - d3_time.day = d3_time_interval(function(date) { - var day = new d3_date(2e3, 0); - day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - return day; - }, function(date, offset) { - date.setDate(date.getDate() + offset); - }, function(date) { - return date.getDate() - 1; - }); - d3_time.days = d3_time.day.range; - d3_time.days.utc = d3_time.day.utc.range; - d3_time.dayOfYear = function(date) { - var year = d3_time.year(date); - return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); - }; - [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) { - i = 7 - i; - var interval = d3_time[day] = d3_time_interval(function(date) { - (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); - return date; - }, function(date, offset) { - date.setDate(date.getDate() + Math.floor(offset) * 7); - }, function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); - }); - d3_time[day + "s"] = interval.range; - d3_time[day + "s"].utc = interval.utc.range; - d3_time[day + "OfYear"] = function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); - }; - }); - d3_time.week = d3_time.sunday; - d3_time.weeks = d3_time.sunday.range; - d3_time.weeks.utc = d3_time.sunday.utc.range; - d3_time.weekOfYear = d3_time.sundayOfYear; - function d3_locale_timeFormat(locale) { - var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; - function d3_time_format(template) { - var n = template.length; - function format(date) { - var string = [], i = -1, j = 0, c, p, f; - while (++i < n) { - if (template.charCodeAt(i) === 37) { - string.push(template.substring(j, i)); - if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); - if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); - string.push(c); - j = i + 1; - } - } - string.push(template.substring(j, i)); - return string.join(""); - } - format.parse = function(string) { - var d = { - y: 1900, - m: 0, - d: 1, - H: 0, - M: 0, - S: 0, - L: 0, - Z: null - }, i = d3_time_parse(d, template, string, 0); - if (i != string.length) return null; - if ("p" in d) d.H = d.H % 12 + d.p * 12; - var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); - if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { - date.setFullYear(d.y, 0, 1); - date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); - } else date.setFullYear(d.y, d.m, d.d); - date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L); - return localZ ? date._ : date; - }; - format.toString = function() { - return template; - }; - return format; - } - function d3_time_parse(date, template, string, j) { - var c, p, t, i = 0, n = template.length, m = string.length; - while (i < n) { - if (j >= m) return -1; - c = template.charCodeAt(i++); - if (c === 37) { - t = template.charAt(i++); - p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; - if (!p || (j = p(date, string, j)) < 0) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; - } - } - return j; - } - d3_time_format.utc = function(template) { - var local = d3_time_format(template); - function format(date) { - try { - d3_date = d3_date_utc; - var utc = new d3_date(); - utc._ = date; - return local(utc); - } finally { - d3_date = Date; - } - } - format.parse = function(string) { - try { - d3_date = d3_date_utc; - var date = local.parse(string); - return date && date._; - } finally { - d3_date = Date; - } - }; - format.toString = local.toString; - return format; - }; - d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti; - var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths); - locale_periods.forEach(function(p, i) { - d3_time_periodLookup.set(p.toLowerCase(), i); - }); - var d3_time_formats = { - a: function(d) { - return locale_shortDays[d.getDay()]; - }, - A: function(d) { - return locale_days[d.getDay()]; - }, - b: function(d) { - return locale_shortMonths[d.getMonth()]; - }, - B: function(d) { - return locale_months[d.getMonth()]; - }, - c: d3_time_format(locale_dateTime), - d: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - e: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - H: function(d, p) { - return d3_time_formatPad(d.getHours(), p, 2); - }, - I: function(d, p) { - return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); - }, - j: function(d, p) { - return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); - }, - L: function(d, p) { - return d3_time_formatPad(d.getMilliseconds(), p, 3); - }, - m: function(d, p) { - return d3_time_formatPad(d.getMonth() + 1, p, 2); - }, - M: function(d, p) { - return d3_time_formatPad(d.getMinutes(), p, 2); - }, - p: function(d) { - return locale_periods[+(d.getHours() >= 12)]; - }, - S: function(d, p) { - return d3_time_formatPad(d.getSeconds(), p, 2); - }, - U: function(d, p) { - return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); - }, - w: function(d) { - return d.getDay(); - }, - W: function(d, p) { - return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); - }, - x: d3_time_format(locale_date), - X: d3_time_format(locale_time), - y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 100, p, 2); - }, - Y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); - }, - Z: d3_time_zone, - "%": function() { - return "%"; - } - }; - var d3_time_parsers = { - a: d3_time_parseWeekdayAbbrev, - A: d3_time_parseWeekday, - b: d3_time_parseMonthAbbrev, - B: d3_time_parseMonth, - c: d3_time_parseLocaleFull, - d: d3_time_parseDay, - e: d3_time_parseDay, - H: d3_time_parseHour24, - I: d3_time_parseHour24, - j: d3_time_parseDayOfYear, - L: d3_time_parseMilliseconds, - m: d3_time_parseMonthNumber, - M: d3_time_parseMinutes, - p: d3_time_parseAmPm, - S: d3_time_parseSeconds, - U: d3_time_parseWeekNumberSunday, - w: d3_time_parseWeekdayNumber, - W: d3_time_parseWeekNumberMonday, - x: d3_time_parseLocaleDate, - X: d3_time_parseLocaleTime, - y: d3_time_parseYear, - Y: d3_time_parseFullYear, - Z: d3_time_parseZone, - "%": d3_time_parseLiteralPercent - }; - function d3_time_parseWeekdayAbbrev(date, string, i) { - d3_time_dayAbbrevRe.lastIndex = 0; - var n = d3_time_dayAbbrevRe.exec(string.substring(i)); - return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseWeekday(date, string, i) { - d3_time_dayRe.lastIndex = 0; - var n = d3_time_dayRe.exec(string.substring(i)); - return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonthAbbrev(date, string, i) { - d3_time_monthAbbrevRe.lastIndex = 0; - var n = d3_time_monthAbbrevRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonth(date, string, i) { - d3_time_monthRe.lastIndex = 0; - var n = d3_time_monthRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseLocaleFull(date, string, i) { - return d3_time_parse(date, d3_time_formats.c.toString(), string, i); - } - function d3_time_parseLocaleDate(date, string, i) { - return d3_time_parse(date, d3_time_formats.x.toString(), string, i); - } - function d3_time_parseLocaleTime(date, string, i) { - return d3_time_parse(date, d3_time_formats.X.toString(), string, i); - } - function d3_time_parseAmPm(date, string, i) { - var n = d3_time_periodLookup.get(string.substring(i, i += 2).toLowerCase()); - return n == null ? -1 : (date.p = n, i); - } - return d3_time_format; - } - var d3_time_formatPads = { - "-": "", - _: " ", - "0": "0" - }, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/; - function d3_time_formatPad(value, fill, width) { - var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; - return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); - } - function d3_time_formatRe(names) { - return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); - } - function d3_time_formatLookup(names) { - var map = new d3_Map(), i = -1, n = names.length; - while (++i < n) map.set(names[i].toLowerCase(), i); - return map; - } - function d3_time_parseWeekdayNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 1)); - return n ? (date.w = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberSunday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i)); - return n ? (date.U = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberMonday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i)); - return n ? (date.W = +n[0], i + n[0].length) : -1; - } - function d3_time_parseFullYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 4)); - return n ? (date.y = +n[0], i + n[0].length) : -1; - } - function d3_time_parseYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; - } - function d3_time_parseZone(date, string, i) { - return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5)) ? (date.Z = +string, - i + 5) : -1; - } - function d3_time_expandYear(d) { - return d + (d > 68 ? 1900 : 2e3); - } - function d3_time_parseMonthNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.m = n[0] - 1, i + n[0].length) : -1; - } - function d3_time_parseDay(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.d = +n[0], i + n[0].length) : -1; - } - function d3_time_parseDayOfYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 3)); - return n ? (date.j = +n[0], i + n[0].length) : -1; - } - function d3_time_parseHour24(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.H = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMinutes(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.M = +n[0], i + n[0].length) : -1; - } - function d3_time_parseSeconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.S = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMilliseconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 3)); - return n ? (date.L = +n[0], i + n[0].length) : -1; - } - function d3_time_zone(d) { - var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(abs(z) / 60), zm = abs(z) % 60; - return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); - } - function d3_time_parseLiteralPercent(date, string, i) { - d3_time_percentRe.lastIndex = 0; - var n = d3_time_percentRe.exec(string.substring(i, i + 1)); - return n ? i + n[0].length : -1; - } - function d3_time_formatMulti(formats) { - var n = formats.length, i = -1; - while (++i < n) formats[i][0] = this(formats[i][0]); - return function(date) { - var i = 0, f = formats[i]; - while (!f[1](date)) f = formats[++i]; - return f[0](date); - }; - } - d3.locale = function(locale) { - return { - numberFormat: d3_locale_numberFormat(locale), - timeFormat: d3_locale_timeFormat(locale) - }; - }; - var d3_locale_enUS = d3.locale({ - decimal: ".", - thousands: ",", - grouping: [ 3 ], - currency: [ "$", "" ], - dateTime: "%a %b %e %X %Y", - date: "%m/%d/%Y", - time: "%H:%M:%S", - periods: [ "AM", "PM" ], - days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], - shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], - months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], - shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] - }); - d3.format = d3_locale_enUS.numberFormat; - d3.geo = {}; - function d3_adder() {} - d3_adder.prototype = { - s: 0, - t: 0, - add: function(y) { - d3_adderSum(y, this.t, d3_adderTemp); - d3_adderSum(d3_adderTemp.s, this.s, this); - if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; - }, - reset: function() { - this.s = this.t = 0; - }, - valueOf: function() { - return this.s; - } - }; - var d3_adderTemp = new d3_adder(); - function d3_adderSum(a, b, o) { - var x = o.s = a + b, bv = x - a, av = x - bv; - o.t = a - av + (b - bv); - } - d3.geo.stream = function(object, listener) { - if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { - d3_geo_streamObjectType[object.type](object, listener); - } else { - d3_geo_streamGeometry(object, listener); - } - }; - function d3_geo_streamGeometry(geometry, listener) { - if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { - d3_geo_streamGeometryType[geometry.type](geometry, listener); - } - } - var d3_geo_streamObjectType = { - Feature: function(feature, listener) { - d3_geo_streamGeometry(feature.geometry, listener); - }, - FeatureCollection: function(object, listener) { - var features = object.features, i = -1, n = features.length; - while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); - } - }; - var d3_geo_streamGeometryType = { - Sphere: function(object, listener) { - listener.sphere(); - }, - Point: function(object, listener) { - object = object.coordinates; - listener.point(object[0], object[1], object[2]); - }, - MultiPoint: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); - }, - LineString: function(object, listener) { - d3_geo_streamLine(object.coordinates, listener, 0); - }, - MultiLineString: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); - }, - Polygon: function(object, listener) { - d3_geo_streamPolygon(object.coordinates, listener); - }, - MultiPolygon: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); - }, - GeometryCollection: function(object, listener) { - var geometries = object.geometries, i = -1, n = geometries.length; - while (++i < n) d3_geo_streamGeometry(geometries[i], listener); - } - }; - function d3_geo_streamLine(coordinates, listener, closed) { - var i = -1, n = coordinates.length - closed, coordinate; - listener.lineStart(); - while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); - listener.lineEnd(); - } - function d3_geo_streamPolygon(coordinates, listener) { - var i = -1, n = coordinates.length; - listener.polygonStart(); - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); - listener.polygonEnd(); - } - d3.geo.area = function(object) { - d3_geo_areaSum = 0; - d3.geo.stream(object, d3_geo_area); - return d3_geo_areaSum; - }; - var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); - var d3_geo_area = { - sphere: function() { - d3_geo_areaSum += 4 * π; - }, - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_areaRingSum.reset(); - d3_geo_area.lineStart = d3_geo_areaRingStart; - }, - polygonEnd: function() { - var area = 2 * d3_geo_areaRingSum; - d3_geo_areaSum += area < 0 ? 4 * π + area : area; - d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; - } - }; - function d3_geo_areaRingStart() { - var λ00, φ00, λ0, cosφ0, sinφ0; - d3_geo_area.point = function(λ, φ) { - d3_geo_area.point = nextPoint; - λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), - sinφ0 = Math.sin(φ); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - φ = φ * d3_radians / 2 + π / 4; - var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ); - d3_geo_areaRingSum.add(Math.atan2(v, u)); - λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; - } - d3_geo_area.lineEnd = function() { - nextPoint(λ00, φ00); - }; - } - function d3_geo_cartesian(spherical) { - var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); - return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; - } - function d3_geo_cartesianDot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - } - function d3_geo_cartesianCross(a, b) { - return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; - } - function d3_geo_cartesianAdd(a, b) { - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; - } - function d3_geo_cartesianScale(vector, k) { - return [ vector[0] * k, vector[1] * k, vector[2] * k ]; - } - function d3_geo_cartesianNormalize(d) { - var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); - d[0] /= l; - d[1] /= l; - d[2] /= l; - } - function d3_geo_spherical(cartesian) { - return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; - } - function d3_geo_sphericalEqual(a, b) { - return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε; - } - d3.geo.bounds = function() { - var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; - var bound = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - bound.point = ringPoint; - bound.lineStart = ringStart; - bound.lineEnd = ringEnd; - dλSum = 0; - d3_geo_area.polygonStart(); - }, - polygonEnd: function() { - d3_geo_area.polygonEnd(); - bound.point = point; - bound.lineStart = lineStart; - bound.lineEnd = lineEnd; - if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; - range[0] = λ0, range[1] = λ1; - } - }; - function point(λ, φ) { - ranges.push(range = [ λ0 = λ, λ1 = λ ]); - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - function linePoint(λ, φ) { - var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); - if (p0) { - var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); - d3_geo_cartesianNormalize(inflection); - inflection = d3_geo_spherical(inflection); - var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180; - if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = inflection[1] * d3_degrees; - if (φi > φ1) φ1 = φi; - } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = -inflection[1] * d3_degrees; - if (φi < φ0) φ0 = φi; - } else { - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - if (antimeridian) { - if (λ < λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } else { - if (λ1 >= λ0) { - if (λ < λ0) λ0 = λ; - if (λ > λ1) λ1 = λ; - } else { - if (λ > λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } - } - } else { - point(λ, φ); - } - p0 = p, λ_ = λ; - } - function lineStart() { - bound.point = linePoint; - } - function lineEnd() { - range[0] = λ0, range[1] = λ1; - bound.point = point; - p0 = null; - } - function ringPoint(λ, φ) { - if (p0) { - var dλ = λ - λ_; - dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; - } else λ__ = λ, φ__ = φ; - d3_geo_area.point(λ, φ); - linePoint(λ, φ); - } - function ringStart() { - d3_geo_area.lineStart(); - } - function ringEnd() { - ringPoint(λ__, φ__); - d3_geo_area.lineEnd(); - if (abs(dλSum) > ε) λ0 = -(λ1 = 180); - range[0] = λ0, range[1] = λ1; - p0 = null; - } - function angle(λ0, λ1) { - return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; - } - function compareRanges(a, b) { - return a[0] - b[0]; - } - function withinRange(x, range) { - return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; - } - return function(feature) { - φ1 = λ1 = -(λ0 = φ0 = Infinity); - ranges = []; - d3.geo.stream(feature, bound); - var n = ranges.length; - if (n) { - ranges.sort(compareRanges); - for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { - b = ranges[i]; - if (withinRange(b[0], a) || withinRange(b[1], a)) { - if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; - if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; - } else { - merged.push(a = b); - } - } - var best = -Infinity, dλ; - for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { - b = merged[i]; - if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; - } - } - ranges = range = null; - return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; - }; - }(); - d3.geo.centroid = function(object) { - d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, d3_geo_centroid); - var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; - if (m < ε2) { - x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; - if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; - m = x * x + y * y + z * z; - if (m < ε2) return [ NaN, NaN ]; - } - return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; - }; - var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; - var d3_geo_centroid = { - sphere: d3_noop, - point: d3_geo_centroidPoint, - lineStart: d3_geo_centroidLineStart, - lineEnd: d3_geo_centroidLineEnd, - polygonStart: function() { - d3_geo_centroid.lineStart = d3_geo_centroidRingStart; - }, - polygonEnd: function() { - d3_geo_centroid.lineStart = d3_geo_centroidLineStart; - } - }; - function d3_geo_centroidPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); - } - function d3_geo_centroidPointXYZ(x, y, z) { - ++d3_geo_centroidW0; - d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; - d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; - d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; - } - function d3_geo_centroidLineStart() { - var x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroid.point = nextPoint; - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_geo_centroidLineEnd() { - d3_geo_centroid.point = d3_geo_centroidPoint; - } - function d3_geo_centroidRingStart() { - var λ00, φ00, x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ00 = λ, φ00 = φ; - d3_geo_centroid.point = nextPoint; - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - d3_geo_centroid.lineEnd = function() { - nextPoint(λ00, φ00); - d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; - d3_geo_centroid.point = d3_geo_centroidPoint; - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); - d3_geo_centroidX2 += v * cx; - d3_geo_centroidY2 += v * cy; - d3_geo_centroidZ2 += v * cz; - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_true() { - return true; - } - function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) { - var subject = [], clip = []; - segments.forEach(function(segment) { - if ((n = segment.length - 1) <= 0) return; - var n, p0 = segment[0], p1 = segment[n]; - if (d3_geo_sphericalEqual(p0, p1)) { - listener.lineStart(); - for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); - listener.lineEnd(); - return; - } - var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false); - a.o = b; - subject.push(a); - clip.push(b); - a = new d3_geo_clipPolygonIntersection(p1, segment, null, false); - b = new d3_geo_clipPolygonIntersection(p1, null, a, true); - a.o = b; - subject.push(a); - clip.push(b); - }); - clip.sort(compare); - d3_geo_clipPolygonLinkCircular(subject); - d3_geo_clipPolygonLinkCircular(clip); - if (!subject.length) return; - for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) { - clip[i].e = entry = !entry; - } - var start = subject[0], points, point; - while (1) { - var current = start, isSubject = true; - while (current.v) if ((current = current.n) === start) return; - points = current.z; - listener.lineStart(); - do { - current.v = current.o.v = true; - if (current.e) { - if (isSubject) { - for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.n.x, 1, listener); - } - current = current.n; - } else { - if (isSubject) { - points = current.p.z; - for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.p.x, -1, listener); - } - current = current.p; - } - current = current.o; - points = current.z; - isSubject = !isSubject; - } while (!current.v); - listener.lineEnd(); - } - } - function d3_geo_clipPolygonLinkCircular(array) { - if (!(n = array.length)) return; - var n, i = 0, a = array[0], b; - while (++i < n) { - a.n = b = array[i]; - b.p = a; - a = b; - } - a.n = b = array[0]; - b.p = a; - } - function d3_geo_clipPolygonIntersection(point, points, other, entry) { - this.x = point; - this.z = points; - this.o = other; - this.e = entry; - this.v = false; - this.n = this.p = null; - } - function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { - return function(rotate, listener) { - var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]); - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - clip.point = pointRing; - clip.lineStart = ringStart; - clip.lineEnd = ringEnd; - segments = []; - polygon = []; - listener.polygonStart(); - }, - polygonEnd: function() { - clip.point = point; - clip.lineStart = lineStart; - clip.lineEnd = lineEnd; - segments = d3.merge(segments); - var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); - if (segments.length) { - d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); - } else if (clipStartInside) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - listener.polygonEnd(); - segments = polygon = null; - }, - sphere: function() { - listener.polygonStart(); - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - listener.polygonEnd(); - } - }; - function point(λ, φ) { - var point = rotate(λ, φ); - if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ); - } - function pointLine(λ, φ) { - var point = rotate(λ, φ); - line.point(point[0], point[1]); - } - function lineStart() { - clip.point = pointLine; - line.lineStart(); - } - function lineEnd() { - clip.point = point; - line.lineEnd(); - } - var segments; - var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygon, ring; - function pointRing(λ, φ) { - ring.push([ λ, φ ]); - var point = rotate(λ, φ); - ringListener.point(point[0], point[1]); - } - function ringStart() { - ringListener.lineStart(); - ring = []; - } - function ringEnd() { - pointRing(ring[0][0], ring[0][1]); - ringListener.lineEnd(); - var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; - ring.pop(); - polygon.push(ring); - ring = null; - if (!n) return; - if (clean & 1) { - segment = ringSegments[0]; - var n = segment.length - 1, i = -1, point; - listener.lineStart(); - while (++i < n) listener.point((point = segment[i])[0], point[1]); - listener.lineEnd(); - return; - } - if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); - segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); - } - return clip; - }; - } - function d3_geo_clipSegmentLength1(segment) { - return segment.length > 1; - } - function d3_geo_clipBufferListener() { - var lines = [], line; - return { - lineStart: function() { - lines.push(line = []); - }, - point: function(λ, φ) { - line.push([ λ, φ ]); - }, - lineEnd: d3_noop, - buffer: function() { - var buffer = lines; - lines = []; - line = null; - return buffer; - }, - rejoin: function() { - if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); - } - }; - } - function d3_geo_clipSort(a, b) { - return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]); - } - function d3_geo_pointInPolygon(point, polygon) { - var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; - d3_geo_areaRingSum.reset(); - for (var i = 0, n = polygon.length; i < n; ++i) { - var ring = polygon[i], m = ring.length; - if (!m) continue; - var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; - while (true) { - if (j === m) j = 0; - point = ring[j]; - var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ; - d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ))); - polarAngle += antimeridian ? dλ + sdλ * τ : dλ; - if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { - var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); - d3_geo_cartesianNormalize(arc); - var intersection = d3_geo_cartesianCross(meridianNormal, arc); - d3_geo_cartesianNormalize(intersection); - var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); - if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) { - winding += antimeridian ^ dλ >= 0 ? 1 : -1; - } - } - if (!j++) break; - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; - } - } - return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; - } - var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]); - function d3_geo_clipAntimeridianLine(listener) { - var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; - return { - lineStart: function() { - listener.lineStart(); - clean = 1; - }, - point: function(λ1, φ1) { - var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0); - if (abs(dλ - π) < ε) { - listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - listener.point(λ1, φ0); - clean = 0; - } else if (sλ0 !== sλ1 && dλ >= π) { - if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; - if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; - φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - clean = 0; - } - listener.point(λ0 = λ1, φ0 = φ1); - sλ0 = sλ1; - }, - lineEnd: function() { - listener.lineEnd(); - λ0 = φ0 = NaN; - }, - clean: function() { - return 2 - clean; - } - }; - } - function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { - var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); - return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; - } - function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { - var φ; - if (from == null) { - φ = direction * halfπ; - listener.point(-π, φ); - listener.point(0, φ); - listener.point(π, φ); - listener.point(π, 0); - listener.point(π, -φ); - listener.point(0, -φ); - listener.point(-π, -φ); - listener.point(-π, 0); - listener.point(-π, φ); - } else if (abs(from[0] - to[0]) > ε) { - var s = from[0] < to[0] ? π : -π; - φ = direction * s / 2; - listener.point(-s, φ); - listener.point(0, φ); - listener.point(s, φ); - } else { - listener.point(to[0], to[1]); - } - } - function d3_geo_clipCircle(radius) { - var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); - return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]); - function visible(λ, φ) { - return Math.cos(λ) * Math.cos(φ) > cr; - } - function clipLine(listener) { - var point0, c0, v0, v00, clean; - return { - lineStart: function() { - v00 = v0 = false; - clean = 1; - }, - point: function(λ, φ) { - var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; - if (!point0 && (v00 = v0 = v)) listener.lineStart(); - if (v !== v0) { - point2 = intersect(point0, point1); - if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { - point1[0] += ε; - point1[1] += ε; - v = visible(point1[0], point1[1]); - } - } - if (v !== v0) { - clean = 0; - if (v) { - listener.lineStart(); - point2 = intersect(point1, point0); - listener.point(point2[0], point2[1]); - } else { - point2 = intersect(point0, point1); - listener.point(point2[0], point2[1]); - listener.lineEnd(); - } - point0 = point2; - } else if (notHemisphere && point0 && smallRadius ^ v) { - var t; - if (!(c & c0) && (t = intersect(point1, point0, true))) { - clean = 0; - if (smallRadius) { - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - } else { - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - } - } - } - if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { - listener.point(point1[0], point1[1]); - } - point0 = point1, v0 = v, c0 = c; - }, - lineEnd: function() { - if (v0) listener.lineEnd(); - point0 = null; - }, - clean: function() { - return clean | (v00 && v0) << 1; - } - }; - } - function intersect(a, b, two) { - var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); - var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; - if (!determinant) return !two && a; - var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); - d3_geo_cartesianAdd(A, B); - var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); - if (t2 < 0) return; - var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); - d3_geo_cartesianAdd(q, A); - q = d3_geo_spherical(q); - if (!two) return q; - var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; - if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; - var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε; - if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; - if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { - var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); - d3_geo_cartesianAdd(q1, A); - return [ q, d3_geo_spherical(q1) ]; - } - } - function code(λ, φ) { - var r = smallRadius ? radius : π - radius, code = 0; - if (λ < -r) code |= 1; else if (λ > r) code |= 2; - if (φ < -r) code |= 4; else if (φ > r) code |= 8; - return code; - } - } - function d3_geom_clipLine(x0, y0, x1, y1) { - return function(line) { - var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; - r = x0 - ax; - if (!dx && r > 0) return; - r /= dx; - if (dx < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dx > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = x1 - ax; - if (!dx && r < 0) return; - r /= dx; - if (dx < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dx > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - r = y0 - ay; - if (!dy && r > 0) return; - r /= dy; - if (dy < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dy > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = y1 - ay; - if (!dy && r < 0) return; - r /= dy; - if (dy < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dy > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - if (t0 > 0) line.a = { - x: ax + t0 * dx, - y: ay + t0 * dy - }; - if (t1 < 1) line.b = { - x: ax + t1 * dx, - y: ay + t1 * dy - }; - return line; - }; - } - var d3_geo_clipExtentMAX = 1e9; - d3.geo.clipExtent = function() { - var x0, y0, x1, y1, stream, clip, clipExtent = { - stream: function(output) { - if (stream) stream.valid = false; - stream = clip(output); - stream.valid = true; - return stream; - }, - extent: function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); - if (stream) stream.valid = false, stream = null; - return clipExtent; - } - }; - return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); - }; - function d3_geo_clipExtent(x0, y0, x1, y1) { - return function(listener) { - var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring; - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - listener = bufferListener; - segments = []; - polygon = []; - clean = true; - }, - polygonEnd: function() { - listener = listener_; - segments = d3.merge(segments); - var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length; - if (inside || visible) { - listener.polygonStart(); - if (inside) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - if (visible) { - d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener); - } - listener.polygonEnd(); - } - segments = polygon = ring = null; - } - }; - function insidePolygon(p) { - var wn = 0, n = polygon.length, y = p[1]; - for (var i = 0; i < n; ++i) { - for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { - b = v[j]; - if (a[1] <= y) { - if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn; - } else { - if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn; - } - a = b; - } - } - return wn !== 0; - } - function interpolate(from, to, direction, listener) { - var a = 0, a1 = 0; - if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { - do { - listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); - } while ((a = (a + direction + 4) % 4) !== a1); - } else { - listener.point(to[0], to[1]); - } - } - function pointVisible(x, y) { - return x0 <= x && x <= x1 && y0 <= y && y <= y1; - } - function point(x, y) { - if (pointVisible(x, y)) listener.point(x, y); - } - var x__, y__, v__, x_, y_, v_, first, clean; - function lineStart() { - clip.point = linePoint; - if (polygon) polygon.push(ring = []); - first = true; - v_ = false; - x_ = y_ = NaN; - } - function lineEnd() { - if (segments) { - linePoint(x__, y__); - if (v__ && v_) bufferListener.rejoin(); - segments.push(bufferListener.buffer()); - } - clip.point = point; - if (v_) listener.lineEnd(); - } - function linePoint(x, y) { - x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); - y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); - var v = pointVisible(x, y); - if (polygon) ring.push([ x, y ]); - if (first) { - x__ = x, y__ = y, v__ = v; - first = false; - if (v) { - listener.lineStart(); - listener.point(x, y); - } - } else { - if (v && v_) listener.point(x, y); else { - var l = { - a: { - x: x_, - y: y_ - }, - b: { - x: x, - y: y - } - }; - if (clipLine(l)) { - if (!v_) { - listener.lineStart(); - listener.point(l.a.x, l.a.y); - } - listener.point(l.b.x, l.b.y); - if (!v) listener.lineEnd(); - clean = false; - } else if (v) { - listener.lineStart(); - listener.point(x, y); - clean = false; - } - } - } - x_ = x, y_ = y, v_ = v; - } - return clip; - }; - function corner(p, direction) { - return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; - } - function compare(a, b) { - return comparePoints(a.x, b.x); - } - function comparePoints(a, b) { - var ca = corner(a, 1), cb = corner(b, 1); - return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; - } - } - function d3_geo_compose(a, b) { - function compose(x, y) { - return x = a(x, y), b(x[0], x[1]); - } - if (a.invert && b.invert) compose.invert = function(x, y) { - return x = b.invert(x, y), x && a.invert(x[0], x[1]); - }; - return compose; - } - function d3_geo_conic(projectAt) { - var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); - p.parallels = function(_) { - if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ]; - return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); - }; - return p; - } - function d3_geo_conicEqualArea(φ0, φ1) { - var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; - function forward(λ, φ) { - var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; - return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = ρ0 - y; - return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; - }; - return forward; - } - (d3.geo.conicEqualArea = function() { - return d3_geo_conic(d3_geo_conicEqualArea); - }).raw = d3_geo_conicEqualArea; - d3.geo.albers = function() { - return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); - }; - d3.geo.albersUsa = function() { - var lower48 = d3.geo.albers(); - var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); - var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); - var point, pointStream = { - point: function(x, y) { - point = [ x, y ]; - } - }, lower48Point, alaskaPoint, hawaiiPoint; - function albersUsa(coordinates) { - var x = coordinates[0], y = coordinates[1]; - point = null; - (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); - return point; - } - albersUsa.invert = function(coordinates) { - var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; - return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); - }; - albersUsa.stream = function(stream) { - var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); - return { - point: function(x, y) { - lower48Stream.point(x, y); - alaskaStream.point(x, y); - hawaiiStream.point(x, y); - }, - sphere: function() { - lower48Stream.sphere(); - alaskaStream.sphere(); - hawaiiStream.sphere(); - }, - lineStart: function() { - lower48Stream.lineStart(); - alaskaStream.lineStart(); - hawaiiStream.lineStart(); - }, - lineEnd: function() { - lower48Stream.lineEnd(); - alaskaStream.lineEnd(); - hawaiiStream.lineEnd(); - }, - polygonStart: function() { - lower48Stream.polygonStart(); - alaskaStream.polygonStart(); - hawaiiStream.polygonStart(); - }, - polygonEnd: function() { - lower48Stream.polygonEnd(); - alaskaStream.polygonEnd(); - hawaiiStream.polygonEnd(); - } - }; - }; - albersUsa.precision = function(_) { - if (!arguments.length) return lower48.precision(); - lower48.precision(_); - alaska.precision(_); - hawaii.precision(_); - return albersUsa; - }; - albersUsa.scale = function(_) { - if (!arguments.length) return lower48.scale(); - lower48.scale(_); - alaska.scale(_ * .35); - hawaii.scale(_); - return albersUsa.translate(lower48.translate()); - }; - albersUsa.translate = function(_) { - if (!arguments.length) return lower48.translate(); - var k = lower48.scale(), x = +_[0], y = +_[1]; - lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; - alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - return albersUsa; - }; - return albersUsa.scale(1070); - }; - var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_pathAreaPolygon = 0; - d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; - }, - polygonEnd: function() { - d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; - d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2); - } - }; - function d3_geo_pathAreaRingStart() { - var x00, y00, x0, y0; - d3_geo_pathArea.point = function(x, y) { - d3_geo_pathArea.point = nextPoint; - x00 = x0 = x, y00 = y0 = y; - }; - function nextPoint(x, y) { - d3_geo_pathAreaPolygon += y0 * x - x0 * y; - x0 = x, y0 = y; - } - d3_geo_pathArea.lineEnd = function() { - nextPoint(x00, y00); - }; - } - var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; - var d3_geo_pathBounds = { - point: d3_geo_pathBoundsPoint, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_pathBoundsPoint(x, y) { - if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; - if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; - if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; - if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; - } - function d3_geo_pathBuffer() { - var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointCircle = d3_geo_pathBufferCircle(_); - return stream; - }, - result: function() { - if (buffer.length) { - var result = buffer.join(""); - buffer = []; - return result; - } - } - }; - function point(x, y) { - buffer.push("M", x, ",", y, pointCircle); - } - function pointLineStart(x, y) { - buffer.push("M", x, ",", y); - stream.point = pointLine; - } - function pointLine(x, y) { - buffer.push("L", x, ",", y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - buffer.push("Z"); - } - return stream; - } - function d3_geo_pathBufferCircle(radius) { - return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; - } - var d3_geo_pathCentroid = { - point: d3_geo_pathCentroidPoint, - lineStart: d3_geo_pathCentroidLineStart, - lineEnd: d3_geo_pathCentroidLineEnd, - polygonStart: function() { - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; - }, - polygonEnd: function() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; - d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; - } - }; - function d3_geo_pathCentroidPoint(x, y) { - d3_geo_centroidX0 += x; - d3_geo_centroidY0 += y; - ++d3_geo_centroidZ0; - } - function d3_geo_pathCentroidLineStart() { - var x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - } - function d3_geo_pathCentroidLineEnd() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - } - function d3_geo_pathCentroidRingStart() { - var x00, y00, x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - z = y0 * x - x0 * y; - d3_geo_centroidX2 += z * (x0 + x); - d3_geo_centroidY2 += z * (y0 + y); - d3_geo_centroidZ2 += z * 3; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - d3_geo_pathCentroid.lineEnd = function() { - nextPoint(x00, y00); - }; - } - function d3_geo_pathContext(context) { - var pointRadius = 4.5; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointRadius = _; - return stream; - }, - result: d3_noop - }; - function point(x, y) { - context.moveTo(x, y); - context.arc(x, y, pointRadius, 0, τ); - } - function pointLineStart(x, y) { - context.moveTo(x, y); - stream.point = pointLine; - } - function pointLine(x, y) { - context.lineTo(x, y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - context.closePath(); - } - return stream; - } - function d3_geo_resample(project) { - var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; - function resample(stream) { - return (maxDepth ? resampleRecursive : resampleNone)(stream); - } - function resampleNone(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - }); - } - function resampleRecursive(stream) { - var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; - var resample = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - stream.polygonStart(); - resample.lineStart = ringStart; - }, - polygonEnd: function() { - stream.polygonEnd(); - resample.lineStart = lineStart; - } - }; - function point(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - } - function lineStart() { - x0 = NaN; - resample.point = linePoint; - stream.lineStart(); - } - function linePoint(λ, φ) { - var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); - resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); - stream.point(x0, y0); - } - function lineEnd() { - resample.point = point; - stream.lineEnd(); - } - function ringStart() { - lineStart(); - resample.point = ringPoint; - resample.lineEnd = ringEnd; - } - function ringPoint(λ, φ) { - linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; - resample.point = linePoint; - } - function ringEnd() { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); - resample.lineEnd = lineEnd; - lineEnd(); - } - return resample; - } - function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { - var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; - if (d2 > 4 * δ2 && depth--) { - var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; - if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); - stream.point(x2, y2); - resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); - } - } - } - resample.precision = function(_) { - if (!arguments.length) return Math.sqrt(δ2); - maxDepth = (δ2 = _ * _) > 0 && 16; - return resample; - }; - return resample; - } - d3.geo.path = function() { - var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; - function path(object) { - if (object) { - if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); - if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); - d3.geo.stream(object, cacheStream); - } - return contextStream.result(); - } - path.area = function(object) { - d3_geo_pathAreaSum = 0; - d3.geo.stream(object, projectStream(d3_geo_pathArea)); - return d3_geo_pathAreaSum; - }; - path.centroid = function(object) { - d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); - return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; - }; - path.bounds = function(object) { - d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); - d3.geo.stream(object, projectStream(d3_geo_pathBounds)); - return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; - }; - path.projection = function(_) { - if (!arguments.length) return projection; - projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; - return reset(); - }; - path.context = function(_) { - if (!arguments.length) return context; - contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); - if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); - return reset(); - }; - path.pointRadius = function(_) { - if (!arguments.length) return pointRadius; - pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); - return path; - }; - function reset() { - cacheStream = null; - return path; - } - return path.projection(d3.geo.albersUsa()).context(null); - }; - function d3_geo_pathProjectStream(project) { - var resample = d3_geo_resample(function(x, y) { - return project([ x * d3_degrees, y * d3_degrees ]); - }); - return function(stream) { - return d3_geo_projectionRadians(resample(stream)); - }; - } - d3.geo.transform = function(methods) { - return { - stream: function(stream) { - var transform = new d3_geo_transform(stream); - for (var k in methods) transform[k] = methods[k]; - return transform; - } - }; - }; - function d3_geo_transform(stream) { - this.stream = stream; - } - d3_geo_transform.prototype = { - point: function(x, y) { - this.stream.point(x, y); - }, - sphere: function() { - this.stream.sphere(); - }, - lineStart: function() { - this.stream.lineStart(); - }, - lineEnd: function() { - this.stream.lineEnd(); - }, - polygonStart: function() { - this.stream.polygonStart(); - }, - polygonEnd: function() { - this.stream.polygonEnd(); - } - }; - function d3_geo_transformPoint(stream, point) { - return { - point: point, - sphere: function() { - stream.sphere(); - }, - lineStart: function() { - stream.lineStart(); - }, - lineEnd: function() { - stream.lineEnd(); - }, - polygonStart: function() { - stream.polygonStart(); - }, - polygonEnd: function() { - stream.polygonEnd(); - } - }; - } - d3.geo.projection = d3_geo_projection; - d3.geo.projectionMutator = d3_geo_projectionMutator; - function d3_geo_projection(project) { - return d3_geo_projectionMutator(function() { - return project; - })(); - } - function d3_geo_projectionMutator(projectAt) { - var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { - x = project(x, y); - return [ x[0] * k + δx, δy - x[1] * k ]; - }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; - function projection(point) { - point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); - return [ point[0] * k + δx, δy - point[1] * k ]; - } - function invert(point) { - point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); - return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; - } - projection.stream = function(output) { - if (stream) stream.valid = false; - stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output)))); - stream.valid = true; - return stream; - }; - projection.clipAngle = function(_) { - if (!arguments.length) return clipAngle; - preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); - return invalidate(); - }; - projection.clipExtent = function(_) { - if (!arguments.length) return clipExtent; - clipExtent = _; - postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; - return invalidate(); - }; - projection.scale = function(_) { - if (!arguments.length) return k; - k = +_; - return reset(); - }; - projection.translate = function(_) { - if (!arguments.length) return [ x, y ]; - x = +_[0]; - y = +_[1]; - return reset(); - }; - projection.center = function(_) { - if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; - λ = _[0] % 360 * d3_radians; - φ = _[1] % 360 * d3_radians; - return reset(); - }; - projection.rotate = function(_) { - if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; - δλ = _[0] % 360 * d3_radians; - δφ = _[1] % 360 * d3_radians; - δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; - return reset(); - }; - d3.rebind(projection, projectResample, "precision"); - function reset() { - projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); - var center = project(λ, φ); - δx = x - center[0] * k; - δy = y + center[1] * k; - return invalidate(); - } - function invalidate() { - if (stream) stream.valid = false, stream = null; - return projection; - } - return function() { - project = projectAt.apply(this, arguments); - projection.invert = project.invert && invert; - return reset(); - }; - } - function d3_geo_projectionRadians(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - stream.point(x * d3_radians, y * d3_radians); - }); - } - function d3_geo_equirectangular(λ, φ) { - return [ λ, φ ]; - } - (d3.geo.equirectangular = function() { - return d3_geo_projection(d3_geo_equirectangular); - }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; - d3.geo.rotation = function(rotate) { - rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); - function forward(coordinates) { - coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - } - forward.invert = function(coordinates) { - coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - }; - return forward; - }; - function d3_geo_identityRotation(λ, φ) { - return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; - } - d3_geo_identityRotation.invert = d3_geo_equirectangular; - function d3_geo_rotation(δλ, δφ, δγ) { - return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation; - } - function d3_geo_forwardRotationλ(δλ) { - return function(λ, φ) { - return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; - }; - } - function d3_geo_rotationλ(δλ) { - var rotation = d3_geo_forwardRotationλ(δλ); - rotation.invert = d3_geo_forwardRotationλ(-δλ); - return rotation; - } - function d3_geo_rotationφγ(δφ, δγ) { - var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); - function rotation(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; - return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; - } - rotation.invert = function(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; - return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; - }; - return rotation; - } - d3.geo.circle = function() { - var origin = [ 0, 0 ], angle, precision = 6, interpolate; - function circle() { - var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; - interpolate(null, null, 1, { - point: function(x, y) { - ring.push(x = rotate(x, y)); - x[0] *= d3_degrees, x[1] *= d3_degrees; - } - }); - return { - type: "Polygon", - coordinates: [ ring ] - }; - } - circle.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return circle; - }; - circle.angle = function(x) { - if (!arguments.length) return angle; - interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); - return circle; - }; - circle.precision = function(_) { - if (!arguments.length) return precision; - interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); - return circle; - }; - return circle.angle(90); - }; - function d3_geo_circleInterpolate(radius, precision) { - var cr = Math.cos(radius), sr = Math.sin(radius); - return function(from, to, direction, listener) { - var step = direction * precision; - if (from != null) { - from = d3_geo_circleAngle(cr, from); - to = d3_geo_circleAngle(cr, to); - if (direction > 0 ? from < to : from > to) from += direction * τ; - } else { - from = radius + direction * τ; - to = radius - .5 * step; - } - for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { - listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); - } - }; - } - function d3_geo_circleAngle(cr, point) { - var a = d3_geo_cartesian(point); - a[0] -= cr; - d3_geo_cartesianNormalize(a); - var angle = d3_acos(-a[1]); - return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); - } - d3.geo.distance = function(a, b) { - var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; - return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); - }; - d3.geo.graticule = function() { - var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; - function graticule() { - return { - type: "MultiLineString", - coordinates: lines() - }; - } - function lines() { - return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { - return abs(x % DX) > ε; - }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { - return abs(y % DY) > ε; - }).map(y)); - } - graticule.lines = function() { - return lines().map(function(coordinates) { - return { - type: "LineString", - coordinates: coordinates - }; - }); - }; - graticule.outline = function() { - return { - type: "Polygon", - coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] - }; - }; - graticule.extent = function(_) { - if (!arguments.length) return graticule.minorExtent(); - return graticule.majorExtent(_).minorExtent(_); - }; - graticule.majorExtent = function(_) { - if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; - X0 = +_[0][0], X1 = +_[1][0]; - Y0 = +_[0][1], Y1 = +_[1][1]; - if (X0 > X1) _ = X0, X0 = X1, X1 = _; - if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; - return graticule.precision(precision); - }; - graticule.minorExtent = function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - x0 = +_[0][0], x1 = +_[1][0]; - y0 = +_[0][1], y1 = +_[1][1]; - if (x0 > x1) _ = x0, x0 = x1, x1 = _; - if (y0 > y1) _ = y0, y0 = y1, y1 = _; - return graticule.precision(precision); - }; - graticule.step = function(_) { - if (!arguments.length) return graticule.minorStep(); - return graticule.majorStep(_).minorStep(_); - }; - graticule.majorStep = function(_) { - if (!arguments.length) return [ DX, DY ]; - DX = +_[0], DY = +_[1]; - return graticule; - }; - graticule.minorStep = function(_) { - if (!arguments.length) return [ dx, dy ]; - dx = +_[0], dy = +_[1]; - return graticule; - }; - graticule.precision = function(_) { - if (!arguments.length) return precision; - precision = +_; - x = d3_geo_graticuleX(y0, y1, 90); - y = d3_geo_graticuleY(x0, x1, precision); - X = d3_geo_graticuleX(Y0, Y1, 90); - Y = d3_geo_graticuleY(X0, X1, precision); - return graticule; - }; - return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); - }; - function d3_geo_graticuleX(y0, y1, dy) { - var y = d3.range(y0, y1 - ε, dy).concat(y1); - return function(x) { - return y.map(function(y) { - return [ x, y ]; - }); - }; - } - function d3_geo_graticuleY(x0, x1, dx) { - var x = d3.range(x0, x1 - ε, dx).concat(x1); - return function(y) { - return x.map(function(x) { - return [ x, y ]; - }); - }; - } - function d3_source(d) { - return d.source; - } - function d3_target(d) { - return d.target; - } - d3.geo.greatArc = function() { - var source = d3_source, source_, target = d3_target, target_; - function greatArc() { - return { - type: "LineString", - coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] - }; - } - greatArc.distance = function() { - return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); - }; - greatArc.source = function(_) { - if (!arguments.length) return source; - source = _, source_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.target = function(_) { - if (!arguments.length) return target; - target = _, target_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.precision = function() { - return arguments.length ? greatArc : 0; - }; - return greatArc; - }; - d3.geo.interpolate = function(source, target) { - return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); - }; - function d3_geo_interpolate(x0, y0, x1, y1) { - var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); - var interpolate = d ? function(t) { - var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; - return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; - } : function() { - return [ x0 * d3_degrees, y0 * d3_degrees ]; - }; - interpolate.distance = d; - return interpolate; - } - d3.geo.length = function(object) { - d3_geo_lengthSum = 0; - d3.geo.stream(object, d3_geo_length); - return d3_geo_lengthSum; - }; - var d3_geo_lengthSum; - var d3_geo_length = { - sphere: d3_noop, - point: d3_noop, - lineStart: d3_geo_lengthLineStart, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_lengthLineStart() { - var λ0, sinφ0, cosφ0; - d3_geo_length.point = function(λ, φ) { - λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); - d3_geo_length.point = nextPoint; - }; - d3_geo_length.lineEnd = function() { - d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; - }; - function nextPoint(λ, φ) { - var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); - d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; - } - } - function d3_geo_azimuthal(scale, angle) { - function azimuthal(λ, φ) { - var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); - return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; - } - azimuthal.invert = function(x, y) { - var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); - return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; - }; - return azimuthal; - } - var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { - return Math.sqrt(2 / (1 + cosλcosφ)); - }, function(ρ) { - return 2 * Math.asin(ρ / 2); - }); - (d3.geo.azimuthalEqualArea = function() { - return d3_geo_projection(d3_geo_azimuthalEqualArea); - }).raw = d3_geo_azimuthalEqualArea; - var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { - var c = Math.acos(cosλcosφ); - return c && c / Math.sin(c); - }, d3_identity); - (d3.geo.azimuthalEquidistant = function() { - return d3_geo_projection(d3_geo_azimuthalEquidistant); - }).raw = d3_geo_azimuthalEquidistant; - function d3_geo_conicConformal(φ0, φ1) { - var cosφ0 = Math.cos(φ0), t = function(φ) { - return Math.tan(π / 4 + φ / 2); - }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; - if (!n) return d3_geo_mercator; - function forward(λ, φ) { - if (F > 0) { - if (φ < -halfπ + ε) φ = -halfπ + ε; - } else { - if (φ > halfπ - ε) φ = halfπ - ε; - } - var ρ = F / Math.pow(t(φ), n); - return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); - return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ]; - }; - return forward; - } - (d3.geo.conicConformal = function() { - return d3_geo_conic(d3_geo_conicConformal); - }).raw = d3_geo_conicConformal; - function d3_geo_conicEquidistant(φ0, φ1) { - var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; - if (abs(n) < ε) return d3_geo_equirectangular; - function forward(λ, φ) { - var ρ = G - φ; - return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = G - y; - return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ]; - }; - return forward; - } - (d3.geo.conicEquidistant = function() { - return d3_geo_conic(d3_geo_conicEquidistant); - }).raw = d3_geo_conicEquidistant; - var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / cosλcosφ; - }, Math.atan); - (d3.geo.gnomonic = function() { - return d3_geo_projection(d3_geo_gnomonic); - }).raw = d3_geo_gnomonic; - function d3_geo_mercator(λ, φ) { - return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ]; - } - d3_geo_mercator.invert = function(x, y) { - return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ]; - }; - function d3_geo_mercatorProjection(project) { - var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; - m.scale = function() { - var v = scale.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.translate = function() { - var v = translate.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.clipExtent = function(_) { - var v = clipExtent.apply(m, arguments); - if (v === m) { - if (clipAuto = _ == null) { - var k = π * scale(), t = translate(); - clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); - } - } else if (clipAuto) { - v = null; - } - return v; - }; - return m.clipExtent(null); - } - (d3.geo.mercator = function() { - return d3_geo_mercatorProjection(d3_geo_mercator); - }).raw = d3_geo_mercator; - var d3_geo_orthographic = d3_geo_azimuthal(function() { - return 1; - }, Math.asin); - (d3.geo.orthographic = function() { - return d3_geo_projection(d3_geo_orthographic); - }).raw = d3_geo_orthographic; - var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / (1 + cosλcosφ); - }, function(ρ) { - return 2 * Math.atan(ρ); - }); - (d3.geo.stereographic = function() { - return d3_geo_projection(d3_geo_stereographic); - }).raw = d3_geo_stereographic; - function d3_geo_transverseMercator(λ, φ) { - return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ]; - } - d3_geo_transverseMercator.invert = function(x, y) { - return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ]; - }; - (d3.geo.transverseMercator = function() { - var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate; - projection.center = function(_) { - return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ -_[1], _[0] ]); - }; - projection.rotate = function(_) { - return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), - [ _[0], _[1], _[2] - 90 ]); - }; - return projection.rotate([ 0, 0 ]); - }).raw = d3_geo_transverseMercator; - d3.geom = {}; - function d3_geom_pointX(d) { - return d[0]; - } - function d3_geom_pointY(d) { - return d[1]; - } - d3.geom.hull = function(vertices) { - var x = d3_geom_pointX, y = d3_geom_pointY; - if (arguments.length) return hull(vertices); - function hull(data) { - if (data.length < 3) return []; - var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = []; - for (i = 0; i < n; i++) { - points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]); - } - points.sort(d3_geom_hullOrder); - for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]); - var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints); - var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; - for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]); - for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]); - return polygon; - } - hull.x = function(_) { - return arguments.length ? (x = _, hull) : x; - }; - hull.y = function(_) { - return arguments.length ? (y = _, hull) : y; - }; - return hull; - }; - function d3_geom_hullUpper(points) { - var n = points.length, hull = [ 0, 1 ], hs = 2; - for (var i = 2; i < n; i++) { - while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs; - hull[hs++] = i; - } - return hull.slice(0, hs); - } - function d3_geom_hullOrder(a, b) { - return a[0] - b[0] || a[1] - b[1]; - } - d3.geom.polygon = function(coordinates) { - d3_subclass(coordinates, d3_geom_polygonPrototype); - return coordinates; - }; - var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; - d3_geom_polygonPrototype.area = function() { - var i = -1, n = this.length, a, b = this[n - 1], area = 0; - while (++i < n) { - a = b; - b = this[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - return area * .5; - }; - d3_geom_polygonPrototype.centroid = function(k) { - var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; - if (!arguments.length) k = -1 / (6 * this.area()); - while (++i < n) { - a = b; - b = this[i]; - c = a[0] * b[1] - b[0] * a[1]; - x += (a[0] + b[0]) * c; - y += (a[1] + b[1]) * c; - } - return [ x * k, y * k ]; - }; - d3_geom_polygonPrototype.clip = function(subject) { - var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; - while (++i < n) { - input = subject.slice(); - subject.length = 0; - b = this[i]; - c = input[(m = input.length - closed) - 1]; - j = -1; - while (++j < m) { - d = input[j]; - if (d3_geom_polygonInside(d, a, b)) { - if (!d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - subject.push(d); - } else if (d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - c = d; - } - if (closed) subject.push(subject[0]); - a = b; - } - return subject; - }; - function d3_geom_polygonInside(p, a, b) { - return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); - } - function d3_geom_polygonIntersect(c, d, a, b) { - var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); - return [ x1 + ua * x21, y1 + ua * y21 ]; - } - function d3_geom_polygonClosed(coordinates) { - var a = coordinates[0], b = coordinates[coordinates.length - 1]; - return !(a[0] - b[0] || a[1] - b[1]); - } - var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = []; - function d3_geom_voronoiBeach() { - d3_geom_voronoiRedBlackNode(this); - this.edge = this.site = this.circle = null; - } - function d3_geom_voronoiCreateBeach(site) { - var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach(); - beach.site = site; - return beach; - } - function d3_geom_voronoiDetachBeach(beach) { - d3_geom_voronoiDetachCircle(beach); - d3_geom_voronoiBeaches.remove(beach); - d3_geom_voronoiBeachPool.push(beach); - d3_geom_voronoiRedBlackNode(beach); - } - function d3_geom_voronoiRemoveBeach(beach) { - var circle = beach.circle, x = circle.x, y = circle.cy, vertex = { - x: x, - y: y - }, previous = beach.P, next = beach.N, disappearing = [ beach ]; - d3_geom_voronoiDetachBeach(beach); - var lArc = previous; - while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) { - previous = lArc.P; - disappearing.unshift(lArc); - d3_geom_voronoiDetachBeach(lArc); - lArc = previous; - } - disappearing.unshift(lArc); - d3_geom_voronoiDetachCircle(lArc); - var rArc = next; - while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) { - next = rArc.N; - disappearing.push(rArc); - d3_geom_voronoiDetachBeach(rArc); - rArc = next; - } - disappearing.push(rArc); - d3_geom_voronoiDetachCircle(rArc); - var nArcs = disappearing.length, iArc; - for (iArc = 1; iArc < nArcs; ++iArc) { - rArc = disappearing[iArc]; - lArc = disappearing[iArc - 1]; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); - } - lArc = disappearing[0]; - rArc = disappearing[nArcs - 1]; - rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiAddBeach(site) { - var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._; - while (node) { - dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x; - if (dxl > ε) node = node.L; else { - dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix); - if (dxr > ε) { - if (!node.R) { - lArc = node; - break; - } - node = node.R; - } else { - if (dxl > -ε) { - lArc = node.P; - rArc = node; - } else if (dxr > -ε) { - lArc = node; - rArc = node.N; - } else { - lArc = rArc = node; - } - break; - } - } - } - var newArc = d3_geom_voronoiCreateBeach(site); - d3_geom_voronoiBeaches.insert(lArc, newArc); - if (!lArc && !rArc) return; - if (lArc === rArc) { - d3_geom_voronoiDetachCircle(lArc); - rArc = d3_geom_voronoiCreateBeach(lArc.site); - d3_geom_voronoiBeaches.insert(newArc, rArc); - newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - return; - } - if (!rArc) { - newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - return; - } - d3_geom_voronoiDetachCircle(lArc); - d3_geom_voronoiDetachCircle(rArc); - var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = { - x: (cy * hb - by * hc) / d + ax, - y: (bx * hc - cx * hb) / d + ay - }; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex); - newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex); - rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiLeftBreakPoint(arc, directrix) { - var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix; - if (!pby2) return rfocx; - var lArc = arc.P; - if (!lArc) return -Infinity; - site = lArc.site; - var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix; - if (!plby2) return lfocx; - var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2; - if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; - return (rfocx + lfocx) / 2; - } - function d3_geom_voronoiRightBreakPoint(arc, directrix) { - var rArc = arc.N; - if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix); - var site = arc.site; - return site.y === directrix ? site.x : Infinity; - } - function d3_geom_voronoiCell(site) { - this.site = site; - this.edges = []; - } - d3_geom_voronoiCell.prototype.prepare = function() { - var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge; - while (iHalfEdge--) { - edge = halfEdges[iHalfEdge].edge; - if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1); - } - halfEdges.sort(d3_geom_voronoiHalfEdgeOrder); - return halfEdges.length; - }; - function d3_geom_voronoiCloseCells(extent) { - var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end; - while (iCell--) { - cell = cells[iCell]; - if (!cell || !cell.prepare()) continue; - halfEdges = cell.edges; - nHalfEdges = halfEdges.length; - iHalfEdge = 0; - while (iHalfEdge < nHalfEdges) { - end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y; - start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y; - if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) { - halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? { - x: x0, - y: abs(x2 - x0) < ε ? y2 : y1 - } : abs(y3 - y1) < ε && x1 - x3 > ε ? { - x: abs(y2 - y1) < ε ? x2 : x1, - y: y1 - } : abs(x3 - x1) < ε && y3 - y0 > ε ? { - x: x1, - y: abs(x2 - x1) < ε ? y2 : y0 - } : abs(y3 - y0) < ε && x3 - x0 > ε ? { - x: abs(y2 - y0) < ε ? x2 : x0, - y: y0 - } : null), cell.site, null)); - ++nHalfEdges; - } - } - } - } - function d3_geom_voronoiHalfEdgeOrder(a, b) { - return b.angle - a.angle; - } - function d3_geom_voronoiCircle() { - d3_geom_voronoiRedBlackNode(this); - this.x = this.y = this.arc = this.site = this.cy = null; - } - function d3_geom_voronoiAttachCircle(arc) { - var lArc = arc.P, rArc = arc.N; - if (!lArc || !rArc) return; - var lSite = lArc.site, cSite = arc.site, rSite = rArc.site; - if (lSite === rSite) return; - var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by; - var d = 2 * (ax * cy - ay * cx); - if (d >= -ε2) return; - var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by; - var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle(); - circle.arc = arc; - circle.site = cSite; - circle.x = x + bx; - circle.y = cy + Math.sqrt(x * x + y * y); - circle.cy = cy; - arc.circle = circle; - var before = null, node = d3_geom_voronoiCircles._; - while (node) { - if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) { - if (node.L) node = node.L; else { - before = node.P; - break; - } - } else { - if (node.R) node = node.R; else { - before = node; - break; - } - } - } - d3_geom_voronoiCircles.insert(before, circle); - if (!before) d3_geom_voronoiFirstCircle = circle; - } - function d3_geom_voronoiDetachCircle(arc) { - var circle = arc.circle; - if (circle) { - if (!circle.P) d3_geom_voronoiFirstCircle = circle.N; - d3_geom_voronoiCircles.remove(circle); - d3_geom_voronoiCirclePool.push(circle); - d3_geom_voronoiRedBlackNode(circle); - arc.circle = null; - } - } - function d3_geom_voronoiClipEdges(extent) { - var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e; - while (i--) { - e = edges[i]; - if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) { - e.a = e.b = null; - edges.splice(i, 1); - } - } - } - function d3_geom_voronoiConnectEdge(edge, extent) { - var vb = edge.b; - if (vb) return true; - var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb; - if (ry === ly) { - if (fx < x0 || fx >= x1) return; - if (lx > rx) { - if (!va) va = { - x: fx, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: fx, - y: y1 - }; - } else { - if (!va) va = { - x: fx, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: fx, - y: y0 - }; - } - } else { - fm = (lx - rx) / (ry - ly); - fb = fy - fm * fx; - if (fm < -1 || fm > 1) { - if (lx > rx) { - if (!va) va = { - x: (y0 - fb) / fm, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: (y1 - fb) / fm, - y: y1 - }; - } else { - if (!va) va = { - x: (y1 - fb) / fm, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: (y0 - fb) / fm, - y: y0 - }; - } - } else { - if (ly < ry) { - if (!va) va = { - x: x0, - y: fm * x0 + fb - }; else if (va.x >= x1) return; - vb = { - x: x1, - y: fm * x1 + fb - }; - } else { - if (!va) va = { - x: x1, - y: fm * x1 + fb - }; else if (va.x < x0) return; - vb = { - x: x0, - y: fm * x0 + fb - }; - } - } - } - edge.a = va; - edge.b = vb; - return true; - } - function d3_geom_voronoiEdge(lSite, rSite) { - this.l = lSite; - this.r = rSite; - this.a = this.b = null; - } - function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, rSite); - d3_geom_voronoiEdges.push(edge); - if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va); - if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb); - d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite)); - d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite)); - return edge; - } - function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, null); - edge.a = va; - edge.b = vb; - d3_geom_voronoiEdges.push(edge); - return edge; - } - function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) { - if (!edge.a && !edge.b) { - edge.a = vertex; - edge.l = lSite; - edge.r = rSite; - } else if (edge.l === rSite) { - edge.b = vertex; - } else { - edge.a = vertex; - } - } - function d3_geom_voronoiHalfEdge(edge, lSite, rSite) { - var va = edge.a, vb = edge.b; - this.edge = edge; - this.site = lSite; - this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y); - } - d3_geom_voronoiHalfEdge.prototype = { - start: function() { - return this.edge.l === this.site ? this.edge.a : this.edge.b; - }, - end: function() { - return this.edge.l === this.site ? this.edge.b : this.edge.a; - } - }; - function d3_geom_voronoiRedBlackTree() { - this._ = null; - } - function d3_geom_voronoiRedBlackNode(node) { - node.U = node.C = node.L = node.R = node.P = node.N = null; - } - d3_geom_voronoiRedBlackTree.prototype = { - insert: function(after, node) { - var parent, grandpa, uncle; - if (after) { - node.P = after; - node.N = after.N; - if (after.N) after.N.P = node; - after.N = node; - if (after.R) { - after = after.R; - while (after.L) after = after.L; - after.L = node; - } else { - after.R = node; - } - parent = after; - } else if (this._) { - after = d3_geom_voronoiRedBlackFirst(this._); - node.P = null; - node.N = after; - after.P = after.L = node; - parent = after; - } else { - node.P = node.N = null; - this._ = node; - parent = null; - } - node.L = node.R = null; - node.U = parent; - node.C = true; - after = node; - while (parent && parent.C) { - grandpa = parent.U; - if (parent === grandpa.L) { - uncle = grandpa.R; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.R) { - d3_geom_voronoiRedBlackRotateLeft(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateRight(this, grandpa); - } - } else { - uncle = grandpa.L; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.L) { - d3_geom_voronoiRedBlackRotateRight(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, grandpa); - } - } - parent = after.U; - } - this._.C = false; - }, - remove: function(node) { - if (node.N) node.N.P = node.P; - if (node.P) node.P.N = node.N; - node.N = node.P = null; - var parent = node.U, sibling, left = node.L, right = node.R, next, red; - if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right); - if (parent) { - if (parent.L === node) parent.L = next; else parent.R = next; - } else { - this._ = next; - } - if (left && right) { - red = next.C; - next.C = node.C; - next.L = left; - left.U = next; - if (next !== right) { - parent = next.U; - next.U = node.U; - node = next.R; - parent.L = node; - next.R = right; - right.U = next; - } else { - next.U = parent; - parent = next; - node = next.R; - } - } else { - red = node.C; - node = next; - } - if (node) node.U = parent; - if (red) return; - if (node && node.C) { - node.C = false; - return; - } - do { - if (node === this._) break; - if (node === parent.L) { - sibling = parent.R; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - sibling = parent.R; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.R || !sibling.R.C) { - sibling.L.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateRight(this, sibling); - sibling = parent.R; - } - sibling.C = parent.C; - parent.C = sibling.R.C = false; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - node = this._; - break; - } - } else { - sibling = parent.L; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateRight(this, parent); - sibling = parent.L; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.L || !sibling.L.C) { - sibling.R.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, sibling); - sibling = parent.L; - } - sibling.C = parent.C; - parent.C = sibling.L.C = false; - d3_geom_voronoiRedBlackRotateRight(this, parent); - node = this._; - break; - } - } - sibling.C = true; - node = parent; - parent = parent.U; - } while (!node.C); - if (node) node.C = false; - } - }; - function d3_geom_voronoiRedBlackRotateLeft(tree, node) { - var p = node, q = node.R, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.R = q.L; - if (p.R) p.R.U = p; - q.L = p; - } - function d3_geom_voronoiRedBlackRotateRight(tree, node) { - var p = node, q = node.L, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.L = q.R; - if (p.L) p.L.U = p; - q.R = p; - } - function d3_geom_voronoiRedBlackFirst(node) { - while (node.L) node = node.L; - return node; - } - function d3_geom_voronoi(sites, bbox) { - var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle; - d3_geom_voronoiEdges = []; - d3_geom_voronoiCells = new Array(sites.length); - d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree(); - d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree(); - while (true) { - circle = d3_geom_voronoiFirstCircle; - if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) { - if (site.x !== x0 || site.y !== y0) { - d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site); - d3_geom_voronoiAddBeach(site); - x0 = site.x, y0 = site.y; - } - site = sites.pop(); - } else if (circle) { - d3_geom_voronoiRemoveBeach(circle.arc); - } else { - break; - } - } - if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox); - var diagram = { - cells: d3_geom_voronoiCells, - edges: d3_geom_voronoiEdges - }; - d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null; - return diagram; - } - function d3_geom_voronoiVertexOrder(a, b) { - return b.y - a.y || b.x - a.x; - } - d3.geom.voronoi = function(points) { - var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent; - if (points) return voronoi(points); - function voronoi(data) { - var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1]; - d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) { - var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) { - var s = e.start(); - return [ s.x, s.y ]; - }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : []; - polygon.point = data[i]; - }); - return polygons; - } - function sites(data) { - return data.map(function(d, i) { - return { - x: Math.round(fx(d, i) / ε) * ε, - y: Math.round(fy(d, i) / ε) * ε, - i: i - }; - }); - } - voronoi.links = function(data) { - return d3_geom_voronoi(sites(data)).edges.filter(function(edge) { - return edge.l && edge.r; - }).map(function(edge) { - return { - source: data[edge.l.i], - target: data[edge.r.i] - }; - }); - }; - voronoi.triangles = function(data) { - var triangles = []; - d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) { - var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l; - while (++j < m) { - e0 = e1; - s0 = s1; - e1 = edges[j].edge; - s1 = e1.l === site ? e1.r : e1.l; - if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) { - triangles.push([ data[i], data[s0.i], data[s1.i] ]); - } - } - }); - return triangles; - }; - voronoi.x = function(_) { - return arguments.length ? (fx = d3_functor(x = _), voronoi) : x; - }; - voronoi.y = function(_) { - return arguments.length ? (fy = d3_functor(y = _), voronoi) : y; - }; - voronoi.clipExtent = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent; - clipExtent = _ == null ? d3_geom_voronoiClipExtent : _; - return voronoi; - }; - voronoi.size = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1]; - return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); - }; - return voronoi; - }; - var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ]; - function d3_geom_voronoiTriangleArea(a, b, c) { - return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y); - } - d3.geom.delaunay = function(vertices) { - return d3.geom.voronoi().triangles(vertices); - }; - d3.geom.quadtree = function(points, x1, y1, x2, y2) { - var x = d3_geom_pointX, y = d3_geom_pointY, compat; - if (compat = arguments.length) { - x = d3_geom_quadtreeCompatX; - y = d3_geom_quadtreeCompatY; - if (compat === 3) { - y2 = y1; - x2 = x1; - y1 = x1 = 0; - } - return quadtree(points); - } - function quadtree(data) { - var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; - if (x1 != null) { - x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; - } else { - x2_ = y2_ = -(x1_ = y1_ = Infinity); - xs = [], ys = []; - n = data.length; - if (compat) for (i = 0; i < n; ++i) { - d = data[i]; - if (d.x < x1_) x1_ = d.x; - if (d.y < y1_) y1_ = d.y; - if (d.x > x2_) x2_ = d.x; - if (d.y > y2_) y2_ = d.y; - xs.push(d.x); - ys.push(d.y); - } else for (i = 0; i < n; ++i) { - var x_ = +fx(d = data[i], i), y_ = +fy(d, i); - if (x_ < x1_) x1_ = x_; - if (y_ < y1_) y1_ = y_; - if (x_ > x2_) x2_ = x_; - if (y_ > y2_) y2_ = y_; - xs.push(x_); - ys.push(y_); - } - } - var dx = x2_ - x1_, dy = y2_ - y1_; - if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; - function insert(n, d, x, y, x1, y1, x2, y2) { - if (isNaN(x) || isNaN(y)) return; - if (n.leaf) { - var nx = n.x, ny = n.y; - if (nx != null) { - if (abs(nx - x) + abs(ny - y) < .01) { - insertChild(n, d, x, y, x1, y1, x2, y2); - } else { - var nPoint = n.point; - n.x = n.y = n.point = null; - insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } else { - n.x = x, n.y = y, n.point = d; - } - } else { - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } - function insertChild(n, d, x, y, x1, y1, x2, y2) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, right = x >= sx, bottom = y >= sy, i = (bottom << 1) + right; - n.leaf = false; - n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); - if (right) x1 = sx; else x2 = sx; - if (bottom) y1 = sy; else y2 = sy; - insert(n, d, x, y, x1, y1, x2, y2); - } - var root = d3_geom_quadtreeNode(); - root.add = function(d) { - insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); - }; - root.visit = function(f) { - d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); - }; - i = -1; - if (x1 == null) { - while (++i < n) { - insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); - } - --i; - } else data.forEach(root.add); - xs = ys = data = d = null; - return root; - } - quadtree.x = function(_) { - return arguments.length ? (x = _, quadtree) : x; - }; - quadtree.y = function(_) { - return arguments.length ? (y = _, quadtree) : y; - }; - quadtree.extent = function(_) { - if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], - y2 = +_[1][1]; - return quadtree; - }; - quadtree.size = function(_) { - if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; - return quadtree; - }; - return quadtree; - }; - function d3_geom_quadtreeCompatX(d) { - return d.x; - } - function d3_geom_quadtreeCompatY(d) { - return d.y; - } - function d3_geom_quadtreeNode() { - return { - leaf: true, - nodes: [], - point: null, - x: null, - y: null - }; - } - function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { - if (!f(node, x1, y1, x2, y2)) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; - if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); - if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); - if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); - if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); - } - } - d3.interpolateRgb = d3_interpolateRgb; - function d3_interpolateRgb(a, b) { - a = d3.rgb(a); - b = d3.rgb(b); - var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; - return function(t) { - return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); - }; - } - d3.interpolateObject = d3_interpolateObject; - function d3_interpolateObject(a, b) { - var i = {}, c = {}, k; - for (k in a) { - if (k in b) { - i[k] = d3_interpolate(a[k], b[k]); - } else { - c[k] = a[k]; - } - } - for (k in b) { - if (!(k in a)) { - c[k] = b[k]; - } - } - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; - } - d3.interpolateNumber = d3_interpolateNumber; - function d3_interpolateNumber(a, b) { - b -= a = +a; - return function(t) { - return a + b * t; - }; - } - d3.interpolateString = d3_interpolateString; - function d3_interpolateString(a, b) { - var m, i, j, s0 = 0, s1 = 0, s = [], q = [], n, o; - a = a + "", b = b + ""; - d3_interpolate_number.lastIndex = 0; - for (i = 0; m = d3_interpolate_number.exec(b); ++i) { - if (m.index) s.push(b.substring(s0, s1 = m.index)); - q.push({ - i: s.length, - x: m[0] - }); - s.push(null); - s0 = d3_interpolate_number.lastIndex; - } - if (s0 < b.length) s.push(b.substring(s0)); - for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { - o = q[i]; - if (o.x == m[0]) { - if (o.i) { - if (s[o.i + 1] == null) { - s[o.i - 1] += o.x; - s.splice(o.i, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } else { - s[o.i - 1] += o.x + s[o.i + 1]; - s.splice(o.i, 2); - for (j = i + 1; j < n; ++j) q[j].i -= 2; - } - } else { - if (s[o.i + 1] == null) { - s[o.i] = o.x; - } else { - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } - } - q.splice(i, 1); - n--; - i--; - } else { - o.x = d3_interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); - } - } - while (i < n) { - o = q.pop(); - if (s[o.i + 1] == null) { - s[o.i] = o.x; - } else { - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - } - n--; - } - if (s.length === 1) { - return s[0] == null ? (o = q[0].x, function(t) { - return o(t) + ""; - }) : function() { - return b; - }; - } - return function(t) { - for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - } - var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; - d3.interpolate = d3_interpolate; - function d3_interpolate(a, b) { - var i = d3.interpolators.length, f; - while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; - return f; - } - d3.interpolators = [ function(a, b) { - var t = typeof b; - return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_Color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b); - } ]; - d3.interpolateArray = d3_interpolateArray; - function d3_interpolateArray(a, b) { - var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; - for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); - for (;i < na; ++i) c[i] = a[i]; - for (;i < nb; ++i) c[i] = b[i]; - return function(t) { - for (i = 0; i < n0; ++i) c[i] = x[i](t); - return c; - }; - } - var d3_ease_default = function() { - return d3_identity; - }; - var d3_ease = d3.map({ - linear: d3_ease_default, - poly: d3_ease_poly, - quad: function() { - return d3_ease_quad; - }, - cubic: function() { - return d3_ease_cubic; - }, - sin: function() { - return d3_ease_sin; - }, - exp: function() { - return d3_ease_exp; - }, - circle: function() { - return d3_ease_circle; - }, - elastic: d3_ease_elastic, - back: d3_ease_back, - bounce: function() { - return d3_ease_bounce; - } - }); - var d3_ease_mode = d3.map({ - "in": d3_identity, - out: d3_ease_reverse, - "in-out": d3_ease_reflect, - "out-in": function(f) { - return d3_ease_reflect(d3_ease_reverse(f)); - } - }); - d3.ease = function(name) { - var i = name.indexOf("-"), t = i >= 0 ? name.substring(0, i) : name, m = i >= 0 ? name.substring(i + 1) : "in"; - t = d3_ease.get(t) || d3_ease_default; - m = d3_ease_mode.get(m) || d3_identity; - return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1)))); - }; - function d3_ease_clamp(f) { - return function(t) { - return t <= 0 ? 0 : t >= 1 ? 1 : f(t); - }; - } - function d3_ease_reverse(f) { - return function(t) { - return 1 - f(1 - t); - }; - } - function d3_ease_reflect(f) { - return function(t) { - return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); - }; - } - function d3_ease_quad(t) { - return t * t; - } - function d3_ease_cubic(t) { - return t * t * t; - } - function d3_ease_cubicInOut(t) { - if (t <= 0) return 0; - if (t >= 1) return 1; - var t2 = t * t, t3 = t2 * t; - return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); - } - function d3_ease_poly(e) { - return function(t) { - return Math.pow(t, e); - }; - } - function d3_ease_sin(t) { - return 1 - Math.cos(t * halfπ); - } - function d3_ease_exp(t) { - return Math.pow(2, 10 * (t - 1)); - } - function d3_ease_circle(t) { - return 1 - Math.sqrt(1 - t * t); - } - function d3_ease_elastic(a, p) { - var s; - if (arguments.length < 2) p = .45; - if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4; - return function(t) { - return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p); - }; - } - function d3_ease_back(s) { - if (!s) s = 1.70158; - return function(t) { - return t * t * ((s + 1) * t - s); - }; - } - function d3_ease_bounce(t) { - return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; - } - d3.interpolateHcl = d3_interpolateHcl; - function d3_interpolateHcl(a, b) { - a = d3.hcl(a); - b = d3.hcl(b); - var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; - if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; - }; - } - d3.interpolateHsl = d3_interpolateHsl; - function d3_interpolateHsl(a, b) { - a = d3.hsl(a); - b = d3.hsl(b); - var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; - if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; - }; - } - d3.interpolateLab = d3_interpolateLab; - function d3_interpolateLab(a, b) { - a = d3.lab(a); - b = d3.lab(b); - var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; - return function(t) { - return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; - }; - } - d3.interpolateRound = d3_interpolateRound; - function d3_interpolateRound(a, b) { - b -= a; - return function(t) { - return Math.round(a + b * t); - }; - } - d3.transform = function(string) { - var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); - return (d3.transform = function(string) { - if (string != null) { - g.setAttribute("transform", string); - var t = g.transform.baseVal.consolidate(); - } - return new d3_transform(t ? t.matrix : d3_transformIdentity); - })(string); - }; - function d3_transform(m) { - var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; - if (r0[0] * r1[1] < r1[0] * r0[1]) { - r0[0] *= -1; - r0[1] *= -1; - kx *= -1; - kz *= -1; - } - this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; - this.translate = [ m.e, m.f ]; - this.scale = [ kx, ky ]; - this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; - } - d3_transform.prototype.toString = function() { - return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; - }; - function d3_transformDot(a, b) { - return a[0] * b[0] + a[1] * b[1]; - } - function d3_transformNormalize(a) { - var k = Math.sqrt(d3_transformDot(a, a)); - if (k) { - a[0] /= k; - a[1] /= k; - } - return k; - } - function d3_transformCombine(a, b, k) { - a[0] += k * b[0]; - a[1] += k * b[1]; - return a; - } - var d3_transformIdentity = { - a: 1, - b: 0, - c: 0, - d: 1, - e: 0, - f: 0 - }; - d3.interpolateTransform = d3_interpolateTransform; - function d3_interpolateTransform(a, b) { - var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; - if (ta[0] != tb[0] || ta[1] != tb[1]) { - s.push("translate(", null, ",", null, ")"); - q.push({ - i: 1, - x: d3_interpolateNumber(ta[0], tb[0]) - }, { - i: 3, - x: d3_interpolateNumber(ta[1], tb[1]) - }); - } else if (tb[0] || tb[1]) { - s.push("translate(" + tb + ")"); - } else { - s.push(""); - } - if (ra != rb) { - if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; - q.push({ - i: s.push(s.pop() + "rotate(", null, ")") - 2, - x: d3_interpolateNumber(ra, rb) - }); - } else if (rb) { - s.push(s.pop() + "rotate(" + rb + ")"); - } - if (wa != wb) { - q.push({ - i: s.push(s.pop() + "skewX(", null, ")") - 2, - x: d3_interpolateNumber(wa, wb) - }); - } else if (wb) { - s.push(s.pop() + "skewX(" + wb + ")"); - } - if (ka[0] != kb[0] || ka[1] != kb[1]) { - n = s.push(s.pop() + "scale(", null, ",", null, ")"); - q.push({ - i: n - 4, - x: d3_interpolateNumber(ka[0], kb[0]) - }, { - i: n - 2, - x: d3_interpolateNumber(ka[1], kb[1]) - }); - } else if (kb[0] != 1 || kb[1] != 1) { - s.push(s.pop() + "scale(" + kb + ")"); - } - n = q.length; - return function(t) { - var i = -1, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - } - function d3_uninterpolateNumber(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { - return (x - a) * b; - }; - } - function d3_uninterpolateClamp(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { - return Math.max(0, Math.min(1, (x - a) * b)); - }; - } - d3.layout = {}; - d3.layout.bundle = function() { - return function(links) { - var paths = [], i = -1, n = links.length; - while (++i < n) paths.push(d3_layout_bundlePath(links[i])); - return paths; - }; - }; - function d3_layout_bundlePath(link) { - var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; - while (start !== lca) { - start = start.parent; - points.push(start); - } - var k = points.length; - while (end !== lca) { - points.splice(k, 0, end); - end = end.parent; - } - return points; - } - function d3_layout_bundleAncestors(node) { - var ancestors = [], parent = node.parent; - while (parent != null) { - ancestors.push(node); - node = parent; - parent = parent.parent; - } - ancestors.push(node); - return ancestors; - } - function d3_layout_bundleLeastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; - while (aNode === bNode) { - sharedNode = aNode; - aNode = aNodes.pop(); - bNode = bNodes.pop(); - } - return sharedNode; - } - d3.layout.chord = function() { - var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; - function relayout() { - var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; - chords = []; - groups = []; - k = 0, i = -1; - while (++i < n) { - x = 0, j = -1; - while (++j < n) { - x += matrix[i][j]; - } - groupSums.push(x); - subgroupIndex.push(d3.range(n)); - k += x; - } - if (sortGroups) { - groupIndex.sort(function(a, b) { - return sortGroups(groupSums[a], groupSums[b]); - }); - } - if (sortSubgroups) { - subgroupIndex.forEach(function(d, i) { - d.sort(function(a, b) { - return sortSubgroups(matrix[i][a], matrix[i][b]); - }); - }); - } - k = (τ - padding * n) / k; - x = 0, i = -1; - while (++i < n) { - x0 = x, j = -1; - while (++j < n) { - var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; - subgroups[di + "-" + dj] = { - index: di, - subindex: dj, - startAngle: a0, - endAngle: a1, - value: v - }; - } - groups[di] = { - index: di, - startAngle: x0, - endAngle: x, - value: (x - x0) / k - }; - x += padding; - } - i = -1; - while (++i < n) { - j = i - 1; - while (++j < n) { - var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; - if (source.value || target.value) { - chords.push(source.value < target.value ? { - source: target, - target: source - } : { - source: source, - target: target - }); - } - } - } - if (sortChords) resort(); - } - function resort() { - chords.sort(function(a, b) { - return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); - }); - } - chord.matrix = function(x) { - if (!arguments.length) return matrix; - n = (matrix = x) && matrix.length; - chords = groups = null; - return chord; - }; - chord.padding = function(x) { - if (!arguments.length) return padding; - padding = x; - chords = groups = null; - return chord; - }; - chord.sortGroups = function(x) { - if (!arguments.length) return sortGroups; - sortGroups = x; - chords = groups = null; - return chord; - }; - chord.sortSubgroups = function(x) { - if (!arguments.length) return sortSubgroups; - sortSubgroups = x; - chords = null; - return chord; - }; - chord.sortChords = function(x) { - if (!arguments.length) return sortChords; - sortChords = x; - if (chords) resort(); - return chord; - }; - chord.chords = function() { - if (!chords) relayout(); - return chords; - }; - chord.groups = function() { - if (!groups) relayout(); - return groups; - }; - return chord; - }; - d3.layout.force = function() { - var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges; - function repulse(node) { - return function(quad, x1, _, x2) { - if (quad.point !== node) { - var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy; - if (dw * dw / theta2 < dn) { - if (dn < chargeDistance2) { - var k = quad.charge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - return true; - } - if (quad.point && dn && dn < chargeDistance2) { - var k = quad.pointCharge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - } - return !quad.charge; - }; - } - force.tick = function() { - if ((alpha *= .99) < .005) { - event.end({ - type: "end", - alpha: alpha = 0 - }); - return true; - } - var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; - for (i = 0; i < m; ++i) { - o = links[i]; - s = o.source; - t = o.target; - x = t.x - s.x; - y = t.y - s.y; - if (l = x * x + y * y) { - l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; - x *= l; - y *= l; - t.x -= x * (k = s.weight / (t.weight + s.weight)); - t.y -= y * k; - s.x += x * (k = 1 - k); - s.y += y * k; - } - } - if (k = alpha * gravity) { - x = size[0] / 2; - y = size[1] / 2; - i = -1; - if (k) while (++i < n) { - o = nodes[i]; - o.x += (x - o.x) * k; - o.y += (y - o.y) * k; - } - } - if (charge) { - d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); - i = -1; - while (++i < n) { - if (!(o = nodes[i]).fixed) { - q.visit(repulse(o)); - } - } - } - i = -1; - while (++i < n) { - o = nodes[i]; - if (o.fixed) { - o.x = o.px; - o.y = o.py; - } else { - o.x -= (o.px - (o.px = o.x)) * friction; - o.y -= (o.py - (o.py = o.y)) * friction; - } - } - event.tick({ - type: "tick", - alpha: alpha - }); - }; - force.nodes = function(x) { - if (!arguments.length) return nodes; - nodes = x; - return force; - }; - force.links = function(x) { - if (!arguments.length) return links; - links = x; - return force; - }; - force.size = function(x) { - if (!arguments.length) return size; - size = x; - return force; - }; - force.linkDistance = function(x) { - if (!arguments.length) return linkDistance; - linkDistance = typeof x === "function" ? x : +x; - return force; - }; - force.distance = force.linkDistance; - force.linkStrength = function(x) { - if (!arguments.length) return linkStrength; - linkStrength = typeof x === "function" ? x : +x; - return force; - }; - force.friction = function(x) { - if (!arguments.length) return friction; - friction = +x; - return force; - }; - force.charge = function(x) { - if (!arguments.length) return charge; - charge = typeof x === "function" ? x : +x; - return force; - }; - force.chargeDistance = function(x) { - if (!arguments.length) return Math.sqrt(chargeDistance2); - chargeDistance2 = x * x; - return force; - }; - force.gravity = function(x) { - if (!arguments.length) return gravity; - gravity = +x; - return force; - }; - force.theta = function(x) { - if (!arguments.length) return Math.sqrt(theta2); - theta2 = x * x; - return force; - }; - force.alpha = function(x) { - if (!arguments.length) return alpha; - x = +x; - if (alpha) { - if (x > 0) alpha = x; else alpha = 0; - } else if (x > 0) { - event.start({ - type: "start", - alpha: alpha = x - }); - d3.timer(force.tick); - } - return force; - }; - force.start = function() { - var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; - for (i = 0; i < n; ++i) { - (o = nodes[i]).index = i; - o.weight = 0; - } - for (i = 0; i < m; ++i) { - o = links[i]; - if (typeof o.source == "number") o.source = nodes[o.source]; - if (typeof o.target == "number") o.target = nodes[o.target]; - ++o.source.weight; - ++o.target.weight; - } - for (i = 0; i < n; ++i) { - o = nodes[i]; - if (isNaN(o.x)) o.x = position("x", w); - if (isNaN(o.y)) o.y = position("y", h); - if (isNaN(o.px)) o.px = o.x; - if (isNaN(o.py)) o.py = o.y; - } - distances = []; - if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; - strengths = []; - if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; - charges = []; - if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; - function position(dimension, size) { - if (!neighbors) { - neighbors = new Array(n); - for (j = 0; j < n; ++j) { - neighbors[j] = []; - } - for (j = 0; j < m; ++j) { - var o = links[j]; - neighbors[o.source.index].push(o.target); - neighbors[o.target.index].push(o.source); - } - } - var candidates = neighbors[i], j = -1, m = candidates.length, x; - while (++j < m) if (!isNaN(x = candidates[j][dimension])) return x; - return Math.random() * size; - } - return force.resume(); - }; - force.resume = function() { - return force.alpha(.1); - }; - force.stop = function() { - return force.alpha(0); - }; - force.drag = function() { - if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); - if (!arguments.length) return drag; - this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); - }; - function dragmove(d) { - d.px = d3.event.x, d.py = d3.event.y; - force.resume(); - } - return d3.rebind(force, event, "on"); - }; - function d3_layout_forceDragstart(d) { - d.fixed |= 2; - } - function d3_layout_forceDragend(d) { - d.fixed &= ~6; - } - function d3_layout_forceMouseover(d) { - d.fixed |= 4; - d.px = d.x, d.py = d.y; - } - function d3_layout_forceMouseout(d) { - d.fixed &= ~4; - } - function d3_layout_forceAccumulate(quad, alpha, charges) { - var cx = 0, cy = 0; - quad.charge = 0; - if (!quad.leaf) { - var nodes = quad.nodes, n = nodes.length, i = -1, c; - while (++i < n) { - c = nodes[i]; - if (c == null) continue; - d3_layout_forceAccumulate(c, alpha, charges); - quad.charge += c.charge; - cx += c.charge * c.cx; - cy += c.charge * c.cy; - } - } - if (quad.point) { - if (!quad.leaf) { - quad.point.x += Math.random() - .5; - quad.point.y += Math.random() - .5; - } - var k = alpha * charges[quad.point.index]; - quad.charge += quad.pointCharge = k; - cx += k * quad.point.x; - cy += k * quad.point.y; - } - quad.cx = cx / quad.charge; - quad.cy = cy / quad.charge; - } - var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity; - d3.layout.hierarchy = function() { - var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; - function recurse(node, depth, nodes) { - var childs = children.call(hierarchy, node, depth); - node.depth = depth; - nodes.push(node); - if (childs && (n = childs.length)) { - var i = -1, n, c = node.children = new Array(n), v = 0, j = depth + 1, d; - while (++i < n) { - d = c[i] = recurse(childs[i], j, nodes); - d.parent = node; - v += d.value; - } - if (sort) c.sort(sort); - if (value) node.value = v; - } else { - delete node.children; - if (value) { - node.value = +value.call(hierarchy, node, depth) || 0; - } - } - return node; - } - function revalue(node, depth) { - var children = node.children, v = 0; - if (children && (n = children.length)) { - var i = -1, n, j = depth + 1; - while (++i < n) v += revalue(children[i], j); - } else if (value) { - v = +value.call(hierarchy, node, depth) || 0; - } - if (value) node.value = v; - return v; - } - function hierarchy(d) { - var nodes = []; - recurse(d, 0, nodes); - return nodes; - } - hierarchy.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return hierarchy; - }; - hierarchy.children = function(x) { - if (!arguments.length) return children; - children = x; - return hierarchy; - }; - hierarchy.value = function(x) { - if (!arguments.length) return value; - value = x; - return hierarchy; - }; - hierarchy.revalue = function(root) { - revalue(root, 0); - return root; - }; - return hierarchy; - }; - function d3_layout_hierarchyRebind(object, hierarchy) { - d3.rebind(object, hierarchy, "sort", "children", "value"); - object.nodes = object; - object.links = d3_layout_hierarchyLinks; - return object; - } - function d3_layout_hierarchyChildren(d) { - return d.children; - } - function d3_layout_hierarchyValue(d) { - return d.value; - } - function d3_layout_hierarchySort(a, b) { - return b.value - a.value; - } - function d3_layout_hierarchyLinks(nodes) { - return d3.merge(nodes.map(function(parent) { - return (parent.children || []).map(function(child) { - return { - source: parent, - target: child - }; - }); - })); - } - d3.layout.partition = function() { - var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; - function position(node, x, dx, dy) { - var children = node.children; - node.x = x; - node.y = node.depth * dy; - node.dx = dx; - node.dy = dy; - if (children && (n = children.length)) { - var i = -1, n, c, d; - dx = node.value ? dx / node.value : 0; - while (++i < n) { - position(c = children[i], x, d = c.value * dx, dy); - x += d; - } - } - } - function depth(node) { - var children = node.children, d = 0; - if (children && (n = children.length)) { - var i = -1, n; - while (++i < n) d = Math.max(d, depth(children[i])); - } - return 1 + d; - } - function partition(d, i) { - var nodes = hierarchy.call(this, d, i); - position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); - return nodes; - } - partition.size = function(x) { - if (!arguments.length) return size; - size = x; - return partition; - }; - return d3_layout_hierarchyRebind(partition, hierarchy); - }; - d3.layout.pie = function() { - var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ; - function pie(data) { - var values = data.map(function(d, i) { - return +value.call(pie, d, i); - }); - var a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle); - var k = ((typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a) / d3.sum(values); - var index = d3.range(data.length); - if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { - return values[j] - values[i]; - } : function(i, j) { - return sort(data[i], data[j]); - }); - var arcs = []; - index.forEach(function(i) { - var d; - arcs[i] = { - data: data[i], - value: d = values[i], - startAngle: a, - endAngle: a += d * k - }; - }); - return arcs; - } - pie.value = function(x) { - if (!arguments.length) return value; - value = x; - return pie; - }; - pie.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return pie; - }; - pie.startAngle = function(x) { - if (!arguments.length) return startAngle; - startAngle = x; - return pie; - }; - pie.endAngle = function(x) { - if (!arguments.length) return endAngle; - endAngle = x; - return pie; - }; - return pie; - }; - var d3_layout_pieSortByValue = {}; - d3.layout.stack = function() { - var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; - function stack(data, index) { - var series = data.map(function(d, i) { - return values.call(stack, d, i); - }); - var points = series.map(function(d) { - return d.map(function(v, i) { - return [ x.call(stack, v, i), y.call(stack, v, i) ]; - }); - }); - var orders = order.call(stack, points, index); - series = d3.permute(series, orders); - points = d3.permute(points, orders); - var offsets = offset.call(stack, points, index); - var n = series.length, m = series[0].length, i, j, o; - for (j = 0; j < m; ++j) { - out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); - for (i = 1; i < n; ++i) { - out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); - } - } - return data; - } - stack.values = function(x) { - if (!arguments.length) return values; - values = x; - return stack; - }; - stack.order = function(x) { - if (!arguments.length) return order; - order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; - return stack; - }; - stack.offset = function(x) { - if (!arguments.length) return offset; - offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; - return stack; - }; - stack.x = function(z) { - if (!arguments.length) return x; - x = z; - return stack; - }; - stack.y = function(z) { - if (!arguments.length) return y; - y = z; - return stack; - }; - stack.out = function(z) { - if (!arguments.length) return out; - out = z; - return stack; - }; - return stack; - }; - function d3_layout_stackX(d) { - return d.x; - } - function d3_layout_stackY(d) { - return d.y; - } - function d3_layout_stackOut(d, y0, y) { - d.y0 = y0; - d.y = y; - } - var d3_layout_stackOrders = d3.map({ - "inside-out": function(data) { - var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { - return max[a] - max[b]; - }), top = 0, bottom = 0, tops = [], bottoms = []; - for (i = 0; i < n; ++i) { - j = index[i]; - if (top < bottom) { - top += sums[j]; - tops.push(j); - } else { - bottom += sums[j]; - bottoms.push(j); - } - } - return bottoms.reverse().concat(tops); - }, - reverse: function(data) { - return d3.range(data.length).reverse(); - }, - "default": d3_layout_stackOrderDefault - }); - var d3_layout_stackOffsets = d3.map({ - silhouette: function(data) { - var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o > max) max = o; - sums.push(o); - } - for (j = 0; j < m; ++j) { - y0[j] = (max - sums[j]) / 2; - } - return y0; - }, - wiggle: function(data) { - var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; - y0[0] = o = o0 = 0; - for (j = 1; j < m; ++j) { - for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; - for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { - for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { - s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; - } - s2 += s3 * data[i][j][1]; - } - y0[j] = o -= s1 ? s2 / s1 * dx : 0; - if (o < o0) o0 = o; - } - for (j = 0; j < m; ++j) y0[j] -= o0; - return y0; - }, - expand: function(data) { - var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; - } - for (j = 0; j < m; ++j) y0[j] = 0; - return y0; - }, - zero: d3_layout_stackOffsetZero - }); - function d3_layout_stackOrderDefault(data) { - return d3.range(data.length); - } - function d3_layout_stackOffsetZero(data) { - var j = -1, m = data[0].length, y0 = []; - while (++j < m) y0[j] = 0; - return y0; - } - function d3_layout_stackMaxIndex(array) { - var i = 1, j = 0, v = array[0][1], k, n = array.length; - for (;i < n; ++i) { - if ((k = array[i][1]) > v) { - j = i; - v = k; - } - } - return j; - } - function d3_layout_stackReduceSum(d) { - return d.reduce(d3_layout_stackSum, 0); - } - function d3_layout_stackSum(p, d) { - return p + d[1]; - } - d3.layout.histogram = function() { - var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; - function histogram(data, i) { - var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; - while (++i < m) { - bin = bins[i] = []; - bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); - bin.y = 0; - } - if (m > 0) { - i = -1; - while (++i < n) { - x = values[i]; - if (x >= range[0] && x <= range[1]) { - bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; - bin.y += k; - bin.push(data[i]); - } - } - } - return bins; - } - histogram.value = function(x) { - if (!arguments.length) return valuer; - valuer = x; - return histogram; - }; - histogram.range = function(x) { - if (!arguments.length) return ranger; - ranger = d3_functor(x); - return histogram; - }; - histogram.bins = function(x) { - if (!arguments.length) return binner; - binner = typeof x === "number" ? function(range) { - return d3_layout_histogramBinFixed(range, x); - } : d3_functor(x); - return histogram; - }; - histogram.frequency = function(x) { - if (!arguments.length) return frequency; - frequency = !!x; - return histogram; - }; - return histogram; - }; - function d3_layout_histogramBinSturges(range, values) { - return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); - } - function d3_layout_histogramBinFixed(range, n) { - var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; - while (++x <= n) f[x] = m * x + b; - return f; - } - function d3_layout_histogramRange(values) { - return [ d3.min(values), d3.max(values) ]; - } - d3.layout.tree = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; - function tree(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0]; - function firstWalk(node, previousSibling) { - var children = node.children, layout = node._tree; - if (children && (n = children.length)) { - var n, firstChild = children[0], previousChild, ancestor = firstChild, child, i = -1; - while (++i < n) { - child = children[i]; - firstWalk(child, previousChild); - ancestor = apportion(child, previousChild, ancestor); - previousChild = child; - } - d3_layout_treeShift(node); - var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim); - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - layout.mod = layout.prelim - midpoint; - } else { - layout.prelim = midpoint; - } - } else { - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - } - } - } - function secondWalk(node, x) { - node.x = node._tree.prelim + x; - var children = node.children; - if (children && (n = children.length)) { - var i = -1, n; - x += node._tree.mod; - while (++i < n) { - secondWalk(children[i], x); - } - } - } - function apportion(node, previousSibling, ancestor) { - if (previousSibling) { - var vip = node, vop = node, vim = previousSibling, vom = node.parent.children[0], sip = vip._tree.mod, sop = vop._tree.mod, sim = vim._tree.mod, som = vom._tree.mod, shift; - while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { - vom = d3_layout_treeLeft(vom); - vop = d3_layout_treeRight(vop); - vop._tree.ancestor = node; - shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip); - if (shift > 0) { - d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift); - sip += shift; - sop += shift; - } - sim += vim._tree.mod; - sip += vip._tree.mod; - som += vom._tree.mod; - sop += vop._tree.mod; - } - if (vim && !d3_layout_treeRight(vop)) { - vop._tree.thread = vim; - vop._tree.mod += sim - sop; - } - if (vip && !d3_layout_treeLeft(vom)) { - vom._tree.thread = vip; - vom._tree.mod += sip - som; - ancestor = node; - } - } - return ancestor; - } - d3_layout_treeVisitAfter(root, function(node, previousSibling) { - node._tree = { - ancestor: node, - prelim: 0, - mod: 0, - change: 0, - shift: 0, - number: previousSibling ? previousSibling._tree.number + 1 : 0 - }; - }); - firstWalk(root); - secondWalk(root, -root._tree.prelim); - var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), right = d3_layout_treeSearch(root, d3_layout_treeRightmost), deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2, y1 = deep.depth || 1; - d3_layout_treeVisitAfter(root, nodeSize ? function(node) { - node.x *= size[0]; - node.y = node.depth * size[1]; - delete node._tree; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = node.depth / y1 * size[1]; - delete node._tree; - }); - return nodes; - } - tree.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return tree; - }; - tree.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return tree; - }; - tree.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return tree; - }; - return d3_layout_hierarchyRebind(tree, hierarchy); - }; - function d3_layout_treeSeparation(a, b) { - return a.parent == b.parent ? 1 : 2; - } - function d3_layout_treeLeft(node) { - var children = node.children; - return children && children.length ? children[0] : node._tree.thread; - } - function d3_layout_treeRight(node) { - var children = node.children, n; - return children && (n = children.length) ? children[n - 1] : node._tree.thread; - } - function d3_layout_treeSearch(node, compare) { - var children = node.children; - if (children && (n = children.length)) { - var child, n, i = -1; - while (++i < n) { - if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) { - node = child; - } - } - } - return node; - } - function d3_layout_treeRightmost(a, b) { - return a.x - b.x; - } - function d3_layout_treeLeftmost(a, b) { - return b.x - a.x; - } - function d3_layout_treeDeepest(a, b) { - return a.depth - b.depth; - } - function d3_layout_treeVisitAfter(node, callback) { - function visit(node, previousSibling) { - var children = node.children; - if (children && (n = children.length)) { - var child, previousChild = null, i = -1, n; - while (++i < n) { - child = children[i]; - visit(child, previousChild); - previousChild = child; - } - } - callback(node, previousSibling); - } - visit(node, null); - } - function d3_layout_treeShift(node) { - var shift = 0, change = 0, children = node.children, i = children.length, child; - while (--i >= 0) { - child = children[i]._tree; - child.prelim += shift; - child.mod += shift; - shift += child.shift + (change += child.change); - } - } - function d3_layout_treeMove(ancestor, node, shift) { - ancestor = ancestor._tree; - node = node._tree; - var change = shift / (node.number - ancestor.number); - ancestor.change += change; - node.change -= change; - node.shift += shift; - node.prelim += shift; - node.mod += shift; - } - function d3_layout_treeAncestor(vim, node, ancestor) { - return vim._tree.ancestor.parent == node.parent ? vim._tree.ancestor : ancestor; - } - d3.layout.pack = function() { - var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; - function pack(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { - return radius; - }; - root.x = root.y = 0; - d3_layout_treeVisitAfter(root, function(d) { - d.r = +r(d.value); - }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - if (padding) { - var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; - d3_layout_treeVisitAfter(root, function(d) { - d.r += dr; - }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - d3_layout_treeVisitAfter(root, function(d) { - d.r -= dr; - }); - } - d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); - return nodes; - } - pack.size = function(_) { - if (!arguments.length) return size; - size = _; - return pack; - }; - pack.radius = function(_) { - if (!arguments.length) return radius; - radius = _ == null || typeof _ === "function" ? _ : +_; - return pack; - }; - pack.padding = function(_) { - if (!arguments.length) return padding; - padding = +_; - return pack; - }; - return d3_layout_hierarchyRebind(pack, hierarchy); - }; - function d3_layout_packSort(a, b) { - return a.value - b.value; - } - function d3_layout_packInsert(a, b) { - var c = a._pack_next; - a._pack_next = b; - b._pack_prev = a; - b._pack_next = c; - c._pack_prev = b; - } - function d3_layout_packSplice(a, b) { - a._pack_next = b; - b._pack_prev = a; - } - function d3_layout_packIntersects(a, b) { - var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; - return .999 * dr * dr > dx * dx + dy * dy; - } - function d3_layout_packSiblings(node) { - if (!(nodes = node.children) || !(n = nodes.length)) return; - var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; - function bound(node) { - xMin = Math.min(node.x - node.r, xMin); - xMax = Math.max(node.x + node.r, xMax); - yMin = Math.min(node.y - node.r, yMin); - yMax = Math.max(node.y + node.r, yMax); - } - nodes.forEach(d3_layout_packLink); - a = nodes[0]; - a.x = -a.r; - a.y = 0; - bound(a); - if (n > 1) { - b = nodes[1]; - b.x = b.r; - b.y = 0; - bound(b); - if (n > 2) { - c = nodes[2]; - d3_layout_packPlace(a, b, c); - bound(c); - d3_layout_packInsert(a, c); - a._pack_prev = c; - d3_layout_packInsert(c, b); - b = a._pack_next; - for (i = 3; i < n; i++) { - d3_layout_packPlace(a, b, c = nodes[i]); - var isect = 0, s1 = 1, s2 = 1; - for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { - if (d3_layout_packIntersects(j, c)) { - isect = 1; - break; - } - } - if (isect == 1) { - for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { - if (d3_layout_packIntersects(k, c)) { - break; - } - } - } - if (isect) { - if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); - i--; - } else { - d3_layout_packInsert(a, c); - b = c; - bound(c); - } - } - } - } - var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; - for (i = 0; i < n; i++) { - c = nodes[i]; - c.x -= cx; - c.y -= cy; - cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); - } - node.r = cr; - nodes.forEach(d3_layout_packUnlink); - } - function d3_layout_packLink(node) { - node._pack_next = node._pack_prev = node; - } - function d3_layout_packUnlink(node) { - delete node._pack_next; - delete node._pack_prev; - } - function d3_layout_packTransform(node, x, y, k) { - var children = node.children; - node.x = x += k * node.x; - node.y = y += k * node.y; - node.r *= k; - if (children) { - var i = -1, n = children.length; - while (++i < n) d3_layout_packTransform(children[i], x, y, k); - } - } - function d3_layout_packPlace(a, b, c) { - var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; - if (db && (dx || dy)) { - var da = b.r + c.r, dc = dx * dx + dy * dy; - da *= da; - db *= db; - var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); - c.x = a.x + x * dx + y * dy; - c.y = a.y + x * dy - y * dx; - } else { - c.x = a.x + db; - c.y = a.y; - } - } - d3.layout.cluster = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; - function cluster(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; - d3_layout_treeVisitAfter(root, function(node) { - var children = node.children; - if (children && children.length) { - node.x = d3_layout_clusterX(children); - node.y = d3_layout_clusterY(children); - } else { - node.x = previousNode ? x += separation(node, previousNode) : 0; - node.y = 0; - previousNode = node; - } - }); - var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; - d3_layout_treeVisitAfter(root, nodeSize ? function(node) { - node.x = (node.x - root.x) * size[0]; - node.y = (root.y - node.y) * size[1]; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; - }); - return nodes; - } - cluster.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return cluster; - }; - cluster.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return cluster; - }; - cluster.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return cluster; - }; - return d3_layout_hierarchyRebind(cluster, hierarchy); - }; - function d3_layout_clusterY(children) { - return 1 + d3.max(children, function(child) { - return child.y; - }); - } - function d3_layout_clusterX(children) { - return children.reduce(function(x, child) { - return x + child.x; - }, 0) / children.length; - } - function d3_layout_clusterLeft(node) { - var children = node.children; - return children && children.length ? d3_layout_clusterLeft(children[0]) : node; - } - function d3_layout_clusterRight(node) { - var children = node.children, n; - return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; - } - d3.layout.treemap = function() { - var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); - function scale(children, k) { - var i = -1, n = children.length, child, area; - while (++i < n) { - area = (child = children[i]).value * (k < 0 ? 0 : k); - child.area = isNaN(area) || area <= 0 ? 0 : area; - } - } - function squarify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while ((n = remaining.length) > 0) { - row.push(child = remaining[n - 1]); - row.area += child.area; - if (mode !== "squarify" || (score = worst(row, u)) <= best) { - remaining.pop(); - best = score; - } else { - row.area -= row.pop().area; - position(row, u, rect, false); - u = Math.min(rect.dx, rect.dy); - row.length = row.area = 0; - best = Infinity; - } - } - if (row.length) { - position(row, u, rect, true); - row.length = row.area = 0; - } - children.forEach(squarify); - } - } - function stickify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), remaining = children.slice(), child, row = []; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while (child = remaining.pop()) { - row.push(child); - row.area += child.area; - if (child.z != null) { - position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); - row.length = row.area = 0; - } - } - children.forEach(stickify); - } - } - function worst(row, u) { - var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; - while (++i < n) { - if (!(r = row[i].area)) continue; - if (r < rmin) rmin = r; - if (r > rmax) rmax = r; - } - s *= s; - u *= u; - return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; - } - function position(row, u, rect, flush) { - var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; - if (u == rect.dx) { - if (flush || v > rect.dy) v = rect.dy; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dy = v; - x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); - } - o.z = true; - o.dx += rect.x + rect.dx - x; - rect.y += v; - rect.dy -= v; - } else { - if (flush || v > rect.dx) v = rect.dx; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dx = v; - y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); - } - o.z = false; - o.dy += rect.y + rect.dy - y; - rect.x += v; - rect.dx -= v; - } - } - function treemap(d) { - var nodes = stickies || hierarchy(d), root = nodes[0]; - root.x = 0; - root.y = 0; - root.dx = size[0]; - root.dy = size[1]; - if (stickies) hierarchy.revalue(root); - scale([ root ], root.dx * root.dy / root.value); - (stickies ? stickify : squarify)(root); - if (sticky) stickies = nodes; - return nodes; - } - treemap.size = function(x) { - if (!arguments.length) return size; - size = x; - return treemap; - }; - treemap.padding = function(x) { - if (!arguments.length) return padding; - function padFunction(node) { - var p = x.call(treemap, node, node.depth); - return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); - } - function padConstant(node) { - return d3_layout_treemapPad(node, x); - } - var type; - pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], - padConstant) : padConstant; - return treemap; - }; - treemap.round = function(x) { - if (!arguments.length) return round != Number; - round = x ? Math.round : Number; - return treemap; - }; - treemap.sticky = function(x) { - if (!arguments.length) return sticky; - sticky = x; - stickies = null; - return treemap; - }; - treemap.ratio = function(x) { - if (!arguments.length) return ratio; - ratio = x; - return treemap; - }; - treemap.mode = function(x) { - if (!arguments.length) return mode; - mode = x + ""; - return treemap; - }; - return d3_layout_hierarchyRebind(treemap, hierarchy); - }; - function d3_layout_treemapPadNull(node) { - return { - x: node.x, - y: node.y, - dx: node.dx, - dy: node.dy - }; - } - function d3_layout_treemapPad(node, padding) { - var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; - if (dx < 0) { - x += dx / 2; - dx = 0; - } - if (dy < 0) { - y += dy / 2; - dy = 0; - } - return { - x: x, - y: y, - dx: dx, - dy: dy - }; - } - d3.random = { - normal: function(µ, σ) { - var n = arguments.length; - if (n < 2) σ = 1; - if (n < 1) µ = 0; - return function() { - var x, y, r; - do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); - return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); - }; - }, - logNormal: function() { - var random = d3.random.normal.apply(d3, arguments); - return function() { - return Math.exp(random()); - }; - }, - bates: function(m) { - var random = d3.random.irwinHall(m); - return function() { - return random() / m; - }; - }, - irwinHall: function(m) { - return function() { - for (var s = 0, j = 0; j < m; j++) s += Math.random(); - return s; - }; - } - }; - d3.scale = {}; - function d3_scaleExtent(domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; - } - function d3_scaleRange(scale) { - return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); - } - function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { - var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); - return function(x) { - return i(u(x)); - }; - } - function d3_scale_nice(domain, nice) { - var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; - if (x1 < x0) { - dx = i0, i0 = i1, i1 = dx; - dx = x0, x0 = x1, x1 = dx; - } - domain[i0] = nice.floor(x0); - domain[i1] = nice.ceil(x1); - return domain; - } - function d3_scale_niceStep(step) { - return step ? { - floor: function(x) { - return Math.floor(x / step) * step; - }, - ceil: function(x) { - return Math.ceil(x / step) * step; - } - } : d3_scale_niceIdentity; - } - var d3_scale_niceIdentity = { - floor: d3_identity, - ceil: d3_identity - }; - function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { - var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; - if (domain[k] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - while (++j <= k) { - u.push(uninterpolate(domain[j - 1], domain[j])); - i.push(interpolate(range[j - 1], range[j])); - } - return function(x) { - var j = d3.bisect(domain, x, 1, k) - 1; - return i[j](u[j](x)); - }; - } - d3.scale.linear = function() { - return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); - }; - function d3_scale_linear(domain, range, interpolate, clamp) { - var output, input; - function rescale() { - var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; - output = linear(domain, range, uninterpolate, interpolate); - input = linear(range, domain, uninterpolate, d3_interpolate); - return scale; - } - function scale(x) { - return output(x); - } - scale.invert = function(y) { - return input(y); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(Number); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.rangeRound = function(x) { - return scale.range(x).interpolate(d3_interpolateRound); - }; - scale.clamp = function(x) { - if (!arguments.length) return clamp; - clamp = x; - return rescale(); - }; - scale.interpolate = function(x) { - if (!arguments.length) return interpolate; - interpolate = x; - return rescale(); - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - d3_scale_linearNice(domain, m); - return rescale(); - }; - scale.copy = function() { - return d3_scale_linear(domain, range, interpolate, clamp); - }; - return rescale(); - } - function d3_scale_linearRebind(scale, linear) { - return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); - } - function d3_scale_linearNice(domain, m) { - return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); - } - function d3_scale_linearTickRange(domain, m) { - if (m == null) m = 10; - var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; - if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; - extent[0] = Math.ceil(extent[0] / step) * step; - extent[1] = Math.floor(extent[1] / step) * step + step * .5; - extent[2] = step; - return extent; - } - function d3_scale_linearTicks(domain, m) { - return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); - } - function d3_scale_linearTickFormat(domain, m, format) { - var range = d3_scale_linearTickRange(domain, m); - if (format) { - var match = d3_format_re.exec(format); - match.shift(); - if (match[8] === "s") { - var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1]))); - if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])); - match[8] = "f"; - format = d3.format(match.join("")); - return function(d) { - return format(prefix.scale(d)) + prefix.symbol; - }; - } - if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range); - format = match.join(""); - } else { - format = ",." + d3_scale_linearPrecision(range[2]) + "f"; - } - return d3.format(format); - } - var d3_scale_linearFormatSignificant = { - s: 1, - g: 1, - p: 1, - r: 1, - e: 1 - }; - function d3_scale_linearPrecision(value) { - return -Math.floor(Math.log(value) / Math.LN10 + .01); - } - function d3_scale_linearFormatPrecision(type, range) { - var p = d3_scale_linearPrecision(range[2]); - return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2; - } - d3.scale.log = function() { - return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); - }; - function d3_scale_log(linear, base, positive, domain) { - function log(x) { - return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); - } - function pow(x) { - return positive ? Math.pow(base, x) : -Math.pow(base, -x); - } - function scale(x) { - return linear(log(x)); - } - scale.invert = function(x) { - return pow(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - positive = x[0] >= 0; - linear.domain((domain = x.map(Number)).map(log)); - return scale; - }; - scale.base = function(_) { - if (!arguments.length) return base; - base = +_; - linear.domain(domain.map(log)); - return scale; - }; - scale.nice = function() { - var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); - linear.domain(niced); - domain = niced.map(pow); - return scale; - }; - scale.ticks = function() { - var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; - if (isFinite(j - i)) { - if (positive) { - for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); - ticks.push(pow(i)); - } else { - ticks.push(pow(i)); - for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); - } - for (i = 0; ticks[i] < u; i++) {} - for (j = ticks.length; ticks[j - 1] > v; j--) {} - ticks = ticks.slice(i, j); - } - return ticks; - }; - scale.tickFormat = function(n, format) { - if (!arguments.length) return d3_scale_logFormat; - if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); - var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, - Math.floor), e; - return function(d) { - return d / pow(f(log(d) + e)) <= k ? format(d) : ""; - }; - }; - scale.copy = function() { - return d3_scale_log(linear.copy(), base, positive, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { - floor: function(x) { - return -Math.ceil(-x); - }, - ceil: function(x) { - return -Math.floor(-x); - } - }; - d3.scale.pow = function() { - return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); - }; - function d3_scale_pow(linear, exponent, domain) { - var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); - function scale(x) { - return linear(powp(x)); - } - scale.invert = function(x) { - return powb(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - linear.domain((domain = x.map(Number)).map(powp)); - return scale; - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - return scale.domain(d3_scale_linearNice(domain, m)); - }; - scale.exponent = function(x) { - if (!arguments.length) return exponent; - powp = d3_scale_powPow(exponent = x); - powb = d3_scale_powPow(1 / exponent); - linear.domain(domain.map(powp)); - return scale; - }; - scale.copy = function() { - return d3_scale_pow(linear.copy(), exponent, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_scale_powPow(e) { - return function(x) { - return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); - }; - } - d3.scale.sqrt = function() { - return d3.scale.pow().exponent(.5); - }; - d3.scale.ordinal = function() { - return d3_scale_ordinal([], { - t: "range", - a: [ [] ] - }); - }; - function d3_scale_ordinal(domain, ranger) { - var index, range, rangeBand; - function scale(x) { - return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length]; - } - function steps(start, step) { - return d3.range(domain.length).map(function(i) { - return start + step * i; - }); - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = []; - index = new d3_Map(); - var i = -1, n = x.length, xi; - while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); - return scale[ranger.t].apply(scale, ranger.a); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - rangeBand = 0; - ranger = { - t: "range", - a: arguments - }; - return scale; - }; - scale.rangePoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding); - range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); - rangeBand = 0; - ranger = { - t: "rangePoints", - a: arguments - }; - return scale; - }; - scale.rangeBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); - range = steps(start + step * outerPadding, step); - if (reverse) range.reverse(); - rangeBand = step * (1 - padding); - ranger = { - t: "rangeBands", - a: arguments - }; - return scale; - }; - scale.rangeRoundBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step; - range = steps(start + Math.round(error / 2), step); - if (reverse) range.reverse(); - rangeBand = Math.round(step * (1 - padding)); - ranger = { - t: "rangeRoundBands", - a: arguments - }; - return scale; - }; - scale.rangeBand = function() { - return rangeBand; - }; - scale.rangeExtent = function() { - return d3_scaleExtent(ranger.a[0]); - }; - scale.copy = function() { - return d3_scale_ordinal(domain, ranger); - }; - return scale.domain(domain); - } - d3.scale.category10 = function() { - return d3.scale.ordinal().range(d3_category10); - }; - d3.scale.category20 = function() { - return d3.scale.ordinal().range(d3_category20); - }; - d3.scale.category20b = function() { - return d3.scale.ordinal().range(d3_category20b); - }; - d3.scale.category20c = function() { - return d3.scale.ordinal().range(d3_category20c); - }; - var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); - var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); - var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); - var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); - d3.scale.quantile = function() { - return d3_scale_quantile([], []); - }; - function d3_scale_quantile(domain, range) { - var thresholds; - function rescale() { - var k = 0, q = range.length; - thresholds = []; - while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); - return scale; - } - function scale(x) { - if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.filter(function(d) { - return !isNaN(d); - }).sort(d3_ascending); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.quantiles = function() { - return thresholds; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; - }; - scale.copy = function() { - return d3_scale_quantile(domain, range); - }; - return rescale(); - } - d3.scale.quantize = function() { - return d3_scale_quantize(0, 1, [ 0, 1 ]); - }; - function d3_scale_quantize(x0, x1, range) { - var kx, i; - function scale(x) { - return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; - } - function rescale() { - kx = range.length / (x1 - x0); - i = range.length - 1; - return scale; - } - scale.domain = function(x) { - if (!arguments.length) return [ x0, x1 ]; - x0 = +x[0]; - x1 = +x[x.length - 1]; - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - y = y < 0 ? NaN : y / kx + x0; - return [ y, y + 1 / kx ]; - }; - scale.copy = function() { - return d3_scale_quantize(x0, x1, range); - }; - return rescale(); - } - d3.scale.threshold = function() { - return d3_scale_threshold([ .5 ], [ 0, 1 ]); - }; - function d3_scale_threshold(domain, range) { - function scale(x) { - if (x <= x) return range[d3.bisect(domain, x)]; - } - scale.domain = function(_) { - if (!arguments.length) return domain; - domain = _; - return scale; - }; - scale.range = function(_) { - if (!arguments.length) return range; - range = _; - return scale; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return [ domain[y - 1], domain[y] ]; - }; - scale.copy = function() { - return d3_scale_threshold(domain, range); - }; - return scale; - } - d3.scale.identity = function() { - return d3_scale_identity([ 0, 1 ]); - }; - function d3_scale_identity(domain) { - function identity(x) { - return +x; - } - identity.invert = identity; - identity.domain = identity.range = function(x) { - if (!arguments.length) return domain; - domain = x.map(identity); - return identity; - }; - identity.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - identity.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - identity.copy = function() { - return d3_scale_identity(domain); - }; - return identity; - } - d3.svg = {}; - d3.svg.arc = function() { - var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function arc() { - var r0 = innerRadius.apply(this, arguments), r1 = outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, da = (a1 < a0 && (da = a0, - a0 = a1, a1 = da), a1 - a0), df = da < π ? "0" : "1", c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1); - return da >= d3_svg_arcMax ? r0 ? "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "M0," + r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + -r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + "Z" : "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "Z" : r0 ? "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L" + r0 * c1 + "," + r0 * s1 + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + "Z" : "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L0,0" + "Z"; - } - arc.innerRadius = function(v) { - if (!arguments.length) return innerRadius; - innerRadius = d3_functor(v); - return arc; - }; - arc.outerRadius = function(v) { - if (!arguments.length) return outerRadius; - outerRadius = d3_functor(v); - return arc; - }; - arc.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return arc; - }; - arc.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return arc; - }; - arc.centroid = function() { - var r = (innerRadius.apply(this, arguments) + outerRadius.apply(this, arguments)) / 2, a = (startAngle.apply(this, arguments) + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; - return [ Math.cos(a) * r, Math.sin(a) * r ]; - }; - return arc; - }; - var d3_svg_arcOffset = -halfπ, d3_svg_arcMax = τ - ε; - function d3_svg_arcInnerRadius(d) { - return d.innerRadius; - } - function d3_svg_arcOuterRadius(d) { - return d.outerRadius; - } - function d3_svg_arcStartAngle(d) { - return d.startAngle; - } - function d3_svg_arcEndAngle(d) { - return d.endAngle; - } - function d3_svg_line(projection) { - var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; - function line(data) { - var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); - function segment() { - segments.push("M", interpolate(projection(points), tension)); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); - } else if (points.length) { - segment(); - points = []; - } - } - if (points.length) segment(); - return segments.length ? segments.join("") : null; - } - line.x = function(_) { - if (!arguments.length) return x; - x = _; - return line; - }; - line.y = function(_) { - if (!arguments.length) return y; - y = _; - return line; - }; - line.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return line; - }; - line.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - return line; - }; - line.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return line; - }; - return line; - } - d3.svg.line = function() { - return d3_svg_line(d3_identity); - }; - var d3_svg_lineInterpolators = d3.map({ - linear: d3_svg_lineLinear, - "linear-closed": d3_svg_lineLinearClosed, - step: d3_svg_lineStep, - "step-before": d3_svg_lineStepBefore, - "step-after": d3_svg_lineStepAfter, - basis: d3_svg_lineBasis, - "basis-open": d3_svg_lineBasisOpen, - "basis-closed": d3_svg_lineBasisClosed, - bundle: d3_svg_lineBundle, - cardinal: d3_svg_lineCardinal, - "cardinal-open": d3_svg_lineCardinalOpen, - "cardinal-closed": d3_svg_lineCardinalClosed, - monotone: d3_svg_lineMonotone - }); - d3_svg_lineInterpolators.forEach(function(key, value) { - value.key = key; - value.closed = /-closed$/.test(key); - }); - function d3_svg_lineLinear(points) { - return points.join("L"); - } - function d3_svg_lineLinearClosed(points) { - return d3_svg_lineLinear(points) + "Z"; - } - function d3_svg_lineStep(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); - if (n > 1) path.push("H", p[0]); - return path.join(""); - } - function d3_svg_lineStepBefore(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); - return path.join(""); - } - function d3_svg_lineStepAfter(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); - return path.join(""); - } - function d3_svg_lineCardinalOpen(points, tension) { - return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineCardinalClosed(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), - points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); - } - function d3_svg_lineCardinal(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineHermite(points, tangents) { - if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { - return d3_svg_lineLinear(points); - } - var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; - if (quad) { - path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; - p0 = points[1]; - pi = 2; - } - if (tangents.length > 1) { - t = tangents[1]; - p = points[pi]; - pi++; - path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - for (var i = 2; i < tangents.length; i++, pi++) { - p = points[pi]; - t = tangents[i]; - path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - } - } - if (quad) { - var lp = points[pi]; - path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; - } - return path; - } - function d3_svg_lineCardinalTangents(points, tension) { - var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; - while (++i < n) { - p0 = p1; - p1 = p2; - p2 = points[i]; - tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); - } - return tangents; - } - function d3_svg_lineBasis(points) { - if (points.length < 3) return d3_svg_lineLinear(points); - var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - points.push(points[n - 1]); - while (++i <= n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - points.pop(); - path.push("L", pi); - return path.join(""); - } - function d3_svg_lineBasisOpen(points) { - if (points.length < 4) return d3_svg_lineLinear(points); - var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; - while (++i < 3) { - pi = points[i]; - px.push(pi[0]); - py.push(pi[1]); - } - path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); - --i; - while (++i < n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBasisClosed(points) { - var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; - while (++i < 4) { - pi = points[i % n]; - px.push(pi[0]); - py.push(pi[1]); - } - path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - --i; - while (++i < m) { - pi = points[i % n]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBundle(points, tension) { - var n = points.length - 1; - if (n) { - var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; - while (++i <= n) { - p = points[i]; - t = i / n; - p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); - p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); - } - } - return d3_svg_lineBasis(points); - } - function d3_svg_lineDot4(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; - } - var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; - function d3_svg_lineBasisBezier(path, x, y) { - path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); - } - function d3_svg_lineSlope(p0, p1) { - return (p1[1] - p0[1]) / (p1[0] - p0[0]); - } - function d3_svg_lineFiniteDifferences(points) { - var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); - while (++i < j) { - m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; - } - m[i] = d; - return m; - } - function d3_svg_lineMonotoneTangents(points) { - var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; - while (++i < j) { - d = d3_svg_lineSlope(points[i], points[i + 1]); - if (abs(d) < ε) { - m[i] = m[i + 1] = 0; - } else { - a = m[i] / d; - b = m[i + 1] / d; - s = a * a + b * b; - if (s > 9) { - s = d * 3 / Math.sqrt(s); - m[i] = s * a; - m[i + 1] = s * b; - } - } - } - i = -1; - while (++i <= j) { - s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); - tangents.push([ s || 0, m[i] * s || 0 ]); - } - return tangents; - } - function d3_svg_lineMonotone(points) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); - } - d3.svg.line.radial = function() { - var line = d3_svg_line(d3_svg_lineRadial); - line.radius = line.x, delete line.x; - line.angle = line.y, delete line.y; - return line; - }; - function d3_svg_lineRadial(points) { - var point, i = -1, n = points.length, r, a; - while (++i < n) { - point = points[i]; - r = point[0]; - a = point[1] + d3_svg_arcOffset; - point[0] = r * Math.cos(a); - point[1] = r * Math.sin(a); - } - return points; - } - function d3_svg_area(projection) { - var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; - function area(data) { - var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { - return x; - } : d3_functor(x1), fy1 = y0 === y1 ? function() { - return y; - } : d3_functor(y1), x, y; - function segment() { - segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); - points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); - } else if (points0.length) { - segment(); - points0 = []; - points1 = []; - } - } - if (points0.length) segment(); - return segments.length ? segments.join("") : null; - } - area.x = function(_) { - if (!arguments.length) return x1; - x0 = x1 = _; - return area; - }; - area.x0 = function(_) { - if (!arguments.length) return x0; - x0 = _; - return area; - }; - area.x1 = function(_) { - if (!arguments.length) return x1; - x1 = _; - return area; - }; - area.y = function(_) { - if (!arguments.length) return y1; - y0 = y1 = _; - return area; - }; - area.y0 = function(_) { - if (!arguments.length) return y0; - y0 = _; - return area; - }; - area.y1 = function(_) { - if (!arguments.length) return y1; - y1 = _; - return area; - }; - area.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return area; - }; - area.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - interpolateReverse = interpolate.reverse || interpolate; - L = interpolate.closed ? "M" : "L"; - return area; - }; - area.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return area; - }; - return area; - } - d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; - d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; - d3.svg.area = function() { - return d3_svg_area(d3_identity); - }; - d3.svg.area.radial = function() { - var area = d3_svg_area(d3_svg_lineRadial); - area.radius = area.x, delete area.x; - area.innerRadius = area.x0, delete area.x0; - area.outerRadius = area.x1, delete area.x1; - area.angle = area.y, delete area.y; - area.startAngle = area.y0, delete area.y0; - area.endAngle = area.y1, delete area.y1; - return area; - }; - d3.svg.chord = function() { - var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function chord(d, i) { - var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); - return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; - } - function subgroup(self, f, d, i) { - var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; - return { - r: r, - a0: a0, - a1: a1, - p0: [ r * Math.cos(a0), r * Math.sin(a0) ], - p1: [ r * Math.cos(a1), r * Math.sin(a1) ] - }; - } - function equals(a, b) { - return a.a0 == b.a0 && a.a1 == b.a1; - } - function arc(r, p, a) { - return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; - } - function curve(r0, p0, r1, p1) { - return "Q 0,0 " + p1; - } - chord.radius = function(v) { - if (!arguments.length) return radius; - radius = d3_functor(v); - return chord; - }; - chord.source = function(v) { - if (!arguments.length) return source; - source = d3_functor(v); - return chord; - }; - chord.target = function(v) { - if (!arguments.length) return target; - target = d3_functor(v); - return chord; - }; - chord.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return chord; - }; - chord.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return chord; - }; - return chord; - }; - function d3_svg_chordRadius(d) { - return d.radius; - } - d3.svg.diagonal = function() { - var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; - function diagonal(d, i) { - var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { - x: p0.x, - y: m - }, { - x: p3.x, - y: m - }, p3 ]; - p = p.map(projection); - return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; - } - diagonal.source = function(x) { - if (!arguments.length) return source; - source = d3_functor(x); - return diagonal; - }; - diagonal.target = function(x) { - if (!arguments.length) return target; - target = d3_functor(x); - return diagonal; - }; - diagonal.projection = function(x) { - if (!arguments.length) return projection; - projection = x; - return diagonal; - }; - return diagonal; - }; - function d3_svg_diagonalProjection(d) { - return [ d.x, d.y ]; - } - d3.svg.diagonal.radial = function() { - var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; - diagonal.projection = function(x) { - return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; - }; - return diagonal; - }; - function d3_svg_diagonalRadialProjection(projection) { - return function() { - var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset; - return [ r * Math.cos(a), r * Math.sin(a) ]; - }; - } - d3.svg.symbol = function() { - var type = d3_svg_symbolType, size = d3_svg_symbolSize; - function symbol(d, i) { - return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); - } - symbol.type = function(x) { - if (!arguments.length) return type; - type = d3_functor(x); - return symbol; - }; - symbol.size = function(x) { - if (!arguments.length) return size; - size = d3_functor(x); - return symbol; - }; - return symbol; - }; - function d3_svg_symbolSize() { - return 64; - } - function d3_svg_symbolType() { - return "circle"; - } - function d3_svg_symbolCircle(size) { - var r = Math.sqrt(size / π); - return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; - } - var d3_svg_symbols = d3.map({ - circle: d3_svg_symbolCircle, - cross: function(size) { - var r = Math.sqrt(size / 5) / 2; - return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; - }, - diamond: function(size) { - var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; - return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; - }, - square: function(size) { - var r = Math.sqrt(size) / 2; - return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; - }, - "triangle-down": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; - }, - "triangle-up": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; - } - }); - d3.svg.symbolTypes = d3_svg_symbols.keys(); - var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); - function d3_transition(groups, id) { - d3_subclass(groups, d3_transitionPrototype); - groups.id = id; - return groups; - } - var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; - d3_transitionPrototype.call = d3_selectionPrototype.call; - d3_transitionPrototype.empty = d3_selectionPrototype.empty; - d3_transitionPrototype.node = d3_selectionPrototype.node; - d3_transitionPrototype.size = d3_selectionPrototype.size; - d3.transition = function(selection) { - return arguments.length ? d3_transitionInheritId ? selection.transition() : selection : d3_selectionRoot.transition(); - }; - d3.transition.prototype = d3_transitionPrototype; - d3_transitionPrototype.select = function(selector) { - var id = this.id, subgroups = [], subgroup, subnode, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - d3_transitionNode(subnode, i, id, node.__transition__[id]); - subgroup.push(subnode); - } else { - subgroup.push(null); - } - } - } - return d3_transition(subgroups, id); - }; - d3_transitionPrototype.selectAll = function(selector) { - var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - transition = node.__transition__[id]; - subnodes = selector.call(node, node.__data__, i, j); - subgroups.push(subgroup = []); - for (var k = -1, o = subnodes.length; ++k < o; ) { - if (subnode = subnodes[k]) d3_transitionNode(subnode, k, id, transition); - subgroup.push(subnode); - } - } - } - } - return d3_transition(subgroups, id); - }; - d3_transitionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); - } - } - } - return d3_transition(subgroups, this.id); - }; - d3_transitionPrototype.tween = function(name, tween) { - var id = this.id; - if (arguments.length < 2) return this.node().__transition__[id].tween.get(name); - return d3_selection_each(this, tween == null ? function(node) { - node.__transition__[id].tween.remove(name); - } : function(node) { - node.__transition__[id].tween.set(name, tween); - }); - }; - function d3_transition_tween(groups, name, value, tween) { - var id = groups.id; - return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j))); - } : (value = tween(value), function(node) { - node.__transition__[id].tween.set(name, value); - })); - } - d3_transitionPrototype.attr = function(nameNS, value) { - if (arguments.length < 2) { - for (value in nameNS) this.attr(value, nameNS[value]); - return this; - } - var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrTween(b) { - return b == null ? attrNull : (b += "", function() { - var a = this.getAttribute(name), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttribute(name, i(t)); - }); - }); - } - function attrTweenNS(b) { - return b == null ? attrNullNS : (b += "", function() { - var a = this.getAttributeNS(name.space, name.local), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttributeNS(name.space, name.local, i(t)); - }); - }); - } - return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.attrTween = function(nameNS, tween) { - var name = d3.ns.qualify(nameNS); - function attrTween(d, i) { - var f = tween.call(this, d, i, this.getAttribute(name)); - return f && function(t) { - this.setAttribute(name, f(t)); - }; - } - function attrTweenNS(d, i) { - var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); - return f && function(t) { - this.setAttributeNS(name.space, name.local, f(t)); - }; - } - return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.style(priority, name[priority], value); - return this; - } - priority = ""; - } - function styleNull() { - this.style.removeProperty(name); - } - function styleString(b) { - return b == null ? styleNull : (b += "", function() { - var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i; - return a !== b && (i = d3_interpolate(a, b), function(t) { - this.style.setProperty(name, i(t), priority); - }); - }); - } - return d3_transition_tween(this, "style." + name, value, styleString); - }; - d3_transitionPrototype.styleTween = function(name, tween, priority) { - if (arguments.length < 3) priority = ""; - function styleTween(d, i) { - var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name)); - return f && function(t) { - this.style.setProperty(name, f(t), priority); - }; - } - return this.tween("style." + name, styleTween); - }; - d3_transitionPrototype.text = function(value) { - return d3_transition_tween(this, "text", value, d3_transition_text); - }; - function d3_transition_text(b) { - if (b == null) b = ""; - return function() { - this.textContent = b; - }; - } - d3_transitionPrototype.remove = function() { - return this.each("end.transition", function() { - var p; - if (this.__transition__.count < 2 && (p = this.parentNode)) p.removeChild(this); - }); - }; - d3_transitionPrototype.ease = function(value) { - var id = this.id; - if (arguments.length < 1) return this.node().__transition__[id].ease; - if (typeof value !== "function") value = d3.ease.apply(d3, arguments); - return d3_selection_each(this, function(node) { - node.__transition__[id].ease = value; - }); - }; - d3_transitionPrototype.delay = function(value) { - var id = this.id; - if (arguments.length < 1) return this.node().__transition__[id].delay; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].delay = +value.call(node, node.__data__, i, j); - } : (value = +value, function(node) { - node.__transition__[id].delay = value; - })); - }; - d3_transitionPrototype.duration = function(value) { - var id = this.id; - if (arguments.length < 1) return this.node().__transition__[id].duration; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j)); - } : (value = Math.max(1, value), function(node) { - node.__transition__[id].duration = value; - })); - }; - d3_transitionPrototype.each = function(type, listener) { - var id = this.id; - if (arguments.length < 2) { - var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; - d3_transitionInheritId = id; - d3_selection_each(this, function(node, i, j) { - d3_transitionInherit = node.__transition__[id]; - type.call(node, node.__data__, i, j); - }); - d3_transitionInherit = inherit; - d3_transitionInheritId = inheritId; - } else { - d3_selection_each(this, function(node) { - var transition = node.__transition__[id]; - (transition.event || (transition.event = d3.dispatch("start", "end"))).on(type, listener); - }); - } - return this; - }; - d3_transitionPrototype.transition = function() { - var id0 = this.id, id1 = ++d3_transitionId, subgroups = [], subgroup, group, node, transition; - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if (node = group[i]) { - transition = Object.create(node.__transition__[id0]); - transition.delay += transition.duration; - d3_transitionNode(node, i, id1, transition); - } - subgroup.push(node); - } - } - return d3_transition(subgroups, id1); - }; - function d3_transitionNode(node, i, id, inherit) { - var lock = node.__transition__ || (node.__transition__ = { - active: 0, - count: 0 - }), transition = lock[id]; - if (!transition) { - var time = inherit.time; - transition = lock[id] = { - tween: new d3_Map(), - time: time, - ease: inherit.ease, - delay: inherit.delay, - duration: inherit.duration - }; - ++lock.count; - d3.timer(function(elapsed) { - var d = node.__data__, ease = transition.ease, delay = transition.delay, duration = transition.duration, timer = d3_timer_active, tweened = []; - timer.t = delay + time; - if (delay <= elapsed) return start(elapsed - delay); - timer.c = start; - function start(elapsed) { - if (lock.active > id) return stop(); - lock.active = id; - transition.event && transition.event.start.call(node, d, i); - transition.tween.forEach(function(key, value) { - if (value = value.call(node, d, i)) { - tweened.push(value); - } - }); - d3.timer(function() { - timer.c = tick(elapsed || 1) ? d3_true : tick; - return 1; - }, 0, time); - } - function tick(elapsed) { - if (lock.active !== id) return stop(); - var t = elapsed / duration, e = ease(t), n = tweened.length; - while (n > 0) { - tweened[--n].call(node, e); - } - if (t >= 1) { - transition.event && transition.event.end.call(node, d, i); - return stop(); - } - } - function stop() { - if (--lock.count) delete lock[id]; else delete node.__transition__; - return 1; - } - }, 0, time); - } - } - d3.svg.axis = function() { - var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; - function axis(g) { - g.each(function() { - var g = d3.select(this); - var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy(); - var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickTransform; - var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), - d3.transition(path)); - tickEnter.append("line"); - tickEnter.append("text"); - var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"); - switch (orient) { - case "bottom": - { - tickTransform = d3_svg_axisX; - lineEnter.attr("y2", innerTickSize); - textEnter.attr("y", Math.max(innerTickSize, 0) + tickPadding); - lineUpdate.attr("x2", 0).attr("y2", innerTickSize); - textUpdate.attr("x", 0).attr("y", Math.max(innerTickSize, 0) + tickPadding); - text.attr("dy", ".71em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize); - break; - } - - case "top": - { - tickTransform = d3_svg_axisX; - lineEnter.attr("y2", -innerTickSize); - textEnter.attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); - lineUpdate.attr("x2", 0).attr("y2", -innerTickSize); - textUpdate.attr("x", 0).attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); - text.attr("dy", "0em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize); - break; - } - - case "left": - { - tickTransform = d3_svg_axisY; - lineEnter.attr("x2", -innerTickSize); - textEnter.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)); - lineUpdate.attr("x2", -innerTickSize).attr("y2", 0); - textUpdate.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "end"); - pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize); - break; - } - - case "right": - { - tickTransform = d3_svg_axisY; - lineEnter.attr("x2", innerTickSize); - textEnter.attr("x", Math.max(innerTickSize, 0) + tickPadding); - lineUpdate.attr("x2", innerTickSize).attr("y2", 0); - textUpdate.attr("x", Math.max(innerTickSize, 0) + tickPadding).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "start"); - pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize); - break; - } - } - if (scale1.rangeBand) { - var x = scale1, dx = x.rangeBand() / 2; - scale0 = scale1 = function(d) { - return x(d) + dx; - }; - } else if (scale0.rangeBand) { - scale0 = scale1; - } else { - tickExit.call(tickTransform, scale1); - } - tickEnter.call(tickTransform, scale0); - tickUpdate.call(tickTransform, scale1); - }); - } - axis.scale = function(x) { - if (!arguments.length) return scale; - scale = x; - return axis; - }; - axis.orient = function(x) { - if (!arguments.length) return orient; - orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; - return axis; - }; - axis.ticks = function() { - if (!arguments.length) return tickArguments_; - tickArguments_ = arguments; - return axis; - }; - axis.tickValues = function(x) { - if (!arguments.length) return tickValues; - tickValues = x; - return axis; - }; - axis.tickFormat = function(x) { - if (!arguments.length) return tickFormat_; - tickFormat_ = x; - return axis; - }; - axis.tickSize = function(x) { - var n = arguments.length; - if (!n) return innerTickSize; - innerTickSize = +x; - outerTickSize = +arguments[n - 1]; - return axis; - }; - axis.innerTickSize = function(x) { - if (!arguments.length) return innerTickSize; - innerTickSize = +x; - return axis; - }; - axis.outerTickSize = function(x) { - if (!arguments.length) return outerTickSize; - outerTickSize = +x; - return axis; - }; - axis.tickPadding = function(x) { - if (!arguments.length) return tickPadding; - tickPadding = +x; - return axis; - }; - axis.tickSubdivide = function() { - return arguments.length && axis; - }; - return axis; - }; - var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { - top: 1, - right: 1, - bottom: 1, - left: 1 - }; - function d3_svg_axisX(selection, x) { - selection.attr("transform", function(d) { - return "translate(" + x(d) + ",0)"; - }); - } - function d3_svg_axisY(selection, y) { - selection.attr("transform", function(d) { - return "translate(0," + y(d) + ")"; - }); - } - d3.svg.brush = function() { - var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; - function brush(g) { - g.each(function() { - var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); - var background = g.selectAll(".background").data([ 0 ]); - background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); - g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); - var resize = g.selectAll(".resize").data(resizes, d3_identity); - resize.exit().remove(); - resize.enter().append("g").attr("class", function(d) { - return "resize " + d; - }).style("cursor", function(d) { - return d3_svg_brushCursor[d]; - }).append("rect").attr("x", function(d) { - return /[ew]$/.test(d) ? -3 : null; - }).attr("y", function(d) { - return /^[ns]/.test(d) ? -3 : null; - }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); - resize.style("display", brush.empty() ? "none" : null); - var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; - if (x) { - range = d3_scaleRange(x); - backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); - redrawX(gUpdate); - } - if (y) { - range = d3_scaleRange(y); - backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); - redrawY(gUpdate); - } - redraw(gUpdate); - }); - } - brush.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), extent1 = { - x: xExtent, - y: yExtent, - i: xExtentDomain, - j: yExtentDomain - }, extent0 = this.__chart__ || extent1; - this.__chart__ = extent1; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.brush", function() { - xExtentDomain = extent0.i; - yExtentDomain = extent0.j; - xExtent = extent0.x; - yExtent = extent0.y; - event_({ - type: "brushstart" - }); - }).tween("brush:brush", function() { - var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); - xExtentDomain = yExtentDomain = null; - return function(t) { - xExtent = extent1.x = xi(t); - yExtent = extent1.y = yi(t); - event_({ - type: "brush", - mode: "resize" - }); - }; - }).each("end.brush", function() { - xExtentDomain = extent1.i; - yExtentDomain = extent1.j; - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - }); - } else { - event_({ - type: "brushstart" - }); - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - } - }); - }; - function redraw(g) { - g.selectAll(".resize").attr("transform", function(d) { - return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; - }); - } - function redrawX(g) { - g.select(".extent").attr("x", xExtent[0]); - g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); - } - function redrawY(g) { - g.select(".extent").attr("y", yExtent[0]); - g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); - } - function brushstart() { - var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(), center, origin = d3.mouse(target), offset; - var w = d3.select(d3_window).on("keydown.brush", keydown).on("keyup.brush", keyup); - if (d3.event.changedTouches) { - w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); - } else { - w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); - } - g.interrupt().selectAll("*").interrupt(); - if (dragging) { - origin[0] = xExtent[0] - origin[0]; - origin[1] = yExtent[0] - origin[1]; - } else if (resizing) { - var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); - offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; - origin[0] = xExtent[ex]; - origin[1] = yExtent[ey]; - } else if (d3.event.altKey) center = origin.slice(); - g.style("pointer-events", "none").selectAll(".resize").style("display", null); - d3.select("body").style("cursor", eventTarget.style("cursor")); - event_({ - type: "brushstart" - }); - brushmove(); - function keydown() { - if (d3.event.keyCode == 32) { - if (!dragging) { - center = null; - origin[0] -= xExtent[1]; - origin[1] -= yExtent[1]; - dragging = 2; - } - d3_eventPreventDefault(); - } - } - function keyup() { - if (d3.event.keyCode == 32 && dragging == 2) { - origin[0] += xExtent[1]; - origin[1] += yExtent[1]; - dragging = 0; - d3_eventPreventDefault(); - } - } - function brushmove() { - var point = d3.mouse(target), moved = false; - if (offset) { - point[0] += offset[0]; - point[1] += offset[1]; - } - if (!dragging) { - if (d3.event.altKey) { - if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; - origin[0] = xExtent[+(point[0] < center[0])]; - origin[1] = yExtent[+(point[1] < center[1])]; - } else center = null; - } - if (resizingX && move1(point, x, 0)) { - redrawX(g); - moved = true; - } - if (resizingY && move1(point, y, 1)) { - redrawY(g); - moved = true; - } - if (moved) { - redraw(g); - event_({ - type: "brush", - mode: dragging ? "move" : "resize" - }); - } - } - function move1(point, scale, i) { - var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; - if (dragging) { - r0 -= position; - r1 -= size + position; - } - min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; - if (dragging) { - max = (min += position) + size; - } else { - if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); - if (position < min) { - max = min; - min = position; - } else { - max = position; - } - } - if (extent[0] != min || extent[1] != max) { - if (i) yExtentDomain = null; else xExtentDomain = null; - extent[0] = min; - extent[1] = max; - return true; - } - } - function brushend() { - brushmove(); - g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); - d3.select("body").style("cursor", null); - w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); - dragRestore(); - event_({ - type: "brushend" - }); - } - } - brush.x = function(z) { - if (!arguments.length) return x; - x = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.y = function(z) { - if (!arguments.length) return y; - y = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.clamp = function(z) { - if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; - if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; - return brush; - }; - brush.extent = function(z) { - var x0, x1, y0, y1, t; - if (!arguments.length) { - if (x) { - if (xExtentDomain) { - x0 = xExtentDomain[0], x1 = xExtentDomain[1]; - } else { - x0 = xExtent[0], x1 = xExtent[1]; - if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - } - } - if (y) { - if (yExtentDomain) { - y0 = yExtentDomain[0], y1 = yExtentDomain[1]; - } else { - y0 = yExtent[0], y1 = yExtent[1]; - if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - } - } - return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; - } - if (x) { - x0 = z[0], x1 = z[1]; - if (y) x0 = x0[0], x1 = x1[0]; - xExtentDomain = [ x0, x1 ]; - if (x.invert) x0 = x(x0), x1 = x(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; - } - if (y) { - y0 = z[0], y1 = z[1]; - if (x) y0 = y0[1], y1 = y1[1]; - yExtentDomain = [ y0, y1 ]; - if (y.invert) y0 = y(y0), y1 = y(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; - } - return brush; - }; - brush.clear = function() { - if (!brush.empty()) { - xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; - xExtentDomain = yExtentDomain = null; - } - return brush; - }; - brush.empty = function() { - return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; - }; - return d3.rebind(brush, event, "on"); - }; - var d3_svg_brushCursor = { - n: "ns-resize", - e: "ew-resize", - s: "ns-resize", - w: "ew-resize", - nw: "nwse-resize", - ne: "nesw-resize", - se: "nwse-resize", - sw: "nesw-resize" - }; - var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; - var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat; - var d3_time_formatUtc = d3_time_format.utc; - var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); - d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; - function d3_time_formatIsoNative(date) { - return date.toISOString(); - } - d3_time_formatIsoNative.parse = function(string) { - var date = new Date(string); - return isNaN(date) ? null : date; - }; - d3_time_formatIsoNative.toString = d3_time_formatIso.toString; - d3_time.second = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 1e3) * 1e3); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 1e3); - }, function(date) { - return date.getSeconds(); - }); - d3_time.seconds = d3_time.second.range; - d3_time.seconds.utc = d3_time.second.utc.range; - d3_time.minute = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 6e4) * 6e4); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 6e4); - }, function(date) { - return date.getMinutes(); - }); - d3_time.minutes = d3_time.minute.range; - d3_time.minutes.utc = d3_time.minute.utc.range; - d3_time.hour = d3_time_interval(function(date) { - var timezone = date.getTimezoneOffset() / 60; - return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 36e5); - }, function(date) { - return date.getHours(); - }); - d3_time.hours = d3_time.hour.range; - d3_time.hours.utc = d3_time.hour.utc.range; - d3_time.month = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setDate(1); - return date; - }, function(date, offset) { - date.setMonth(date.getMonth() + offset); - }, function(date) { - return date.getMonth(); - }); - d3_time.months = d3_time.month.range; - d3_time.months.utc = d3_time.month.utc.range; - function d3_time_scale(linear, methods, format) { - function scale(x) { - return linear(x); - } - scale.invert = function(x) { - return d3_time_scaleDate(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(d3_time_scaleDate); - linear.domain(x); - return scale; - }; - function tickMethod(extent, count) { - var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); - return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { - return d / 31536e6; - }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; - } - scale.nice = function(interval, skip) { - var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); - if (method) interval = method[0], skip = method[1]; - function skipped(date) { - return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; - } - return scale.domain(d3_scale_nice(domain, skip > 1 ? { - floor: function(date) { - while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); - return date; - }, - ceil: function(date) { - while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); - return date; - } - } : interval)); - }; - scale.ticks = function(interval, skip) { - var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { - range: interval - }, skip ]; - if (method) interval = method[0], skip = method[1]; - return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); - }; - scale.tickFormat = function() { - return format; - }; - scale.copy = function() { - return d3_time_scale(linear.copy(), methods, format); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_time_scaleDate(t) { - return new Date(t); - } - var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; - var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; - var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) { - return d.getMilliseconds(); - } ], [ ":%S", function(d) { - return d.getSeconds(); - } ], [ "%I:%M", function(d) { - return d.getMinutes(); - } ], [ "%I %p", function(d) { - return d.getHours(); - } ], [ "%a %d", function(d) { - return d.getDay() && d.getDate() != 1; - } ], [ "%b %d", function(d) { - return d.getDate() != 1; - } ], [ "%B", function(d) { - return d.getMonth(); - } ], [ "%Y", d3_true ] ]); - var d3_time_scaleMilliseconds = { - range: function(start, stop, step) { - return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate); - }, - floor: d3_identity, - ceil: d3_identity - }; - d3_time_scaleLocalMethods.year = d3_time.year; - d3_time.scale = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); - }; - var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) { - return [ m[0].utc, m[1] ]; - }); - var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) { - return d.getUTCMilliseconds(); - } ], [ ":%S", function(d) { - return d.getUTCSeconds(); - } ], [ "%I:%M", function(d) { - return d.getUTCMinutes(); - } ], [ "%I %p", function(d) { - return d.getUTCHours(); - } ], [ "%a %d", function(d) { - return d.getUTCDay() && d.getUTCDate() != 1; - } ], [ "%b %d", function(d) { - return d.getUTCDate() != 1; - } ], [ "%B", function(d) { - return d.getUTCMonth(); - } ], [ "%Y", d3_true ] ]); - d3_time_scaleUtcMethods.year = d3_time.year.utc; - d3_time.scale.utc = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat); - }; - d3.text = d3_xhrType(function(request) { - return request.responseText; - }); - d3.json = function(url, callback) { - return d3_xhr(url, "application/json", d3_json, callback); - }; - function d3_json(request) { - return JSON.parse(request.responseText); - } - d3.html = function(url, callback) { - throw "disallowed by chromium security"; - return d3_xhr(url, "text/html", d3_html, callback); - }; - function d3_html(request) { - throw "disallowed by chromium security"; - var range = d3_document.createRange(); - range.selectNode(d3_document.body); - return range.createContextualFragment(request.responseText); - } - d3.xml = d3_xhrType(function(request) { - return request.responseXML; - }); - if (typeof define === "function" && define.amd) { - define(d3); - } else if (typeof module === "object" && module.exports) { - module.exports = d3; - } else { - this.d3 = d3; - } -}(); \ No newline at end of file
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 1342087..efb04c55 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -30546,7 +30546,6 @@ <int value="1820317896" label="NTPShowGoogleGInOmnibox:disabled"/> <int value="1820451991" label="enable-offline-auto-reload"/> <int value="1821723343" label="disable-saml-signin"/> - <int value="1823102966" label="disable-ipc-flooding-protection"/> <int value="1825940786" label="ChromeHomePromo:disabled"/> <int value="1827369558" label="AndroidPayIntegrationV1:disabled"/> <int value="1828660283" label="enable-webfonts-intervention-trigger"/> @@ -49397,6 +49396,7 @@ <int value="6" label="Sync was paused"/> <int value="7" label="User turned off sync data type"/> <int value="8" label="User turned off on-by-default privacy setting"/> + <int value="9" label="User has a custom passphrase for their sync account"/> </enum> <enum name="UnifiedConsentRevokeReason">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 73b8466..9ad3e616 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -9173,7 +9173,9 @@ <summary> The percentage of time between a BeginMainFrame and paint results commit in - Blink that is used for committing paint results to the compositor. + Blink that is used for committing paint results to the compositor. The + reported value is an average over the time since the previous record: 30 + seconds unless the frame is disposed of. </summary> </histogram> @@ -9183,7 +9185,9 @@ <summary> The percentage of time between a BeginMainFrame and paint results commit in - Blink that is used for computing Compositing. + Blink that is used for computing Compositing. The reported value is an + average over the time since the previous record: 30 seconds unless the frame + is disposed of. </summary> </histogram> @@ -9195,7 +9199,9 @@ <summary> The time between each paint results commit used in computing forced style recalc and layouts for this document and ancestors as a percentage of the - Blink local frame lifecycle update time. + Blink local frame lifecycle update time. The reported value is an average + over the time since the previous record: 30 seconds unless the frame is + disposed of. </summary> </histogram> @@ -9205,7 +9211,9 @@ <summary> The percentage of time between a BeginMainFrame and paint results commit in - Blink that is used for computing Intersection Observations. + Blink that is used for computing Intersection Observations. The reported + value is an average over the time since the previous record: 30 seconds + unless the frame is disposed of. </summary> </histogram> @@ -9215,7 +9223,9 @@ <summary> The percentage of time between a BeginMainFrame and paint results commit in - Blink that is used for computing Paint. + Blink that is used for computing Paint. The reported value is an average + over the time since the previous record: 30 seconds unless the frame is + disposed of. </summary> </histogram> @@ -9225,7 +9235,9 @@ <summary> The percentage of time between a BeginMainFrame and paint results commit in - Blink that is used for computing PrePaint. + Blink that is used for computing PrePaint. The reported value is an average + over the time since the previous record: 30 seconds unless the frame is + disposed of. </summary> </histogram> @@ -9235,7 +9247,9 @@ <summary> The percentage of time between a BeginMainFrame and paint results commit in - Blink that is used for computing Style and Layout. + Blink that is used for computing Style and Layout. The reported value is an + average over the time since the previous record: 30 seconds unless the frame + is disposed of. </summary> </histogram>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 21dc50d..9e19611c 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -1769,6 +1769,12 @@ be zero. This score is taken from MediaEngagementService. </summary> </metric> + <metric name="Playbacks.AudioContextTotal"> + <summary> + The total number of significant media playbacks on this origin that came + from WebAudio / AudioContext. + </summary> + </metric> <metric name="Playbacks.Delta"> <summary> The number of significant media playbacks on this origin during this @@ -1777,6 +1783,12 @@ 200x140px, is not muted, is playing, etc. </summary> </metric> + <metric name="Playbacks.MediaElementTotal"> + <summary> + The total number of significant media playbacks on this origin that came + from media elements. + </summary> + </metric> <metric name="Playbacks.SecondsSinceLast"> <summary> The number of seconds between significant media playback on the last visit
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index 4f8b027..5425e0c5 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -43,7 +43,7 @@ rasterize_and_record_micro.partial_invalidation,"vmpstr@chromium.org, wkorman@chromium.org",Internals>Compositing>Rasterization,, rasterize_and_record_micro.top_25,"vmpstr@chromium.org, wkorman@chromium.org",Internals>Compositing>Rasterization,, rendering.desktop,"sadrul@chromium.org, vmiura@chromium.org",Internals>GPU>Metrics,https://bit.ly/rendering-benchmarks,"gpu_rasterization,image_decoding,key_desktop_move,maps,required_webgl,top_real_world_desktop,tough_animation,tough_canvas,tough_compositor,tough_filters,tough_image_decode,tough_path_rendering,tough_pinch_zoom,tough_scheduling,tough_scrolling,tough_texture_upload,tough_webgl,use_fake_camera_device" -rendering.mobile,"sadrul@chromium.org, vmiura@chromium.org",Internals>GPU>Metrics,https://bit.ly/rendering-benchmarks,"fastpath,gpu_rasterization,image_decoding,key_hit_test,key_idle_power,key_noop,key_silk,maps,motionmark,pathological_mobile_sites,polymer,required_webgl,simple_mobile_sites,sync_scroll,top_real_world_desktop,top_real_world_mobile,tough_animation,tough_canvas,tough_compositor,tough_filters,tough_image_decode,tough_path_rendering,tough_scheduling,tough_scrolling,tough_texture_upload,tough_webgl,use_fake_camera_device" +rendering.mobile,"sadrul@chromium.org, vmiura@chromium.org",Internals>GPU>Metrics,https://bit.ly/rendering-benchmarks,"fastpath,gpu_rasterization,image_decoding,key_hit_test,key_idle_power,key_noop,key_silk,maps,motionmark,pathological_mobile_sites,polymer,required_webgl,simple_mobile_sites,top_real_world_desktop,top_real_world_mobile,tough_animation,tough_canvas,tough_compositor,tough_filters,tough_image_decode,tough_path_rendering,tough_scheduling,tough_scrolling,tough_texture_upload,tough_webgl,use_fake_camera_device" resource_sizes,"agrieve@chromium.org, rnephew@chromium.org, perezju@chromium.org",,, sizes (linux),thestig@chromium.org,,, sizes (mac),tapted@chromium.org,,,
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 0ea5bbc9..b94853c 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -185,11 +185,8 @@ crbug.com/338838 [ All ] rendering.mobile/basic_stream [ Skip ] crbug.com/338838 [ All ] rendering.mobile/basic_stream [ Skip ] crbug.com/873013 [ Android_Webview ] rendering.mobile/yahoo_answers_mobile_2018 [ Skip ] -crbug.com/873014 [ Android_Webview ] rendering.mobile/yahoo_answers_mobile_sync_scroll_2018 [ Skip ] crbug.com/874935 [ Nexus_5X ] rendering.mobile/yahoo_answers_mobile_2018 [ Skip ] -crbug.com/874935 [ Nexus_5X ] rendering.mobile/yahoo_answers_mobile_sync_scroll_2018 [ Skip ] crbug.com/865400 [ Pixel_2 ] rendering.mobile/yahoo_answers_mobile_2018 [ Skip ] -crbug.com/865400 [ Pixel_2 ] rendering.mobile/yahoo_answers_mobile_sync_scroll_2018 [ Skip ] # Benchmark: rasterize_and_record_micro.top_25 crbug.com/764543 [ All ] rasterize_and_record_micro.top_25/file://static_top_25/wikipedia.html [ Skip ]
diff --git a/tools/perf/page_sets/data/rendering_mobile.json b/tools/perf/page_sets/data/rendering_mobile.json index 78fdb2b..9de2edd 100644 --- a/tools/perf/page_sets/data/rendering_mobile.json +++ b/tools/perf/page_sets/data/rendering_mobile.json
@@ -15,18 +15,12 @@ "amazon_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "amazon_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "analog_clock_svg": { "DEFAULT": "rendering_mobile_002.wprgo" }, "androidpolice_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "androidpolice_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "animometer_webgl": { "DEFAULT": "rendering_mobile_026.wprgo" }, @@ -39,18 +33,12 @@ "baidu_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "baidu_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "basic_stream": { "DEFAULT": "rendering_mobile_019.wprgo" }, "bing_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "bing_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "blob": { "DEFAULT": "rendering_mobile_026.wprgo" }, @@ -63,15 +51,9 @@ "blogspot_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "blogspot_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "boingboing_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "boingboing_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "booking.com_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, @@ -81,18 +63,12 @@ "booking.com_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "booking.com_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "camera_to_webgl": { "DEFAULT": "rendering_mobile_026.wprgo" }, "capitolvolkswagen_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "capitolvolkswagen_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "card_expansion": { "DEFAULT": "rendering_mobile_020.wprgo" }, @@ -129,18 +105,12 @@ "cnn_article_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "cnn_article_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "cnn_desktop_gpu_raster_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, "cnn_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "cnn_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "cnn_pathological_2018": { "DEFAULT": "rendering_mobile_025.wprgo" }, @@ -156,15 +126,9 @@ "deviantart_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "deviantart_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "digg_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "digg_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "dynamic_cube_map": { "DEFAULT": "rendering_mobile_026.wprgo" }, @@ -180,9 +144,6 @@ "ebay_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "ebay_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "ebay_scroll_2018": { "DEFAULT": "rendering_mobile_016.wprgo" }, @@ -198,9 +159,6 @@ "espn_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "espn_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "espn_pathological_2018": { "DEFAULT": "rendering_mobile_025.wprgo" }, @@ -213,9 +171,6 @@ "facebook_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "facebook_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "famo_us_twitter_demo": { "DEFAULT": "rendering_mobile_019.wprgo" }, @@ -228,9 +183,6 @@ "forecast.io_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "forecast.io_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "geo_apis": { "DEFAULT": "rendering_mobile_004.wprgo" }, @@ -261,18 +213,12 @@ "google_image_search_mobile_2018": { "DEFAULT": "rendering_mobile_015.wprgo" }, - "google_image_search_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_015.wprgo" - }, "google_news_ios": { "DEFAULT": "rendering_mobile_019.wprgo" }, "google_news_mobile_2018": { "DEFAULT": "rendering_mobile_013.wprgo" }, - "google_news_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_013.wprgo" - }, "google_plus_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, @@ -282,9 +228,6 @@ "google_plus_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "google_plus_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "google_web_search_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, @@ -294,15 +237,9 @@ "google_web_search_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "google_web_search_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "gsp.ro_mobile_2018": { "DEFAULT": "rendering_mobile_014.wprgo" }, - "gsp.ro_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_014.wprgo" - }, "guardian_pathological_2018": { "DEFAULT": "rendering_mobile_025.wprgo" }, @@ -357,9 +294,6 @@ "linkedin_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "linkedin_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "linkedin_pathological_2018": { "DEFAULT": "rendering_mobile_025.wprgo" }, @@ -411,9 +345,6 @@ "mlb_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "mlb_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "mobile_news_sandbox": { "DEFAULT": "rendering_mobile_019.wprgo" }, @@ -504,9 +435,6 @@ "nytimes_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "nytimes_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "nytimes_scroll_2018": { "DEFAULT": "rendering_mobile_016.wprgo" }, @@ -555,9 +483,6 @@ "pinterest_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "pinterest_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "polymer_topeka": { "DEFAULT": "rendering_mobile_024.wprgo" }, @@ -567,9 +492,6 @@ "reddit_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "reddit_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "runway": { "DEFAULT": "rendering_mobile_004.wprgo" }, @@ -579,15 +501,9 @@ "sfgate_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "sfgate_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "slashdot_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "slashdot_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "smash_cat": { "DEFAULT": "rendering_mobile_004.wprgo" }, @@ -612,21 +528,12 @@ "techcrunch_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "techcrunch_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "theverge_article_mobile_2018": { "DEFAULT": "rendering_mobile_012.wprgo" }, - "theverge_article_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_012.wprgo" - }, "theverge_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "theverge_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "twitch_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, @@ -642,15 +549,9 @@ "twitter_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "twitter_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "usatoday_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "usatoday_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "vertical_expansion": { "DEFAULT": "rendering_mobile_020.wprgo" }, @@ -660,18 +561,12 @@ "wikipedia_delayed_scroll_start_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "wikipedia_delayed_scroll_start_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "wikipedia_desktop_gpu_raster_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, "wikipedia_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "wikipedia_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "wordpress_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, @@ -681,30 +576,18 @@ "wordpress_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "wordpress_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "worldjournal_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "worldjournal_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "wow_wiki_pathological_2018": { "DEFAULT": "rendering_mobile_025.wprgo" }, "wowwiki_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "wowwiki_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "wsj_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "wsj_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "yahoo_answers_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, @@ -714,9 +597,6 @@ "yahoo_answers_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "yahoo_answers_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "yahoo_news_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, @@ -726,9 +606,6 @@ "yahoo_news_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "yahoo_news_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "yahoo_sports_2018": { "DEFAULT": "rendering_mobile_000.wprgo" }, @@ -747,9 +624,6 @@ "youtube_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "youtube_mobile_sync_scroll_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" - }, "zdnet_pathological_2018": { "DEFAULT": "rendering_mobile_025.wprgo" },
diff --git a/tools/perf/page_sets/data/system_health_desktop.json b/tools/perf/page_sets/data/system_health_desktop.json index 3247a7d..43818ae3 100644 --- a/tools/perf/page_sets/data/system_health_desktop.json +++ b/tools/perf/page_sets/data/system_health_desktop.json
@@ -27,6 +27,9 @@ "browse:news:flipboard": { "DEFAULT": "system_health_desktop_021.wprgo" }, + "browse:news:flipboard:2018": { + "DEFAULT": "system_health_desktop_4c82ac641b.wprgo" + }, "browse:news:hackernews": { "DEFAULT": "system_health_desktop_014.wprgo" }, @@ -42,6 +45,9 @@ "browse:news:reddit": { "DEFAULT": "system_health_desktop_016.wprgo" }, + "browse:news:reddit:2018": { + "DEFAULT": "system_health_desktop_907087980d.wprgo" + }, "browse:search:google": { "DEFAULT": "system_health_desktop_037.wprgo" },
diff --git a/tools/perf/page_sets/data/system_health_desktop_095d91e4f1.wprgo.sha1 b/tools/perf/page_sets/data/system_health_desktop_095d91e4f1.wprgo.sha1 new file mode 100644 index 0000000..f233030 --- /dev/null +++ b/tools/perf/page_sets/data/system_health_desktop_095d91e4f1.wprgo.sha1
@@ -0,0 +1 @@ +095d91e4f10176ea40eced02a9e656a5e131e3c8 \ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_desktop_4c82ac641b.wprgo.sha1 b/tools/perf/page_sets/data/system_health_desktop_4c82ac641b.wprgo.sha1 new file mode 100644 index 0000000..1e66b65e --- /dev/null +++ b/tools/perf/page_sets/data/system_health_desktop_4c82ac641b.wprgo.sha1
@@ -0,0 +1 @@ +4c82ac641b02b0a49a57c608bf03fd98cecb5866 \ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_desktop_907087980d.wprgo.sha1 b/tools/perf/page_sets/data/system_health_desktop_907087980d.wprgo.sha1 new file mode 100644 index 0000000..0ce0ee73 --- /dev/null +++ b/tools/perf/page_sets/data/system_health_desktop_907087980d.wprgo.sha1
@@ -0,0 +1 @@ +907087980d52d972104ce9b71ab50d7a8b6a52e0 \ No newline at end of file
diff --git a/tools/perf/page_sets/rendering/rendering_stories.py b/tools/perf/page_sets/rendering/rendering_stories.py index fada5cb..3c387178 100644 --- a/tools/perf/page_sets/rendering/rendering_stories.py +++ b/tools/perf/page_sets/rendering/rendering_stories.py
@@ -69,17 +69,6 @@ if (platform == platforms.MOBILE and story_class.TAGS and - story_tags.SYNC_SCROLL in story_class.TAGS): - self.AddStory(story_class( - page_set=self, - shared_page_state_class=shared_page_state_class, - name_suffix='_sync_scroll', - extra_browser_args=required_args + [ - '--disable-threaded-scrolling', - ])) - - if (platform == platforms.MOBILE and - story_class.TAGS and story_tags.IMAGE_DECODING in story_class.TAGS): self.AddStory(story_class( page_set=self,
diff --git a/tools/perf/page_sets/rendering/story_tags.py b/tools/perf/page_sets/rendering/story_tags.py index 01cd09fca..c3cab812 100644 --- a/tools/perf/page_sets/rendering/story_tags.py +++ b/tools/perf/page_sets/rendering/story_tags.py
@@ -13,8 +13,6 @@ GPU_RASTERIZATION = Tag( 'gpu_rasterization', 'Story tests performance with GPU rasterization.') -SYNC_SCROLL = Tag( - 'sync_scroll', 'Story tests rendering with synchronous scrolling.') FASTPATH = Tag( 'fastpath', 'Fast path stories.') REQUIRED_WEBGL = Tag(
diff --git a/tools/perf/page_sets/rendering/top_real_world_mobile.py b/tools/perf/page_sets/rendering/top_real_world_mobile.py index 143baa7..0789aa5 100644 --- a/tools/perf/page_sets/rendering/top_real_world_mobile.py +++ b/tools/perf/page_sets/rendering/top_real_world_mobile.py
@@ -11,7 +11,7 @@ class TopRealWorldMobilePage(rendering_story.RenderingStory): ABSTRACT_STORY = True - TAGS = [story_tags.SYNC_SCROLL, story_tags.TOP_REAL_WORLD_MOBILE] + TAGS = [story_tags.TOP_REAL_WORLD_MOBILE] SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY def __init__(self,
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py index 71bb2bf..b5886e05 100644 --- a/tools/perf/page_sets/system_health/browsing_stories.py +++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -178,6 +178,15 @@ TAGS = [story_tags.YEAR_2016] +class FlipboardDesktopStory2018(_ArticleBrowsingStory): + NAME = 'browse:news:flipboard:2018' + URL = 'https://flipboard.com/explore' + IS_SINGLE_PAGE_APP = True + ITEM_SELECTOR = '.cover-image' + SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY + TAGS = [story_tags.YEAR_2018] + + class HackerNewsDesktopStory(_ArticleBrowsingStory): NAME = 'browse:news:hackernews' URL = 'https://news.ycombinator.com' @@ -238,6 +247,16 @@ TAGS = [story_tags.YEAR_2016] +class RedditDesktopStory2018(_ArticleBrowsingStory): + """The top website in http://www.alexa.com/topsites/category/News""" + NAME = 'browse:news:reddit:2018' + URL = 'https://www.reddit.com/r/news/top/?sort=top&t=week' + IS_SINGLE_PAGE_APP = True + ITEM_SELECTOR = 'article' + SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY + TAGS = [story_tags.YEAR_2018] + + class RedditMobileStory(_ArticleBrowsingStory): """The top website in http://www.alexa.com/topsites/category/News""" NAME = 'browse:news:reddit'
diff --git a/ui/android/java/src/org/chromium/ui/ContactsPickerListener.java b/ui/android/java/src/org/chromium/ui/ContactsPickerListener.java index 52c15242..ed573c5 100644 --- a/ui/android/java/src/org/chromium/ui/ContactsPickerListener.java +++ b/ui/android/java/src/org/chromium/ui/ContactsPickerListener.java
@@ -14,6 +14,8 @@ enum ContactsPickerAction { CANCEL, CONTACTS_SELECTED, + SELECT_ALL, + UNDO_SELECT_ALL, } /**
diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java index 33cff06f4..90654cf 100644 --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
@@ -440,6 +440,10 @@ case CONTACTS_SELECTED: onFileNotSelected(); break; + + case SELECT_ALL: + case UNDO_SELECT_ALL: + break; } }
diff --git a/ui/aura/mus/client_surface_embedder.cc b/ui/aura/mus/client_surface_embedder.cc index 6ce87d0..340eef1 100644 --- a/ui/aura/mus/client_surface_embedder.cc +++ b/ui/aura/mus/client_surface_embedder.cc
@@ -43,6 +43,10 @@ false /* stretch_content_to_fill_bounds */); } +bool ClientSurfaceEmbedder::HasPrimarySurfaceId() const { + return surface_layer_owner_->layer()->GetPrimarySurfaceId() != nullptr; +} + void ClientSurfaceEmbedder::SetFallbackSurfaceInfo( const viz::SurfaceInfo& surface_info) { fallback_surface_info_ = surface_info;
diff --git a/ui/aura/mus/client_surface_embedder.h b/ui/aura/mus/client_surface_embedder.h index 724a0825..bcf1ce1 100644 --- a/ui/aura/mus/client_surface_embedder.h +++ b/ui/aura/mus/client_surface_embedder.h
@@ -37,6 +37,8 @@ // on the provided |surface_id|. void SetPrimarySurfaceId(const viz::SurfaceId& surface_id); + bool HasPrimarySurfaceId() const; + // Sets the fallback SurfaceInfo of the surface layer. The clip layer is not // updated. void SetFallbackSurfaceInfo(const viz::SurfaceInfo& surface_info);
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc index 5678ce1..82d494c4 100644 --- a/ui/aura/mus/window_port_mus.cc +++ b/ui/aura/mus/window_port_mus.cc
@@ -464,6 +464,12 @@ embedded_client_local_surface_id); local_surface_id_ = parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId(); + UpdatePrimarySurfaceId(); + + // OnWindowMusBoundsChanged() triggers notifying the server of the new + // LocalSurfaceId. + window_tree_client_->OnWindowMusBoundsChanged(this, window_->bounds(), + window_->bounds()); } const viz::LocalSurfaceId& WindowPortMus::GetLocalSurfaceId() { @@ -660,12 +666,6 @@ primary_surface_id_ = viz::SurfaceId(window_->GetFrameSinkId(), local_surface_id_); - UpdateClientSurfaceEmbedder(); -} - -void WindowPortMus::UpdateClientSurfaceEmbedder() { - if (!window_->IsEmbeddingClient()) - return; if (!client_surface_embedder_) { client_surface_embedder_ = std::make_unique<ClientSurfaceEmbedder>(
diff --git a/ui/aura/mus/window_port_mus.h b/ui/aura/mus/window_port_mus.h index c56b0db..428b05a2 100644 --- a/ui/aura/mus/window_port_mus.h +++ b/ui/aura/mus/window_port_mus.h
@@ -297,7 +297,6 @@ void UnregisterFrameSinkId(const viz::FrameSinkId& frame_sink_id) override; void UpdatePrimarySurfaceId(); - void UpdateClientSurfaceEmbedder(); WindowTreeClient* window_tree_client_;
diff --git a/ui/aura/mus/window_port_mus_unittest.cc b/ui/aura/mus/window_port_mus_unittest.cc index fa492c8..fe616b2d 100644 --- a/ui/aura/mus/window_port_mus_unittest.cc +++ b/ui/aura/mus/window_port_mus_unittest.cc
@@ -9,6 +9,7 @@ #include "ui/aura/mus/client_surface_embedder.h" #include "ui/aura/test/aura_mus_test_base.h" #include "ui/aura/test/aura_test_base.h" +#include "ui/aura/test/mus/test_window_tree.h" #include "ui/aura/test/mus/window_port_mus_test_helper.h" #include "ui/aura/window.h" #include "ui/base/ui_base_features.h" @@ -60,4 +61,46 @@ EXPECT_EQ(local_surface_id, primary_surface_id.local_surface_id()); } +TEST_F(WindowPortMusTest, + UpdateLocalSurfaceIdFromEmbeddedClientUpdateClientSurfaceEmbedder) { + Window window(nullptr); + window.Init(ui::LAYER_NOT_DRAWN); + window.set_owned_by_parent(false); + window.SetBounds(gfx::Rect(300, 300)); + // Simulate an embedding. + window.SetEmbedFrameSinkId(viz::FrameSinkId(0, 1)); + root_window()->AddChild(&window); + + // AckAllChanges() so that can verify a bounds change happens from + // UpdateLocalSurfaceIdFromEmbeddedClient(). + window_tree()->AckAllChanges(); + + // Update the LocalSurfaceId. + viz::LocalSurfaceId current_id = window.GetSurfaceId().local_surface_id(); + ASSERT_TRUE(current_id.is_valid()); + viz::ParentLocalSurfaceIdAllocator* parent_allocator = + WindowPortMusTestHelper(&window).GetParentLocalSurfaceIdAllocator(); + parent_allocator->Reset(current_id); + viz::LocalSurfaceId updated_id = parent_allocator->GenerateId(); + ASSERT_TRUE(updated_id.is_valid()); + EXPECT_NE(updated_id, current_id); + window.UpdateLocalSurfaceIdFromEmbeddedClient(updated_id); + + // Updating the LocalSurfaceId should propagate to the ClientSurfaceEmbedder. + auto* window_mus = WindowPortMus::Get(&window); + ASSERT_TRUE(window_mus); + ASSERT_TRUE(window_mus->client_surface_embedder()); + EXPECT_EQ(updated_id, window_mus->client_surface_embedder() + ->GetPrimarySurfaceIdForTesting() + .local_surface_id()); + + // The server is notified of a bounds change, so that it sees the new + // LocalSurfaceId. + ASSERT_EQ(1u, + window_tree()->GetChangeCountForType(WindowTreeChangeType::BOUNDS)); + ASSERT_TRUE(window_tree()->last_local_surface_id()); + EXPECT_EQ(window_mus->server_id(), window_tree()->window_id()); + EXPECT_EQ(updated_id, *(window_tree()->last_local_surface_id())); +} + } // namespace aura
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index ffca8b77..9a5c9e6b 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -284,6 +284,11 @@ WindowMus* window, const viz::FrameSinkId& frame_sink_id) { tree_->AttachFrameSinkId(window->server_id(), frame_sink_id); + + // Call OnWindowMusBoundsChanged() to force allocation of a LocalSurfaceId as + // well as notifying the server of the LocalSurfaceId. + const gfx::Rect bounds = window->GetWindow()->bounds(); + OnWindowMusBoundsChanged(window, bounds, bounds); } void WindowTreeClient::UnregisterFrameSinkId(WindowMus* window) {
diff --git a/ui/aura/test/mus/window_port_mus_test_helper.cc b/ui/aura/test/mus/window_port_mus_test_helper.cc index 98652a1..55d8002 100644 --- a/ui/aura/test/mus/window_port_mus_test_helper.cc +++ b/ui/aura/test/mus/window_port_mus_test_helper.cc
@@ -29,4 +29,9 @@ return window_port_mus_->local_layer_tree_frame_sink_; } +viz::ParentLocalSurfaceIdAllocator* +WindowPortMusTestHelper::GetParentLocalSurfaceIdAllocator() { + return &(window_port_mus_->parent_local_surface_id_allocator_); +} + } // namespace aura
diff --git a/ui/aura/test/mus/window_port_mus_test_helper.h b/ui/aura/test/mus/window_port_mus_test_helper.h index 860c763..5076c80 100644 --- a/ui/aura/test/mus/window_port_mus_test_helper.h +++ b/ui/aura/test/mus/window_port_mus_test_helper.h
@@ -14,6 +14,10 @@ class LayerTreeFrameSink; } +namespace viz { +class ParentLocalSurfaceIdAllocator; +} + namespace aura { class Window; @@ -28,6 +32,8 @@ base::WeakPtr<cc::LayerTreeFrameSink> GetFrameSink(); + viz::ParentLocalSurfaceIdAllocator* GetParentLocalSurfaceIdAllocator(); + private: static uint32_t next_client_id_;
diff --git a/ui/events/blink/blink_features.cc b/ui/events/blink/blink_features.cc index 46384f2..a88686a 100644 --- a/ui/events/blink/blink_features.cc +++ b/ui/events/blink/blink_features.cc
@@ -19,4 +19,7 @@ const base::Feature kNoHoverAfterLayoutChange{ "NoHoverAfterLayoutChange", base::FEATURE_DISABLED_BY_DEFAULT}; + +const base::Feature kNoHoverDuringScroll{"NoHoverDuringScroll", + base::FEATURE_DISABLED_BY_DEFAULT}; }
diff --git a/ui/events/blink/blink_features.h b/ui/events/blink/blink_features.h index 7a82663..c7ee6ef 100644 --- a/ui/events/blink/blink_features.h +++ b/ui/events/blink/blink_features.h
@@ -20,8 +20,15 @@ // the native platforms. crbug.com/450631 extern const base::Feature kSendMouseLeaveEvents; -// Do not update hover after the layout is changed. +// When enabled, this feature prevents Blink from changing the hover state and +// dispatching mouse enter/exit events for elements under the mouse after the +// layout under the mouse cursor is changed. extern const base::Feature kNoHoverAfterLayoutChange; + +// When enabled, this feature prevents Blink from changing the hover state and +// dispatching mouse enter/exit events for elements under the mouse as the page +// is scrolled. +extern const base::Feature kNoHoverDuringScroll; } #endif // UI_EVENTS_BLINK_BLINK_FEATURES_H_
diff --git a/ui/wm/test/wm_test_helper.cc b/ui/wm/test/wm_test_helper.cc index 709f4df..613ecff 100644 --- a/ui/wm/test/wm_test_helper.cc +++ b/ui/wm/test/wm_test_helper.cc
@@ -100,7 +100,10 @@ if (running_in_ws_process) { // Spin message loop to wait for displays when WindowService runs in the // same process to avoid deadlock. - display_wait_loop_.Run(); + display_wait_loop_ = std::make_unique<base::RunLoop>( + base::RunLoop::Type::kNestableTasksAllowed); + display_wait_loop_->Run(); + display_wait_loop_.reset(); // Bind to test_ws so that it could be shutdown at the right time. connector->BindInterface(test_ws::mojom::kServiceName, &test_ws_); @@ -142,7 +145,8 @@ int64_t primary_display_id, int64_t internal_display_id, int64_t display_id_for_new_windows) { - display_wait_loop_.Quit(); + if (display_wait_loop_) + display_wait_loop_->Quit(); } } // namespace wm
diff --git a/ui/wm/test/wm_test_helper.h b/ui/wm/test/wm_test_helper.h index 0ffd7d595..c56ebe5 100644 --- a/ui/wm/test/wm_test_helper.h +++ b/ui/wm/test/wm_test_helper.h
@@ -98,7 +98,7 @@ std::unique_ptr<aura::client::FocusClient> focus_client_; // Loop to wait for |host_| gets embedded under mus. - base::RunLoop display_wait_loop_; + std::unique_ptr<base::RunLoop> display_wait_loop_; test_ws::mojom::TestWsPtr test_ws_;