diff --git a/DEPS b/DEPS
index 9c94833..abbff73a 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # 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': 'c2d2c94fd4960b69e0ea915b9e862f16bea778cb',
+  'v8_revision': 'c2021812f3c6f6a74107a160d36614fbb837924e',
   # 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.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'b0acf6c12b290c7dcbb54b389f7120c580a8e39a',
+  'catapult_revision': '44b022b2a09508ec025ae76a26308e89deb2cf69',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -235,7 +235,7 @@
     Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'beaccf9aa08e8e5dbd06235d60150bbe0e14ce98', # commit position 19024
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '2048bc47c23b16f614fd6ab680b6faa0cf02a2f4', # commit position 19063
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
@@ -1205,7 +1205,7 @@
       'action': [
         'python',
         'src/build/fuchsia/update_sdk.py',
-        '8b1076a14d3e31dd3e569b44ddb49e49e0799baf',
+        '06ab789730c8f0749bda7eb4fd1e7988eccc38e0',
       ],
     },
   ],
diff --git a/android_webview/browser/aw_web_contents_view_delegate.cc b/android_webview/browser/aw_web_contents_view_delegate.cc
index 7319b41..8d239b8 100644
--- a/android_webview/browser/aw_web_contents_view_delegate.cc
+++ b/android_webview/browser/aw_web_contents_view_delegate.cc
@@ -6,6 +6,7 @@
 
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/context_menu_params.h"
+#include "ui/gfx/color_space.h"
 
 namespace android_webview {
 
@@ -30,4 +31,13 @@
   return NULL;
 }
 
+void AwWebContentsViewDelegate::OverrideDisplayColorSpace(
+    gfx::ColorSpace* color_space) {
+  // TODO(ccameron): WebViews that are embedded in WCG windows will want to
+  // override the display color space to gfx::ColorSpace::CreateExtendedSRGB().
+  // This situation is not yet detected.
+  // https://crbug.com/735658
+  *color_space = gfx::ColorSpace::CreateSRGB();
+}
+
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_web_contents_view_delegate.h b/android_webview/browser/aw_web_contents_view_delegate.h
index 8ef322c..da935c0 100644
--- a/android_webview/browser/aw_web_contents_view_delegate.h
+++ b/android_webview/browser/aw_web_contents_view_delegate.h
@@ -24,6 +24,7 @@
 
   // content::WebContentsViewDelegate implementation.
   content::WebDragDestDelegate* GetDragDestDelegate() override;
+  void OverrideDisplayColorSpace(gfx::ColorSpace* color_space) override;
 
  private:
   AwWebContentsViewDelegate(content::WebContents* web_contents);
diff --git a/android_webview/browser/surfaces_instance.cc b/android_webview/browser/surfaces_instance.cc
index 2dc0589..8a6bc9d 100644
--- a/android_webview/browser/surfaces_instance.cc
+++ b/android_webview/browser/surfaces_instance.cc
@@ -81,6 +81,12 @@
       std::move(output_surface_holder), std::move(scheduler),
       std::move(texture_mailbox_deleter));
   display_->Initialize(this, frame_sink_manager_->surface_manager());
+  // TODO(ccameron): WebViews that are embedded in WCG windows will want to
+  // specify gfx::ColorSpace::CreateExtendedSRGB(). This situation is not yet
+  // detected.
+  // https://crbug.com/735658
+  gfx::ColorSpace display_color_space = gfx::ColorSpace::CreateSRGB();
+  display_->SetColorSpace(display_color_space, display_color_space);
   frame_sink_manager_->RegisterBeginFrameSource(begin_frame_source_.get(),
                                                 frame_sink_id_);
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java
index 23dbe08..45aa5f2 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java
@@ -361,8 +361,9 @@
 
         @Override
         public long skip(long n) throws IOException {
-            if (n < 0)
+            if (n < 0) {
                 throw new IOException("skipping negative number of bytes");
+            }
             return 0;
         }
     }
diff --git a/ash/accelerators/accelerator_commands_unittest.cc b/ash/accelerators/accelerator_commands_unittest.cc
index 2e38152..d7d0ba7 100644
--- a/ash/accelerators/accelerator_commands_unittest.cc
+++ b/ash/accelerators/accelerator_commands_unittest.cc
@@ -21,7 +21,7 @@
 namespace ash {
 namespace accelerators {
 
-typedef test::AshTestBase AcceleratorCommandsTest;
+using AcceleratorCommandsTest = AshTestBase;
 
 TEST_F(AcceleratorCommandsTest, ToggleMinimized) {
   std::unique_ptr<aura::Window> window1(
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc
index dd96cae..5f7e460 100644
--- a/ash/accelerators/accelerator_controller_unittest.cc
+++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -206,13 +206,13 @@
 
 }  // namespace
 
-class AcceleratorControllerTest : public test::AshTestBase {
+class AcceleratorControllerTest : public AshTestBase {
  public:
   AcceleratorControllerTest() = default;
   ~AcceleratorControllerTest() override = default;
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     test_input_method_manager_ = new TestInputMethodManager;
     // Takes ownership.
     InputMethodManager::Initialize(test_input_method_manager_);
@@ -220,7 +220,7 @@
 
   void TearDown() override {
     InputMethodManager::Shutdown();
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
  protected:
@@ -685,7 +685,7 @@
   // The "Take Screenshot", "Take Partial Screenshot", volume, brightness, and
   // keyboard brightness accelerators are only defined on ChromeOS.
   {
-    test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
+    TestScreenshotDelegate* delegate = GetScreenshotDelegate();
     delegate->set_can_take_screenshot(false);
     EXPECT_TRUE(ProcessInController(
         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
@@ -991,16 +991,16 @@
   EXPECT_TRUE(input_method_manager->GetImeKeyboard()->CapsLockIsEnabled());
 }
 
-class PreferredReservedAcceleratorsTest : public test::AshTestBase {
+class PreferredReservedAcceleratorsTest : public AshTestBase {
  public:
   PreferredReservedAcceleratorsTest() {}
   ~PreferredReservedAcceleratorsTest() override {}
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override {
     AshTestBase::SetUp();
     Shell::Get()->lock_state_controller()->set_animator_for_test(
-        new test::TestSessionStateAnimator);
+        new TestSessionStateAnimator);
   }
 
  private:
@@ -1026,8 +1026,7 @@
   ui::test::EventGenerator& generator = GetEventGenerator();
 
   // Power key (reserved) should always be handled.
-  test::LockStateControllerTestApi test_api(
-      Shell::Get()->lock_state_controller());
+  LockStateControllerTestApi test_api(Shell::Get()->lock_state_controller());
   EXPECT_FALSE(test_api.is_animating_lock());
   generator.PressKey(ui::VKEY_POWER, ui::EF_NONE);
   EXPECT_TRUE(test_api.is_animating_lock());
@@ -1078,8 +1077,7 @@
   ui::test::EventGenerator& generator = GetEventGenerator();
 
   // Power key (reserved) should always be handled.
-  test::LockStateControllerTestApi test_api(
-      Shell::Get()->lock_state_controller());
+  LockStateControllerTestApi test_api(Shell::Get()->lock_state_controller());
   EXPECT_FALSE(test_api.is_animating_lock());
   generator.PressKey(ui::VKEY_POWER, ui::EF_NONE);
   EXPECT_TRUE(test_api.is_animating_lock());
@@ -1134,7 +1132,7 @@
   //
   // Screenshot
   {
-    test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
+    TestScreenshotDelegate* delegate = GetScreenshotDelegate();
     delegate->set_can_take_screenshot(false);
     EXPECT_TRUE(ProcessInController(
         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
diff --git a/ash/accelerators/accelerator_filter_unittest.cc b/ash/accelerators/accelerator_filter_unittest.cc
index 3b1897cb..4adaefa 100644
--- a/ash/accelerators/accelerator_filter_unittest.cc
+++ b/ash/accelerators/accelerator_filter_unittest.cc
@@ -30,9 +30,8 @@
 #include "ui/gfx/geometry/rect.h"
 
 namespace ash {
-namespace test {
 
-typedef AshTestBase AcceleratorFilterTest;
+using AcceleratorFilterTest = AshTestBase;
 
 // Tests if AcceleratorFilter works without a focused window.
 TEST_F(AcceleratorFilterTest, TestFilterWithoutFocus) {
@@ -209,5 +208,4 @@
   EXPECT_EQ(1u, test_app_list_presenter.toggle_count());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/accelerators/accelerator_interactive_uitest_chromeos.cc b/ash/accelerators/accelerator_interactive_uitest_chromeos.cc
index 1294cdf8..f0d7ba6 100644
--- a/ash/accelerators/accelerator_interactive_uitest_chromeos.cc
+++ b/ash/accelerators/accelerator_interactive_uitest_chromeos.cc
@@ -21,7 +21,6 @@
 #include "ui/base/test/ui_controls.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -208,5 +207,4 @@
   EXPECT_EQ(2u, test_app_list_presenter.toggle_count());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/accelerators/magnifier_key_scroller_unittest.cc b/ash/accelerators/magnifier_key_scroller_unittest.cc
index b886bf9d5..67aa815 100644
--- a/ash/accelerators/magnifier_key_scroller_unittest.cc
+++ b/ash/accelerators/magnifier_key_scroller_unittest.cc
@@ -37,7 +37,7 @@
 
 }  // namespace
 
-typedef ash::test::AshTestBase MagnifierKeyScrollerTest;
+using MagnifierKeyScrollerTest = AshTestBase;
 
 TEST_F(MagnifierKeyScrollerTest, Basic) {
   KeyEventDelegate delegate;
diff --git a/ash/accelerators/spoken_feedback_toggler_unittest.cc b/ash/accelerators/spoken_feedback_toggler_unittest.cc
index 7fa6c736..c8d470f64 100644
--- a/ash/accelerators/spoken_feedback_toggler_unittest.cc
+++ b/ash/accelerators/spoken_feedback_toggler_unittest.cc
@@ -13,7 +13,7 @@
 
 namespace ash {
 
-using SpokenFeedbackTogglerTest = test::AshTestBase;
+using SpokenFeedbackTogglerTest = AshTestBase;
 
 TEST_F(SpokenFeedbackTogglerTest, Basic) {
   SpokenFeedbackToggler::ScopedEnablerForTest scoped;
diff --git a/ash/app_list/app_list_presenter_delegate_unittest.cc b/ash/app_list/app_list_presenter_delegate_unittest.cc
index 57d448f..0ec12afd 100644
--- a/ash/app_list/app_list_presenter_delegate_unittest.cc
+++ b/ash/app_list/app_list_presenter_delegate_unittest.cc
@@ -39,7 +39,7 @@
 }
 
 void SetShelfAlignment(ShelfAlignment alignment) {
-  test::AshTestBase::GetPrimaryShelf()->SetAlignment(alignment);
+  AshTestBase::GetPrimaryShelf()->SetAlignment(alignment);
 }
 
 void EnableMaximizeMode(bool enable) {
@@ -49,7 +49,7 @@
 
 }  // namespace
 
-class AppListPresenterDelegateTest : public test::AshTestBase,
+class AppListPresenterDelegateTest : public AshTestBase,
                                      public testing::WithParamInterface<bool> {
  public:
   AppListPresenterDelegateTest() {}
@@ -78,7 +78,7 @@
   }
 
  private:
-  test::TestAppListViewPresenterImpl app_list_presenter_impl_;
+  TestAppListViewPresenterImpl app_list_presenter_impl_;
   base::test::ScopedFeatureList scoped_feature_list_;
 
   DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateTest);
@@ -87,7 +87,7 @@
 // TODO(Newcomer): Remove FullscreenAppListPresenterDelegateTest when the
 // fullscreen app list becomes default.
 class FullscreenAppListPresenterDelegateTest
-    : public test::AshTestBase,
+    : public AshTestBase,
       public testing::WithParamInterface<bool> {
  public:
   FullscreenAppListPresenterDelegateTest() {}
@@ -123,7 +123,7 @@
   }
 
  private:
-  test::TestAppListViewPresenterImpl app_list_presenter_impl_;
+  TestAppListViewPresenterImpl app_list_presenter_impl_;
   base::test::ScopedFeatureList scoped_feature_list_;
 
   DISALLOW_COPY_AND_ASSIGN(FullscreenAppListPresenterDelegateTest);
diff --git a/ash/ash_touch_exploration_manager_chromeos_unittest.cc b/ash/ash_touch_exploration_manager_chromeos_unittest.cc
index 53befb0..a50c5c249 100644
--- a/ash/ash_touch_exploration_manager_chromeos_unittest.cc
+++ b/ash/ash_touch_exploration_manager_chromeos_unittest.cc
@@ -11,7 +11,7 @@
 
 namespace ash {
 
-typedef test::AshTestBase AshTouchExplorationManagerTest;
+using AshTouchExplorationManagerTest = AshTestBase;
 
 TEST_F(AshTouchExplorationManagerTest, AdjustSound) {
   RootWindowController* controller = Shell::GetPrimaryRootWindowController();
diff --git a/ash/aura/pointer_watcher_adapter_unittest.cc b/ash/aura/pointer_watcher_adapter_unittest.cc
index 7b830d0..145e2c11 100644
--- a/ash/aura/pointer_watcher_adapter_unittest.cc
+++ b/ash/aura/pointer_watcher_adapter_unittest.cc
@@ -12,7 +12,7 @@
 
 namespace ash {
 
-using PointerWatcherAdapterTest = test::AshTestBase;
+using PointerWatcherAdapterTest = AshTestBase;
 
 enum TestPointerCaptureEvents {
   NONE = 0x01,
diff --git a/ash/autoclick/autoclick_unittest.cc b/ash/autoclick/autoclick_unittest.cc
index 0a0352da..b929b7d 100644
--- a/ash/autoclick/autoclick_unittest.cc
+++ b/ash/autoclick/autoclick_unittest.cc
@@ -56,13 +56,13 @@
   DISALLOW_COPY_AND_ASSIGN(MouseEventCapturer);
 };
 
-class AutoclickTest : public test::AshTestBase {
+class AutoclickTest : public AshTestBase {
  public:
   AutoclickTest() {}
   ~AutoclickTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     Shell::Get()->AddPreTargetHandler(&mouse_event_capturer_);
     GetAutoclickController()->SetAutoclickDelay(base::TimeDelta());
 
@@ -78,7 +78,7 @@
 
   void TearDown() override {
     Shell::Get()->RemovePreTargetHandler(&mouse_event_capturer_);
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
   void MoveMouseWithFlagsTo(int x, int y, ui::EventFlags flags) {
diff --git a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc
index ce00963e..a66527f 100644
--- a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc
+++ b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc
@@ -104,14 +104,14 @@
 
 }  // namespace
 
-class ScreenOrientationControllerTest : public test::AshTestBase {
+class ScreenOrientationControllerTest : public AshTestBase {
  public:
   ScreenOrientationControllerTest();
   ~ScreenOrientationControllerTest() override;
 
   content::ScreenOrientationDelegate* delegate() {
-    test::AshTestEnvironmentContent* test_environment_content =
-        static_cast<test::AshTestEnvironmentContent*>(
+    AshTestEnvironmentContent* test_environment_content =
+        static_cast<AshTestEnvironmentContent*>(
             ash_test_helper()->ash_test_environment());
     return test_environment_content->test_shell_content_state()
         ->screen_orientation_delegate();
@@ -125,7 +125,7 @@
   // content::BrowserContext.
   content::WebContents* CreateSecondaryWebContents();
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override;
 
  protected:
@@ -137,7 +137,7 @@
   }
 
   void SetSystemRotationLocked(bool rotation_locked) {
-    test::ScreenOrientationControllerTestApi(
+    ScreenOrientationControllerTestApi(
         Shell::Get()->screen_orientation_controller())
         .SetRotationLocked(rotation_locked);
   }
@@ -150,7 +150,7 @@
   }
 
   blink::WebScreenOrientationLockType UserLockedOrientation() const {
-    test::ScreenOrientationControllerTestApi test_api(
+    ScreenOrientationControllerTestApi test_api(
         Shell::Get()->screen_orientation_controller());
     return test_api.UserLockedOrientation();
   }
@@ -187,7 +187,7 @@
 void ScreenOrientationControllerTest::SetUp() {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       ::switches::kUseFirstDisplayAsInternal);
-  test::AshTestBase::SetUp();
+  AshTestBase::SetUp();
 }
 
 // Tests that a content::WebContents can lock rotation.
@@ -641,7 +641,7 @@
   ASSERT_NE(kNewRotation, display_manager()
                               ->GetDisplayInfo(kInternalDisplayId)
                               .GetActiveRotation());
-  test::ScreenOrientationControllerTestApi(
+  ScreenOrientationControllerTestApi(
       Shell::Get()->screen_orientation_controller())
       .SetDisplayRotation(kNewRotation,
                           display::Display::ROTATION_SOURCE_ACTIVE);
diff --git a/ash/content/keyboard_overlay/keyboard_overlay_delegate_unittest.cc b/ash/content/keyboard_overlay/keyboard_overlay_delegate_unittest.cc
index 93ef5df..3612093 100644
--- a/ash/content/keyboard_overlay/keyboard_overlay_delegate_unittest.cc
+++ b/ash/content/keyboard_overlay/keyboard_overlay_delegate_unittest.cc
@@ -17,7 +17,7 @@
 namespace ash {
 
 class KeyboardOverlayDelegateTest
-    : public test::AshTestBase,
+    : public AshTestBase,
       public testing::WithParamInterface<ShelfAlignment> {
  public:
   KeyboardOverlayDelegateTest() : shelf_alignment_(GetParam()) {}
diff --git a/ash/content/keyboard_overlay/keyboard_overlay_view_unittest.cc b/ash/content/keyboard_overlay/keyboard_overlay_view_unittest.cc
index c4e4173..8504bb80 100644
--- a/ash/content/keyboard_overlay/keyboard_overlay_view_unittest.cc
+++ b/ash/content/keyboard_overlay/keyboard_overlay_view_unittest.cc
@@ -15,7 +15,7 @@
 
 namespace ash {
 
-typedef test::AshTestBase KeyboardOverlayViewTest;
+using KeyboardOverlayViewTest = AshTestBase;
 
 bool operator==(const KeyboardOverlayView::KeyEventData& lhs,
                 const KeyboardOverlayView::KeyEventData& rhs) {
diff --git a/ash/dip_unittest.cc b/ash/dip_unittest.cc
index b3caac68..9b100bf 100644
--- a/ash/dip_unittest.cc
+++ b/ash/dip_unittest.cc
@@ -27,7 +27,7 @@
 
 namespace ash {
 
-using DIPTest = test::AshTestBase;
+using DIPTest = AshTestBase;
 
 // Test if the WM sets correct work area under different density.
 TEST_F(DIPTest, WorkArea) {
diff --git a/ash/display/cursor_window_controller.h b/ash/display/cursor_window_controller.h
index 762bd40..8521804 100644
--- a/ash/display/cursor_window_controller.h
+++ b/ash/display/cursor_window_controller.h
@@ -14,9 +14,6 @@
 #include "ui/display/display.h"
 
 namespace ash {
-namespace test {
-class MirrorWindowTestApi;
-}
 
 class CursorWindowControllerTest;
 class CursorWindowDelegate;
@@ -55,7 +52,7 @@
 
  private:
   friend class CursorWindowControllerTest;
-  friend class test::MirrorWindowTestApi;
+  friend class MirrorWindowTestApi;
 
   // Sets the container window for the cursor window controller.
   // Closes the cursor window if |container| is NULL.
diff --git a/ash/display/cursor_window_controller_unittest.cc b/ash/display/cursor_window_controller_unittest.cc
index d7460a6..1b6b6ac0 100644
--- a/ash/display/cursor_window_controller_unittest.cc
+++ b/ash/display/cursor_window_controller_unittest.cc
@@ -19,12 +19,12 @@
 
 namespace ash {
 
-class CursorWindowControllerTest : public test::AshTestBase {
+class CursorWindowControllerTest : public AshTestBase {
  public:
   CursorWindowControllerTest() {}
   ~CursorWindowControllerTest() override {}
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override {
     AshTestBase::SetUp();
     SetCursorCompositionEnabled(true);
diff --git a/ash/display/display_configuration_controller.h b/ash/display/display_configuration_controller.h
index f46b806..e17f140a4 100644
--- a/ash/display/display_configuration_controller.h
+++ b/ash/display/display_configuration_controller.h
@@ -20,10 +20,6 @@
 
 namespace ash {
 
-namespace test {
-class DisplayConfigurationControllerTestApi;
-}  // namespace test
-
 class DisplayAnimator;
 class ScreenRotationAnimator;
 
@@ -65,7 +61,7 @@
   void OnDisplayConfigurationChanged() override;
 
  protected:
-  friend class ash::test::DisplayConfigurationControllerTestApi;
+  friend class DisplayConfigurationControllerTestApi;
 
   // Allow tests to skip animations.
   void ResetAnimatorForTest();
diff --git a/ash/display/display_configuration_controller_unittest.cc b/ash/display/display_configuration_controller_unittest.cc
index 0c31c5f..fb49736 100644
--- a/ash/display/display_configuration_controller_unittest.cc
+++ b/ash/display/display_configuration_controller_unittest.cc
@@ -24,8 +24,7 @@
       .GetActiveRotation();
 }
 
-class DisplayConfigurationControllerSmoothRotationTest
-    : public test::AshTestBase {
+class DisplayConfigurationControllerSmoothRotationTest : public AshTestBase {
  public:
   DisplayConfigurationControllerSmoothRotationTest() {}
   ~DisplayConfigurationControllerSmoothRotationTest() override {}
@@ -33,7 +32,7 @@
   void SetUp() override {
     base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
         switches::kAshDisableSmoothScreenRotation, "false");
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
   }
 
  private:
@@ -42,7 +41,7 @@
 
 }  // namespace
 
-using DisplayConfigurationControllerTest = test::AshTestBase;
+using DisplayConfigurationControllerTest = AshTestBase;
 
 TEST_F(DisplayConfigurationControllerTest, OnlyHasOneAnimator) {
   // TODO(wutao): needs display_configuration_controller
@@ -51,7 +50,7 @@
     return;
 
   display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
-  test::DisplayConfigurationControllerTestApi testapi(
+  DisplayConfigurationControllerTestApi testapi(
       Shell::Get()->display_configuration_controller());
   ScreenRotationAnimator* old_screen_rotation_animator =
       testapi.GetScreenRotationAnimatorForDisplay(display.id());
@@ -76,7 +75,7 @@
   display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
   DisplayConfigurationController* controller =
       Shell::Get()->display_configuration_controller();
-  test::DisplayConfigurationControllerTestApi testapi(controller);
+  DisplayConfigurationControllerTestApi testapi(controller);
   controller->SetDisplayRotation(
       display.id(), display::Display::ROTATE_180,
       display::Display::RotationSource::ROTATION_SOURCE_USER);
diff --git a/ash/display/display_error_observer_chromeos_unittest.cc b/ash/display/display_error_observer_chromeos_unittest.cc
index 367dba7..d47ddaa 100644
--- a/ash/display/display_error_observer_chromeos_unittest.cc
+++ b/ash/display/display_error_observer_chromeos_unittest.cc
@@ -17,14 +17,14 @@
 
 namespace ash {
 
-class DisplayErrorObserverTest : public test::AshTestBase {
+class DisplayErrorObserverTest : public AshTestBase {
  protected:
   DisplayErrorObserverTest() {}
 
   ~DisplayErrorObserverTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     observer_.reset(new DisplayErrorObserver());
   }
 
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc
index 734516a..45c7d49 100644
--- a/ash/display/display_manager_unittest.cc
+++ b/ash/display/display_manager_unittest.cc
@@ -60,7 +60,7 @@
 
 }  // namespace
 
-class DisplayManagerTest : public test::AshTestBase,
+class DisplayManagerTest : public AshTestBase,
                            public display::DisplayObserver,
                            public aura::WindowObserver {
  public:
@@ -2135,7 +2135,7 @@
   }
 
  private:
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   bool changed_;
 
   DISALLOW_COPY_AND_ASSIGN(TestDisplayObserver);
@@ -2144,7 +2144,7 @@
 TEST_F(DisplayManagerTest, SoftwareMirroring) {
   UpdateDisplay("300x400,400x500");
 
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   EXPECT_EQ(nullptr, test_api.GetHost());
 
   TestDisplayObserver display_observer;
@@ -2240,7 +2240,7 @@
 TEST_F(DisplayManagerTest, SoftwareMirroringWithCompositingCursor) {
   UpdateDisplay("300x400,400x500");
 
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   EXPECT_EQ(nullptr, test_api.GetHost());
 
   display::ManagedDisplayInfo secondary_info =
@@ -2710,7 +2710,7 @@
       list, builder.Build());
 }
 
-class ScreenShutdownTest : public test::AshTestBase {
+class ScreenShutdownTest : public AshTestBase {
  public:
   ScreenShutdownTest() {}
   ~ScreenShutdownTest() override {}
@@ -2740,7 +2740,7 @@
 // A helper class that sets the display configuration and starts ash.
 // This is to make sure the font configuration happens during ash
 // initialization process.
-class FontTestHelper : public test::AshTestBase {
+class FontTestHelper : public AshTestBase {
  public:
   enum DisplayType { INTERNAL, EXTERNAL };
 
@@ -2756,7 +2756,7 @@
 
   ~FontTestHelper() override { TearDown(); }
 
-  // test::AshTestBase:
+  // AshTestBase:
   void TestBody() override { NOTREACHED(); }
 
  private:
@@ -3001,7 +3001,7 @@
       .SetFirstDisplayAsInternalDisplay();
   ScreenOrientationController* orientation_controller =
       shell->screen_orientation_controller();
-  test::ScreenOrientationControllerTestApi test_api(orientation_controller);
+  ScreenOrientationControllerTestApi test_api(orientation_controller);
   TestObserver test_observer;
   orientation_controller->AddObserver(&test_observer);
 
@@ -3178,7 +3178,7 @@
       .SetFirstDisplayAsInternalDisplay();
   ScreenOrientationController* orientation_controller =
       shell->screen_orientation_controller();
-  test::ScreenOrientationControllerTestApi test_api(orientation_controller);
+  ScreenOrientationControllerTestApi test_api(orientation_controller);
 
   aura::Window* window_a = CreateTestWindowInShellWithId(0);
   {
diff --git a/ash/display/display_util_unittest.cc b/ash/display/display_util_unittest.cc
index 33f0232a..0e42e44c 100644
--- a/ash/display/display_util_unittest.cc
+++ b/ash/display/display_util_unittest.cc
@@ -10,7 +10,7 @@
 
 namespace ash {
 
-typedef test::AshTestBase DisplayUtilTest;
+using DisplayUtilTest = AshTestBase;
 
 TEST_F(DisplayUtilTest, RotatedDisplay) {
   {
diff --git a/ash/display/extended_mouse_warp_controller.h b/ash/display/extended_mouse_warp_controller.h
index b044882..5c812aa 100644
--- a/ash/display/extended_mouse_warp_controller.h
+++ b/ash/display/extended_mouse_warp_controller.h
@@ -27,9 +27,7 @@
 }
 
 namespace ash {
-namespace test {
-class AshTestBase;
-}
+
 class SharedDisplayEdgeIndicator;
 
 // A MouseWarpController used in extended display mode.
@@ -43,7 +41,7 @@
   void SetEnabled(bool enable) override;
 
  private:
-  friend class test::AshTestBase;
+  friend class AshTestBase;
   friend class ExtendedMouseWarpControllerTest;
   FRIEND_TEST_ALL_PREFIXES(ExtendedMouseWarpControllerTest,
                            IndicatorBoundsTestThreeDisplays);
diff --git a/ash/display/extended_mouse_warp_controller_unittest.cc b/ash/display/extended_mouse_warp_controller_unittest.cc
index 9160864..7ab65d9 100644
--- a/ash/display/extended_mouse_warp_controller_unittest.cc
+++ b/ash/display/extended_mouse_warp_controller_unittest.cc
@@ -17,7 +17,7 @@
 
 namespace ash {
 
-class ExtendedMouseWarpControllerTest : public test::AshTestBase {
+class ExtendedMouseWarpControllerTest : public AshTestBase {
  public:
   ExtendedMouseWarpControllerTest() {}
   ~ExtendedMouseWarpControllerTest() override {}
diff --git a/ash/display/mirror_window_controller.h b/ash/display/mirror_window_controller.h
index c5e31d10..0f2fda7 100644
--- a/ash/display/mirror_window_controller.h
+++ b/ash/display/mirror_window_controller.h
@@ -39,10 +39,7 @@
 
 namespace ash {
 class AshWindowTreeHost;
-
-namespace test {
 class MirrorWindowTestApi;
-}
 
 // An object that copies the content of the primary root window to a
 // mirror window. This also draws a mouse cursor as the mouse cursor
@@ -81,7 +78,7 @@
   aura::Window::Windows GetAllRootWindows() const;
 
  private:
-  friend class test::MirrorWindowTestApi;
+  friend class MirrorWindowTestApi;
 
   struct MirroringHostInfo;
 
diff --git a/ash/display/mirror_window_controller_unittest.cc b/ash/display/mirror_window_controller_unittest.cc
index 156050e0..cbd1747 100644
--- a/ash/display/mirror_window_controller_unittest.cc
+++ b/ash/display/mirror_window_controller_unittest.cc
@@ -33,7 +33,7 @@
   return info;
 }
 
-class MirrorOnBootTest : public test::AshTestBase {
+class MirrorOnBootTest : public AshTestBase {
  public:
   MirrorOnBootTest() {}
   ~MirrorOnBootTest() override {}
@@ -43,19 +43,19 @@
         ::switches::kHostWindowBounds, "1+1-300x300,1+301-300x300");
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         ::switches::kEnableSoftwareMirroring);
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
   }
-  void TearDown() override { test::AshTestBase::TearDown(); }
+  void TearDown() override { AshTestBase::TearDown(); }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MirrorOnBootTest);
 };
 }
 
-typedef test::AshTestBase MirrorWindowControllerTest;
+using MirrorWindowControllerTest = AshTestBase;
 
 TEST_F(MirrorWindowControllerTest, MirrorCursorBasic) {
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   aura::test::TestWindowDelegate test_window_delegate;
   test_window_delegate.set_window_component(HTTOP);
 
@@ -101,7 +101,7 @@
 }
 
 TEST_F(MirrorWindowControllerTest, MirrorCursorRotate) {
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   aura::test::TestWindowDelegate test_window_delegate;
   test_window_delegate.set_window_component(HTTOP);
 
@@ -155,7 +155,7 @@
 // the source display's host location in the mirror root window's
 // coordinates.
 TEST_F(MirrorWindowControllerTest, MirrorCursorLocations) {
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   display_manager()->SetMultiDisplayMode(display::DisplayManager::MIRRORING);
 
   // Test with device scale factor.
@@ -206,7 +206,7 @@
       window_tree_host_manager->GetRootWindowForDisplayId(secondary_display_id);
   secondary_root_window->MoveCursorTo(gfx::Point(100, 200));
   EXPECT_EQ("300,200", env->last_mouse_location().ToString());
-  test::CursorManagerTestApi cursor_test_api(shell->cursor_manager());
+  CursorManagerTestApi cursor_test_api(shell->cursor_manager());
   EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
   EXPECT_EQ(display::Display::ROTATE_0,
             cursor_test_api.GetCurrentCursorRotation());
@@ -223,7 +223,7 @@
             cursor_test_api.GetCurrentCursorRotation());
 
   // Check mirrored cursor's location.
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   // The hot point location depends on the specific cursor.
   EXPECT_EQ(ui::CursorType::kNull, test_api.GetCurrentCursorType());
   // Rotated hot point must be (25-7, 7).
@@ -283,7 +283,7 @@
 TEST_F(MirrorOnBootTest, MirrorOnBoot) {
   EXPECT_TRUE(display_manager()->IsInMirrorMode());
   RunAllPendingInMessageLoop();
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   EXPECT_TRUE(test_api.GetHost());
 }
 
diff --git a/ash/display/mouse_cursor_event_filter.h b/ash/display/mouse_cursor_event_filter.h
index 602cde9e..ffda5d8 100644
--- a/ash/display/mouse_cursor_event_filter.h
+++ b/ash/display/mouse_cursor_event_filter.h
@@ -20,11 +20,8 @@
 }
 
 namespace ash {
-class MouseWarpController;
 
-namespace test {
-class AshTestBase;
-}
+class MouseWarpController;
 
 // An event filter that controls mouse location in extended desktop
 // environment.
@@ -50,7 +47,7 @@
   void OnMouseEvent(ui::MouseEvent* event) override;
 
  private:
-  friend class test::AshTestBase;
+  friend class AshTestBase;
   friend class ExtendedMouseWarpControllerTest;
   friend class MouseCursorEventFilterTest;
   friend class UnifiedMouseWarpControllerTest;
diff --git a/ash/display/mouse_cursor_event_filter_unittest.cc b/ash/display/mouse_cursor_event_filter_unittest.cc
index d1139c4..83566d50 100644
--- a/ash/display/mouse_cursor_event_filter_unittest.cc
+++ b/ash/display/mouse_cursor_event_filter_unittest.cc
@@ -15,7 +15,7 @@
 
 namespace ash {
 
-class MouseCursorEventFilterTest : public test::AshTestBase {
+class MouseCursorEventFilterTest : public AshTestBase {
  public:
   MouseCursorEventFilterTest() {}
   ~MouseCursorEventFilterTest() override {}
@@ -26,8 +26,8 @@
   }
 
   bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) {
-    return test::AshTestBase::TestIfMouseWarpsAt(GetEventGenerator(),
-                                                 point_in_screen);
+    return AshTestBase::TestIfMouseWarpsAt(GetEventGenerator(),
+                                           point_in_screen);
   }
 
  private:
@@ -145,7 +145,7 @@
   display_manager()->SetLayoutForCurrentDisplays(
       display::test::CreateDisplayLayout(display_manager(),
                                          display::DisplayPlacement::RIGHT, 0));
-  test::CursorManagerTestApi cursor_test_api(Shell::Get()->cursor_manager());
+  CursorManagerTestApi cursor_test_api(Shell::Get()->cursor_manager());
 
   EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
   TestIfMouseWarpsAt(gfx::Point(399, 200));
diff --git a/ash/display/resolution_notification_controller_unittest.cc b/ash/display/resolution_notification_controller_unittest.cc
index b1064f98..e29ec3fa 100644
--- a/ash/display/resolution_notification_controller_unittest.cc
+++ b/ash/display/resolution_notification_controller_unittest.cc
@@ -19,7 +19,7 @@
 
 namespace ash {
 
-class ResolutionNotificationControllerTest : public ash::test::AshTestBase {
+class ResolutionNotificationControllerTest : public AshTestBase {
  public:
   ResolutionNotificationControllerTest() : accept_count_(0) {}
 
@@ -46,7 +46,7 @@
 
  protected:
   void SetUp() override {
-    ash::test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     ResolutionNotificationController::SuppressTimerForTest();
   }
 
diff --git a/ash/display/root_window_transformers_unittest.cc b/ash/display/root_window_transformers_unittest.cc
index 667ee766..e841a807 100644
--- a/ash/display/root_window_transformers_unittest.cc
+++ b/ash/display/root_window_transformers_unittest.cc
@@ -113,7 +113,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
 };
 
-class RootWindowTransformersTest : public test::AshTestBase {
+class RootWindowTransformersTest : public AshTestBase {
  public:
   RootWindowTransformersTest() {}
   ~RootWindowTransformersTest() override {}
@@ -141,8 +141,6 @@
 
 }  // namespace
 
-// using RootWindowTransformersTest = test::AshTestBase;
-
 TEST_F(RootWindowTransformersTest, RotateAndMagnify) {
   MagnificationController* magnifier = Shell::Get()->magnification_controller();
 
@@ -406,7 +404,7 @@
 }
 
 TEST_F(RootWindowTransformersTest, LetterBoxPillarBox) {
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   display_manager()->SetMultiDisplayMode(display::DisplayManager::MIRRORING);
   UpdateDisplay("400x200,500x500");
   std::unique_ptr<RootWindowTransformer> transformer(
diff --git a/ash/display/screen_ash_unittest.cc b/ash/display/screen_ash_unittest.cc
index b89b43790..584e2001 100644
--- a/ash/display/screen_ash_unittest.cc
+++ b/ash/display/screen_ash_unittest.cc
@@ -9,7 +9,7 @@
 
 namespace ash {
 
-using ScreenAshTest = test::AshTestBase;
+using ScreenAshTest = AshTestBase;
 
 // Tests that ScreenAsh::GetWindowAtScreenPoint() returns the correct window on
 // the correct display.
diff --git a/ash/display/screen_orientation_controller_chromeos.h b/ash/display/screen_orientation_controller_chromeos.h
index 23ed91a9..2ee3628 100644
--- a/ash/display/screen_orientation_controller_chromeos.h
+++ b/ash/display/screen_orientation_controller_chromeos.h
@@ -24,9 +24,6 @@
 }
 
 namespace ash {
-namespace test {
-class ScreenOrientationControllerTestApi;
-}
 
 // Implements ChromeOS specific functionality for ScreenOrientationProvider.
 class ASH_EXPORT ScreenOrientationController
@@ -126,7 +123,7 @@
   void OnMaximizeModeEnding() override;
 
  private:
-  friend class test::ScreenOrientationControllerTestApi;
+  friend class ScreenOrientationControllerTestApi;
 
   struct LockInfo {
     LockInfo() {}
diff --git a/ash/display/screen_position_controller_unittest.cc b/ash/display/screen_position_controller_unittest.cc
index 335dcc3e..d3b4e33 100644
--- a/ash/display/screen_position_controller_unittest.cc
+++ b/ash/display/screen_position_controller_unittest.cc
@@ -22,7 +22,6 @@
 #include "ui/events/test/event_generator.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -31,7 +30,7 @@
   return test_api.screen_position_controller();
 }
 
-class ScreenPositionControllerTest : public test::AshTestBase {
+class ScreenPositionControllerTest : public AshTestBase {
  public:
   ScreenPositionControllerTest() {}
   ~ScreenPositionControllerTest() override {}
@@ -339,5 +338,4 @@
   EXPECT_TRUE(event_handler->could_convert_to_screen());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/display/unified_mouse_warp_controller.h b/ash/display/unified_mouse_warp_controller.h
index d26db4b32..3ec8911 100644
--- a/ash/display/unified_mouse_warp_controller.h
+++ b/ash/display/unified_mouse_warp_controller.h
@@ -17,10 +17,6 @@
 }
 
 namespace ash {
-namespace test {
-class AshTestBase;
-class DisplayManagerTestApi;
-}
 
 // A MouseWarpController used in unified display mode.
 class ASH_EXPORT UnifiedMouseWarpController : public MouseWarpController {
@@ -33,8 +29,8 @@
   void SetEnabled(bool enabled) override;
 
  private:
-  friend class test::AshTestBase;
-  friend class test::DisplayManagerTestApi;
+  friend class AshTestBase;
+  friend class DisplayManagerTestApi;
   friend class UnifiedMouseWarpControllerTest;
 
   void ComputeBounds();
diff --git a/ash/display/unified_mouse_warp_controller_unittest.cc b/ash/display/unified_mouse_warp_controller_unittest.cc
index 956b9b1..08de81a 100644
--- a/ash/display/unified_mouse_warp_controller_unittest.cc
+++ b/ash/display/unified_mouse_warp_controller_unittest.cc
@@ -21,13 +21,13 @@
 
 namespace ash {
 
-class UnifiedMouseWarpControllerTest : public test::AshTestBase {
+class UnifiedMouseWarpControllerTest : public AshTestBase {
  public:
   UnifiedMouseWarpControllerTest() {}
   ~UnifiedMouseWarpControllerTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     display_manager()->SetUnifiedDesktopEnabled(true);
   }
 
diff --git a/ash/display/window_tree_host_manager_unittest.cc b/ash/display/window_tree_host_manager_unittest.cc
index 46f47fa..3bac9692 100644
--- a/ash/display/window_tree_host_manager_unittest.cc
+++ b/ash/display/window_tree_host_manager_unittest.cc
@@ -178,7 +178,7 @@
 
 class TestHelper {
  public:
-  explicit TestHelper(test::AshTestBase* delegate);
+  explicit TestHelper(AshTestBase* delegate);
   ~TestHelper();
 
   void SetSecondaryDisplayLayoutAndOffset(
@@ -192,11 +192,11 @@
   float GetStoredUIScale(int64_t id);
 
  private:
-  test::AshTestBase* delegate_;  // Not owned
+  AshTestBase* delegate_;  // Not owned
   DISALLOW_COPY_AND_ASSIGN(TestHelper);
 };
 
-TestHelper::TestHelper(test::AshTestBase* delegate) : delegate_(delegate) {}
+TestHelper::TestHelper(AshTestBase* delegate) : delegate_(delegate) {}
 TestHelper::~TestHelper() {}
 
 void TestHelper::SetSecondaryDisplayLayoutAndOffset(
@@ -225,14 +225,14 @@
   return delegate_->display_manager()->GetDisplayInfo(id).GetEffectiveUIScale();
 }
 
-class WindowTreeHostManagerShutdownTest : public test::AshTestBase,
+class WindowTreeHostManagerShutdownTest : public AshTestBase,
                                           public TestHelper {
  public:
   WindowTreeHostManagerShutdownTest() : TestHelper(this) {}
   ~WindowTreeHostManagerShutdownTest() override {}
 
   void TearDown() override {
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
 
     // Make sure that primary display is accessible after shutdown.
     display::Display primary =
@@ -245,18 +245,18 @@
   DISALLOW_COPY_AND_ASSIGN(WindowTreeHostManagerShutdownTest);
 };
 
-class StartupHelper : public test::TestShellDelegate,
+class StartupHelper : public TestShellDelegate,
                       public WindowTreeHostManager::Observer {
  public:
   StartupHelper() : displays_initialized_(false) {}
   ~StartupHelper() override {}
 
-  // ash::ShellSelegate:
+  // ShellDelegate:
   void PreInit() override {
     Shell::Get()->window_tree_host_manager()->AddObserver(this);
   }
 
-  // ash::WindowTreeHostManager::Observer:
+  // WindowTreeHostManager::Observer:
   void OnDisplaysInitialized() override {
     DCHECK(!displays_initialized_);
     displays_initialized_ = true;
@@ -270,21 +270,20 @@
   DISALLOW_COPY_AND_ASSIGN(StartupHelper);
 };
 
-class WindowTreeHostManagerStartupTest : public test::AshTestBase,
-                                         public TestHelper {
+class WindowTreeHostManagerStartupTest : public AshTestBase, public TestHelper {
  public:
   WindowTreeHostManagerStartupTest()
       : TestHelper(this), startup_helper_(new StartupHelper) {}
   ~WindowTreeHostManagerStartupTest() override {}
 
-  // ash::test::AshTestBase:
+  // AshTestBase:
   void SetUp() override {
     ash_test_helper()->set_test_shell_delegate(startup_helper_);
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
   }
   void TearDown() override {
     Shell::Get()->window_tree_host_manager()->RemoveObserver(startup_helper_);
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
   const StartupHelper* startup_helper() const { return startup_helper_; }
@@ -388,7 +387,7 @@
 
 }  // namespace
 
-class WindowTreeHostManagerTest : public test::AshTestBase, public TestHelper {
+class WindowTreeHostManagerTest : public AshTestBase, public TestHelper {
  public:
   WindowTreeHostManagerTest() : TestHelper(this) {}
   ~WindowTreeHostManagerTest() override {}
@@ -1623,7 +1622,7 @@
   Shell* shell = Shell::Get();
   WindowTreeHostManager* window_tree_host_manager =
       shell->window_tree_host_manager();
-  test::CursorManagerTestApi test_api(shell->cursor_manager());
+  CursorManagerTestApi test_api(shell->cursor_manager());
 
   window_tree_host_manager->GetPrimaryRootWindow()->MoveCursorTo(
       gfx::Point(20, 50));
@@ -1647,7 +1646,7 @@
   Shell* shell = Shell::Get();
   WindowTreeHostManager* window_tree_host_manager =
       shell->window_tree_host_manager();
-  test::CursorManagerTestApi test_api(shell->cursor_manager());
+  CursorManagerTestApi test_api(shell->cursor_manager());
 
   UpdateDisplay("300x300*2/r,200x200");
   // Swap the primary display to make it possible to remove the primary display
diff --git a/ash/drag_drop/drag_drop_controller.h b/ash/drag_drop/drag_drop_controller.h
index d2d564dfb..f70d5cca7 100644
--- a/ash/drag_drop/drag_drop_controller.h
+++ b/ash/drag_drop/drag_drop_controller.h
@@ -33,10 +33,6 @@
 class DragDropTrackerDelegate;
 class DragImageView;
 
-namespace test {
-class DragDropControllerTest;
-}
-
 class ASH_EXPORT DragDropController : public aura::client::DragDropClient,
                                       public ui::EventHandler,
                                       public gfx::AnimationDelegate,
@@ -86,7 +82,7 @@
   virtual void DoDragCancel(int drag_cancel_animation_duration_ms);
 
  private:
-  friend class ash::test::DragDropControllerTest;
+  friend class DragDropControllerTest;
 
   // Overridden from gfx::AnimationDelegate:
   void AnimationEnded(const gfx::Animation* animation) override;
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index b24c57b..46dcf5b4 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -33,7 +33,6 @@
 #include "ui/views/widget/widget.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -1101,5 +1100,4 @@
   EXPECT_TRUE(drag_view->drag_done_received_);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/drag_drop/drag_drop_interactive_uitest.cc b/ash/drag_drop/drag_drop_interactive_uitest.cc
index dacca73..f24adf2 100644
--- a/ash/drag_drop/drag_drop_interactive_uitest.cc
+++ b/ash/drag_drop/drag_drop_interactive_uitest.cc
@@ -111,7 +111,7 @@
 
 }  // namespace
 
-using DragDropTest = test::AshInteractiveUITestBase;
+using DragDropTest = AshInteractiveUITestBase;
 
 // Test if the mouse gets moved properly to another display
 // during drag & drop operation.
diff --git a/ash/drag_drop/drag_drop_tracker_unittest.cc b/ash/drag_drop/drag_drop_tracker_unittest.cc
index 3cb8ec3..74f16f9 100644
--- a/ash/drag_drop/drag_drop_tracker_unittest.cc
+++ b/ash/drag_drop/drag_drop_tracker_unittest.cc
@@ -16,9 +16,8 @@
 #include "ui/events/event_utils.h"
 
 namespace ash {
-namespace test {
 
-class DragDropTrackerTest : public test::AshTestBase {
+class DragDropTrackerTest : public AshTestBase {
  public:
   void SetUp() override { AshTestBase::SetUp(); }
 
@@ -175,5 +174,4 @@
   EXPECT_EQ(original11.flags(), converted11->flags());
 }
 
-}  // namespace test
 }  // namespace aura
diff --git a/ash/drag_drop/drag_image_view_unittest.cc b/ash/drag_drop/drag_image_view_unittest.cc
index 44911a7..1fd7dd86 100644
--- a/ash/drag_drop/drag_image_view_unittest.cc
+++ b/ash/drag_drop/drag_image_view_unittest.cc
@@ -9,7 +9,6 @@
 #include "ui/base/dragdrop/drag_drop_types.h"
 
 namespace ash {
-namespace test {
 
 using DragDropImageTest = AshTestBase;
 
@@ -74,5 +73,4 @@
             drag_image_view.GetBoundsInScreen());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/extended_desktop_unittest.cc b/ash/extended_desktop_unittest.cc
index f8d42b4..6d715d8 100644
--- a/ash/extended_desktop_unittest.cc
+++ b/ash/extended_desktop_unittest.cc
@@ -133,7 +133,7 @@
 
 }  // namespace
 
-class ExtendedDesktopTest : public test::AshTestBase {
+class ExtendedDesktopTest : public AshTestBase {
  public:
   views::Widget* CreateTestWidget(const gfx::Rect& bounds) {
     return CreateTestWidgetWithParentAndContext(nullptr, CurrentContext(),
diff --git a/ash/first_run/desktop_cleaner.h b/ash/first_run/desktop_cleaner.h
index 1f0fdeb..52034c78 100644
--- a/ash/first_run/desktop_cleaner.h
+++ b/ash/first_run/desktop_cleaner.h
@@ -15,10 +15,6 @@
 class ContainerHider;
 class NotificationBlocker;
 
-namespace test {
-class FirstRunHelperTest;
-}
-
 // Class used to "clean" ash desktop, i.e. hide all windows and notifications.
 class ASH_EXPORT DesktopCleaner {
  public:
@@ -26,13 +22,14 @@
   ~DesktopCleaner();
 
  private:
+  friend class FirstRunHelperTest;
+
   // Returns the list of containers that DesctopCleaner hides.
   static std::vector<int> GetContainersToHideForTest();
 
   std::vector<std::unique_ptr<ContainerHider>> container_hiders_;
   std::unique_ptr<NotificationBlocker> notification_blocker_;
 
-  friend class ash::test::FirstRunHelperTest;
   DISALLOW_COPY_AND_ASSIGN(DesktopCleaner);
 };
 
diff --git a/ash/first_run/first_run_helper_unittest.cc b/ash/first_run/first_run_helper_unittest.cc
index feca789..67429d5 100644
--- a/ash/first_run/first_run_helper_unittest.cc
+++ b/ash/first_run/first_run_helper_unittest.cc
@@ -14,7 +14,6 @@
 #include "ui/views/window/dialog_delegate.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -141,5 +140,4 @@
   overlay_window->RemovePreTargetHandler(&handler);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/focus_cycler_unittest.cc b/ash/focus_cycler_unittest.cc
index e3edad9..4c708896 100644
--- a/ash/focus_cycler_unittest.cc
+++ b/ash/focus_cycler_unittest.cc
@@ -23,7 +23,6 @@
 #include "ui/views/widget/widget.h"
 
 namespace ash {
-namespace test {
 
 using aura::Window;
 
@@ -402,5 +401,4 @@
   EXPECT_TRUE(wm::IsActiveWindow(window.get()));
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
index 00dd3bc..3034f06 100644
--- a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
+++ b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
@@ -37,7 +37,7 @@
 
 }  // namespace
 
-class FrameCaptionButtonContainerViewTest : public ash::test::AshTestBase {
+class FrameCaptionButtonContainerViewTest : public AshTestBase {
  public:
   enum MaximizeAllowed { MAXIMIZE_ALLOWED, MAXIMIZE_DISALLOWED };
 
diff --git a/ash/frame/caption_buttons/frame_size_button_unittest.cc b/ash/frame/caption_buttons/frame_size_button_unittest.cc
index 0ca88d9..df7a0f5 100644
--- a/ash/frame/caption_buttons/frame_size_button_unittest.cc
+++ b/ash/frame/caption_buttons/frame_size_button_unittest.cc
@@ -21,7 +21,6 @@
 #include "ui/views/widget/widget_delegate.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -458,5 +457,4 @@
   EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/frame/custom_frame_view_ash_unittest.cc b/ash/frame/custom_frame_view_ash_unittest.cc
index f5b8ed8..66e514ab2 100644
--- a/ash/frame/custom_frame_view_ash_unittest.cc
+++ b/ash/frame/custom_frame_view_ash_unittest.cc
@@ -90,7 +90,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestWidgetConstraintsDelegate);
 };
 
-class CustomFrameViewAshTest : public test::AshTestBase {
+class CustomFrameViewAshTest : public AshTestBase {
  public:
   CustomFrameViewAshTest() {}
   ~CustomFrameViewAshTest() override {}
diff --git a/ash/frame/default_header_painter_unittest.cc b/ash/frame/default_header_painter_unittest.cc
index 083a8c0..ce98498 100644
--- a/ash/frame/default_header_painter_unittest.cc
+++ b/ash/frame/default_header_painter_unittest.cc
@@ -19,7 +19,7 @@
 
 namespace ash {
 
-using DefaultHeaderPainterTest = test::AshTestBase;
+using DefaultHeaderPainterTest = AshTestBase;
 
 // Ensure the title text is vertically aligned with the window icon.
 TEST_F(DefaultHeaderPainterTest, TitleIconAlignment) {
diff --git a/ash/ime/ime_controller_unittest.cc b/ash/ime/ime_controller_unittest.cc
index 9c3e38d..d1db7faf 100644
--- a/ash/ime/ime_controller_unittest.cc
+++ b/ash/ime/ime_controller_unittest.cc
@@ -93,7 +93,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestImeControllerClient);
 };
 
-using ImeControllerTest = test::AshTestBase;
+using ImeControllerTest = AshTestBase;
 
 TEST_F(ImeControllerTest, RefreshIme) {
   ImeController* controller = Shell::Get()->ime_controller();
diff --git a/ash/laser/laser_pointer_controller_unittest.cc b/ash/laser/laser_pointer_controller_unittest.cc
index b35b759..d65a6b0 100644
--- a/ash/laser/laser_pointer_controller_unittest.cc
+++ b/ash/laser/laser_pointer_controller_unittest.cc
@@ -14,7 +14,7 @@
 namespace ash {
 namespace {
 
-class LaserPointerControllerTest : public test::AshTestBase {
+class LaserPointerControllerTest : public AshTestBase {
  public:
   LaserPointerControllerTest() {}
   ~LaserPointerControllerTest() override {}
diff --git a/ash/laser/laser_pointer_points_unittest.cc b/ash/laser/laser_pointer_points_unittest.cc
index 60161e6..71897e2 100644
--- a/ash/laser/laser_pointer_points_unittest.cc
+++ b/ash/laser/laser_pointer_points_unittest.cc
@@ -12,7 +12,7 @@
 
 const int kTestPointsLifetimeSeconds = 5;
 
-class LaserPointerPointsTest : public test::AshTestBase {
+class LaserPointerPointsTest : public AshTestBase {
  public:
   LaserPointerPointsTest()
       : points_(base::TimeDelta::FromSeconds(kTestPointsLifetimeSeconds)) {}
diff --git a/ash/login/lock_screen_controller_unittest.cc b/ash/login/lock_screen_controller_unittest.cc
index 11cd15bf7..69e5e0a 100644
--- a/ash/login/lock_screen_controller_unittest.cc
+++ b/ash/login/lock_screen_controller_unittest.cc
@@ -14,7 +14,7 @@
 namespace ash {
 
 namespace {
-using LockScreenControllerTest = test::AshTestBase;
+using LockScreenControllerTest = AshTestBase;
 
 TEST_F(LockScreenControllerTest, RequestAuthentication) {
   LockScreenController* controller = Shell::Get()->lock_screen_controller();
diff --git a/ash/login/ui/login_test_base.cc b/ash/login/ui/login_test_base.cc
index a55b0a7..0b9411d2 100644
--- a/ash/login/ui/login_test_base.cc
+++ b/ash/login/ui/login_test_base.cc
@@ -72,7 +72,7 @@
     widget_ = nullptr;
   }
 
-  test::AshTestBase::TearDown();
+  AshTestBase::TearDown();
 }
 
 }  // namespace ash
\ No newline at end of file
diff --git a/ash/login/ui/login_test_base.h b/ash/login/ui/login_test_base.h
index 84652958..25574cc 100644
--- a/ash/login/ui/login_test_base.h
+++ b/ash/login/ui/login_test_base.h
@@ -19,7 +19,7 @@
 
 // Base test fixture for testing the views-based login and lock screens. This
 // class provides easy access to types which the login/lock frequently need.
-class LoginTestBase : public test::AshTestBase {
+class LoginTestBase : public AshTestBase {
  public:
   LoginTestBase();
   ~LoginTestBase() override;
@@ -39,7 +39,7 @@
 
   LoginDataDispatcher* data_dispatcher() { return &data_dispatcher_; }
 
-  // test::AshTestBase:
+  // AshTestBase:
   void TearDown() override;
 
  private:
diff --git a/ash/magnifier/magnification_controller_unittest.cc b/ash/magnifier/magnification_controller_unittest.cc
index 34d01f82..d623fd4 100644
--- a/ash/magnifier/magnification_controller_unittest.cc
+++ b/ash/magnifier/magnification_controller_unittest.cc
@@ -55,7 +55,7 @@
 
 }  // namespace
 
-class MagnificationControllerTest : public test::AshTestBase {
+class MagnificationControllerTest : public AshTestBase {
  public:
   MagnificationControllerTest() : text_input_view_(NULL) {}
   ~MagnificationControllerTest() override {}
diff --git a/ash/magnifier/partial_magnification_controller_unittest.cc b/ash/magnifier/partial_magnification_controller_unittest.cc
index b58ccf4..4da69eeda 100644
--- a/ash/magnifier/partial_magnification_controller_unittest.cc
+++ b/ash/magnifier/partial_magnification_controller_unittest.cc
@@ -35,7 +35,7 @@
   DISALLOW_ASSIGN(PartialMagnificationControllerTestApi);
 };
 
-class PartialMagnificationControllerTest : public test::AshTestBase {
+class PartialMagnificationControllerTest : public AshTestBase {
  public:
   PartialMagnificationControllerTest() {}
   ~PartialMagnificationControllerTest() override {}
diff --git a/ash/metrics/desktop_task_switch_metric_recorder_unittest.cc b/ash/metrics/desktop_task_switch_metric_recorder_unittest.cc
index 9a6b674ea..c4b4231ca 100644
--- a/ash/metrics/desktop_task_switch_metric_recorder_unittest.cc
+++ b/ash/metrics/desktop_task_switch_metric_recorder_unittest.cc
@@ -29,12 +29,12 @@
 // by the test target can be obtained through Shell::Get()->metrics() and the
 // test target is not the same instance as the one owned by the
 // UserMetricsRecorder instance.
-class DesktopTaskSwitchMetricRecorderTest : public test::AshTestBase {
+class DesktopTaskSwitchMetricRecorderTest : public AshTestBase {
  public:
   DesktopTaskSwitchMetricRecorderTest();
   ~DesktopTaskSwitchMetricRecorderTest() override;
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override;
   void TearDown() override;
 
@@ -73,7 +73,7 @@
 DesktopTaskSwitchMetricRecorderTest::~DesktopTaskSwitchMetricRecorderTest() {}
 
 void DesktopTaskSwitchMetricRecorderTest::SetUp() {
-  test::AshTestBase::SetUp();
+  AshTestBase::SetUp();
   metrics_recorder_.reset(new DesktopTaskSwitchMetricRecorder);
   user_action_tester_.reset(new base::UserActionTester);
 }
@@ -81,7 +81,7 @@
 void DesktopTaskSwitchMetricRecorderTest::TearDown() {
   user_action_tester_.reset();
   metrics_recorder_.reset();
-  test::AshTestBase::TearDown();
+  AshTestBase::TearDown();
 }
 
 void DesktopTaskSwitchMetricRecorderTest::ActiveTaskWindowWithUserInput(
@@ -259,12 +259,12 @@
 // Test fixture to test the integration of the DesktopTaskSwitchMetricsRecorder
 // class with ash::Shell environment.
 class DesktopTaskSwitchMetricRecorderWithShellIntegrationTest
-    : public test::AshTestBase {
+    : public AshTestBase {
  public:
   DesktopTaskSwitchMetricRecorderWithShellIntegrationTest();
   ~DesktopTaskSwitchMetricRecorderWithShellIntegrationTest() override;
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override;
   void TearDown() override;
 
@@ -297,13 +297,13 @@
     ~DesktopTaskSwitchMetricRecorderWithShellIntegrationTest() {}
 
 void DesktopTaskSwitchMetricRecorderWithShellIntegrationTest::SetUp() {
-  test::AshTestBase::SetUp();
+  AshTestBase::SetUp();
   user_action_tester_.reset(new base::UserActionTester);
 }
 
 void DesktopTaskSwitchMetricRecorderWithShellIntegrationTest::TearDown() {
   user_action_tester_.reset();
-  test::AshTestBase::TearDown();
+  AshTestBase::TearDown();
 }
 
 int DesktopTaskSwitchMetricRecorderWithShellIntegrationTest::GetActionCount()
diff --git a/ash/metrics/pointer_metrics_recorder_unittest.cc b/ash/metrics/pointer_metrics_recorder_unittest.cc
index ef5d9633..b2af2f9 100644
--- a/ash/metrics/pointer_metrics_recorder_unittest.cc
+++ b/ash/metrics/pointer_metrics_recorder_unittest.cc
@@ -26,12 +26,12 @@
 const char kDestinationHistogramName[] = "Event.DownEventCount.PerDestination";
 
 // Test fixture for the PointerMetricsRecorder class.
-class PointerMetricsRecorderTest : public test::AshTestBase {
+class PointerMetricsRecorderTest : public AshTestBase {
  public:
   PointerMetricsRecorderTest();
   ~PointerMetricsRecorderTest() override;
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override;
   void TearDown() override;
 
@@ -51,14 +51,14 @@
 PointerMetricsRecorderTest::~PointerMetricsRecorderTest() {}
 
 void PointerMetricsRecorderTest::SetUp() {
-  test::AshTestBase::SetUp();
+  AshTestBase::SetUp();
   pointer_metrics_recorder_.reset(new PointerMetricsRecorder());
   histogram_tester_.reset(new base::HistogramTester());
 }
 
 void PointerMetricsRecorderTest::TearDown() {
   pointer_metrics_recorder_.reset();
-  test::AshTestBase::TearDown();
+  AshTestBase::TearDown();
 }
 
 }  // namespace
diff --git a/ash/metrics/task_switch_time_tracker.h b/ash/metrics/task_switch_time_tracker.h
index 65edde31..552bffac 100644
--- a/ash/metrics/task_switch_time_tracker.h
+++ b/ash/metrics/task_switch_time_tracker.h
@@ -19,10 +19,6 @@
 
 namespace ash {
 
-namespace test {
-class TaskSwitchTimeTrackerTestAPI;
-}  // namespace test
-
 // Tracks time deltas between task switches and records them in a histogram.
 class ASH_EXPORT TaskSwitchTimeTracker {
  public:
@@ -37,9 +33,9 @@
   void OnTaskSwitch();
 
  private:
-  friend class test::TaskSwitchTimeTrackerTestAPI;
+  friend class TaskSwitchTimeTrackerTestAPI;
 
-  // Private constructor that the test::TaskSwitchTimeTrackerTestAPI can use to
+  // Private constructor that the TaskSwitchTimeTrackerTestAPI can use to
   // inject a custom |tick_clock|.
   TaskSwitchTimeTracker(const std::string& histogram_name,
                         std::unique_ptr<base::TickClock> tick_clock);
diff --git a/ash/metrics/task_switch_time_tracker_unittest.cc b/ash/metrics/task_switch_time_tracker_unittest.cc
index 3db5ef9..9b6c909 100644
--- a/ash/metrics/task_switch_time_tracker_unittest.cc
+++ b/ash/metrics/task_switch_time_tracker_unittest.cc
@@ -40,7 +40,7 @@
   std::unique_ptr<base::HistogramTester> histogram_tester_;
 
   // A Test API that wraps the test target.
-  std::unique_ptr<test::TaskSwitchTimeTrackerTestAPI> time_tracker_test_api_;
+  std::unique_ptr<TaskSwitchTimeTrackerTestAPI> time_tracker_test_api_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TaskSwitchTimeTrackerTest);
@@ -55,7 +55,7 @@
 
   histogram_tester_.reset(new base::HistogramTester());
   time_tracker_test_api_.reset(
-      new test::TaskSwitchTimeTrackerTestAPI(kHistogramName));
+      new TaskSwitchTimeTrackerTestAPI(kHistogramName));
   // The TaskSwitchTimeTracker interprets a value of base::TimeTicks() as if the
   // |last_action_time_| has not been set.
   time_tracker_test_api_->Advance(base::TimeDelta::FromMilliseconds(1));
diff --git a/ash/metrics/user_metrics_recorder.h b/ash/metrics/user_metrics_recorder.h
index 524c5c1..9cf082d 100644
--- a/ash/metrics/user_metrics_recorder.h
+++ b/ash/metrics/user_metrics_recorder.h
@@ -18,10 +18,6 @@
 class DesktopTaskSwitchMetricRecorder;
 class PointerMetricsRecorder;
 
-namespace test {
-class UserMetricsRecorderTestAPI;
-}
-
 // User Metrics Recorder provides a repeating callback (RecordPeriodicMetrics)
 // on a timer to allow recording of state data over time to the UMA records.
 // Any additional states (in ash) that require monitoring can be added to
@@ -49,7 +45,7 @@
   void OnShellShuttingDown();
 
  private:
-  friend class test::UserMetricsRecorderTestAPI;
+  friend class UserMetricsRecorderTestAPI;
 
   // Creates a UserMetricsRecorder and will only record periodic metrics if
   // |record_periodic_metrics| is true. This is used by tests that do not want
diff --git a/ash/metrics/user_metrics_recorder_unittest.cc b/ash/metrics/user_metrics_recorder_unittest.cc
index 6806eeb7..c67d5364 100644
--- a/ash/metrics/user_metrics_recorder_unittest.cc
+++ b/ash/metrics/user_metrics_recorder_unittest.cc
@@ -38,18 +38,18 @@
 
 // Test fixture for the UserMetricsRecorder class. The tests manage their own
 // session state.
-class UserMetricsRecorderTest : public test::NoSessionAshTestBase {
+class UserMetricsRecorderTest : public NoSessionAshTestBase {
  public:
   UserMetricsRecorderTest() = default;
   ~UserMetricsRecorderTest() override = default;
 
-  test::UserMetricsRecorderTestAPI& test_api() { return test_api_; }
+  UserMetricsRecorderTestAPI& test_api() { return test_api_; }
 
   base::HistogramTester& histograms() { return histograms_; }
 
  private:
   // Test API to access private members of the test target.
-  test::UserMetricsRecorderTestAPI test_api_;
+  UserMetricsRecorderTestAPI test_api_;
 
   // Histogram value verifier.
   base::HistogramTester histograms_;
@@ -72,7 +72,7 @@
   EXPECT_TRUE(test_api().IsUserInActiveDesktopEnvironment());
 
   // Environment is not active when screen is locked.
-  test::TestSessionControllerClient* client = GetSessionControllerClient();
+  TestSessionControllerClient* client = GetSessionControllerClient();
   client->SetSessionState(SessionState::LOCKED);
   ASSERT_TRUE(session->IsScreenLocked());
   EXPECT_FALSE(test_api().IsUserInActiveDesktopEnvironment());
diff --git a/ash/mus/display_synchronizer_unittest.cc b/ash/mus/display_synchronizer_unittest.cc
index 7a146e63..a727ea3e 100644
--- a/ash/mus/display_synchronizer_unittest.cc
+++ b/ash/mus/display_synchronizer_unittest.cc
@@ -14,7 +14,7 @@
 namespace ash {
 namespace mus {
 
-using DisplaySynchronizerTest = test::AshTestBase;
+using DisplaySynchronizerTest = AshTestBase;
 
 TEST_F(DisplaySynchronizerTest, ChangingWorkAreaNotifesServer) {
   aura::TestWindowManagerClient* test_window_manager_client =
diff --git a/ash/mus/non_client_frame_controller_unittest.cc b/ash/mus/non_client_frame_controller_unittest.cc
index 436e688..9222a6b 100644
--- a/ash/mus/non_client_frame_controller_unittest.cc
+++ b/ash/mus/non_client_frame_controller_unittest.cc
@@ -74,7 +74,7 @@
 
 }  // namespace
 
-class NonClientFrameControllerTest : public test::AshTestBase {
+class NonClientFrameControllerTest : public AshTestBase {
  public:
   NonClientFrameControllerTest() = default;
   ~NonClientFrameControllerTest() override = default;
@@ -83,7 +83,7 @@
     return context_factory_.GetLastCompositorFrame();
   }
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override {
     aura::Env* env = aura::Env::GetInstance();
     DCHECK(env);
diff --git a/ash/mus/top_level_window_factory_unittest.cc b/ash/mus/top_level_window_factory_unittest.cc
index 0d8de94..52082596 100644
--- a/ash/mus/top_level_window_factory_unittest.cc
+++ b/ash/mus/top_level_window_factory_unittest.cc
@@ -51,7 +51,7 @@
 
 }  // namespace
 
-using TopLevelWindowFactoryTest = test::AshTestBase;
+using TopLevelWindowFactoryTest = AshTestBase;
 
 TEST_F(TopLevelWindowFactoryTest, CreateFullscreenWindow) {
   std::unique_ptr<aura::Window> window = CreateTestWindow();
@@ -60,7 +60,7 @@
   EXPECT_EQ(root_window->bounds(), window->bounds());
 }
 
-using TopLevelWindowFactoryWmTest = test::AshTestBase;
+using TopLevelWindowFactoryWmTest = AshTestBase;
 
 TEST_F(TopLevelWindowFactoryWmTest, IsWindowShownInCorrectDisplay) {
   UpdateDisplay("400x400,400x400");
@@ -80,7 +80,7 @@
             GetDisplayId(window_secondary_display.get()));
 }
 
-using TopLevelWindowFactoryAshTest = test::AshTestBase;
+using TopLevelWindowFactoryAshTest = AshTestBase;
 
 TEST_F(TopLevelWindowFactoryAshTest, TopLevelNotShownOnCreate) {
   std::map<std::string, std::vector<uint8_t>> properties;
diff --git a/ash/mus/window_manager.h b/ash/mus/window_manager.h
index 9615c81..949968f 100644
--- a/ash/mus/window_manager.h
+++ b/ash/mus/window_manager.h
@@ -44,12 +44,8 @@
 }
 
 namespace ash {
-
-enum class Config;
-
-namespace test {
 class AshTestHelper;
-}
+enum class Config;
 
 namespace mus {
 
@@ -106,7 +102,7 @@
   display::mojom::DisplayController* GetDisplayController();
 
  private:
-  friend class test::AshTestHelper;
+  friend class ash::AshTestHelper;
 
   // Creates the Shell. This is done after the connection to mus is established.
   void CreateShell();
diff --git a/ash/mus/window_manager_application.h b/ash/mus/window_manager_application.h
index ca8a6b7..647af79f 100644
--- a/ash/mus/window_manager_application.h
+++ b/ash/mus/window_manager_application.h
@@ -38,10 +38,8 @@
 }
 
 namespace ash {
-
-namespace test {
 class AshTestHelper;
-}
+
 namespace mus {
 
 class NetworkConnectDelegateMus;
@@ -64,7 +62,7 @@
   service_manager::Connector* GetConnector();
 
  private:
-  friend class ash::test::AshTestHelper;
+  friend class ash::AshTestHelper;
 
   // If |init_network_handler| is true, chromeos::NetworkHandler is initialized.
   void InitWindowManager(
diff --git a/ash/mus/window_manager_common_unittests.cc b/ash/mus/window_manager_common_unittests.cc
index ccec34cd..98390b1 100644
--- a/ash/mus/window_manager_common_unittests.cc
+++ b/ash/mus/window_manager_common_unittests.cc
@@ -17,7 +17,7 @@
 namespace ash {
 namespace mus {
 
-using WindowManagerCommonTest = test::AshTestBase;
+using WindowManagerCommonTest = AshTestBase;
 
 TEST_F(WindowManagerCommonTest, Focus) {
   if (Shell::GetAshConfig() == Config::CLASSIC)
diff --git a/ash/mus_property_mirror_ash_unittest.cc b/ash/mus_property_mirror_ash_unittest.cc
index 64e10da9..16d1783 100644
--- a/ash/mus_property_mirror_ash_unittest.cc
+++ b/ash/mus_property_mirror_ash_unittest.cc
@@ -16,7 +16,7 @@
 
 namespace ash {
 
-using MusPropertyMirrorAshTest = test::AshTestBase;
+using MusPropertyMirrorAshTest = AshTestBase;
 
 // Ensure the property mirror can copy primitive properties between windows.
 TEST_F(MusPropertyMirrorAshTest, PrimitiveProperties) {
diff --git a/ash/perftests/ash_background_filter_blur_perftest.cc b/ash/perftests/ash_background_filter_blur_perftest.cc
index 595a9e4..0fc05d64 100644
--- a/ash/perftests/ash_background_filter_blur_perftest.cc
+++ b/ash/perftests/ash_background_filter_blur_perftest.cc
@@ -15,12 +15,12 @@
 
 // TODO(wutao): On chromeos_linux builds, the tests only run with
 // use_ozone = false.
-class AshBackgroundFilterBlurPerfTest : public test::AshTestBase {
+class AshBackgroundFilterBlurPerfTest : public AshTestBase {
  public:
   AshBackgroundFilterBlurPerfTest() : timer_(0, base::TimeDelta(), 1) {}
   ~AshBackgroundFilterBlurPerfTest() override {}
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override;
 
  protected:
diff --git a/ash/resources/vector_icons/palette_tray_icon_capture_region.1x.icon b/ash/resources/vector_icons/palette_tray_icon_capture_region.1x.icon
index 2624b588..236892b4 100644
--- a/ash/resources/vector_icons/palette_tray_icon_capture_region.1x.icon
+++ b/ash/resources/vector_icons/palette_tray_icon_capture_region.1x.icon
@@ -3,82 +3,81 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 9.97f, 8.99f,
-V_LINE_TO, 8,
-R_H_LINE_TO, -0.98f,
-R_V_LINE_TO, 0.99f,
-H_LINE_TO, 8,
-R_V_LINE_TO, 0.97f,
-R_H_LINE_TO, 0.99f,
-R_V_LINE_TO, 1,
-R_H_LINE_TO, 0.99f,
-V_LINE_TO, 9.97f,
-R_H_LINE_TO, 0.99f,
-R_V_LINE_TO, -0.98f,
-H_LINE_TO, 9.97f,
+MOVE_TO, 12.8f, 6,
+H_LINE_TO, 14,
+V_LINE_TO, 4.8f,
+R_H_LINE_TO, -1.2f,
+V_LINE_TO, 6,
 CLOSE,
-MOVE_TO, 7.02f, 6.48f,
-LINE_TO, 2, 11.5f,
+MOVE_TO, 14, 3.2f,
+R_H_LINE_TO, -1.2f,
+V_LINE_TO, 2,
+R_CUBIC_TO, 0.66f, 0, 1.2f, 0.57f, 1.2f, 1.2f,
+CLOSE,
+R_MOVE_TO, -4, 0,
+R_H_LINE_TO, 1.2f,
+V_LINE_TO, 2,
+H_LINE_TO, 10,
+R_V_LINE_TO, 1.2f,
+CLOSE,
+R_MOVE_TO, 2.8f, 5.2f,
+H_LINE_TO, 14,
+V_LINE_TO, 7.2f,
+R_H_LINE_TO, -1.2f,
+R_V_LINE_TO, 1.2f,
+CLOSE,
+R_MOVE_TO, -8, 5.6f,
+H_LINE_TO, 6,
+R_V_LINE_TO, -1.2f,
+H_LINE_TO, 4.8f,
 V_LINE_TO, 14,
-R_H_LINE_TO, 2.49f,
-R_LINE_TO, 2.5f, -2.62f,
-V_LINE_TO, 8.25f,
-R_CUBIC_TO, 0, -0.44f, 0.21f, -0.81f, 0.52f, -1.09f,
-R_LINE_TO, -0.48f, -0.68f,
 CLOSE,
-R_MOVE_TO, 2.39f, -2.4f,
-LINE_TO, 7.72f, 5.77f,
-R_LINE_TO, 1.27f, 1.23f,
-H_LINE_TO, 11.68f,
-R_LINE_TO, 2.13f, -2.29f,
-R_CUBIC_TO, 0.26f, -0.26f, 0.26f, -0.69f, 0, -0.95f,
-R_LINE_TO, -1.56f, -1.55f,
-R_CUBIC_TO, -0.26f, -0.26f, -0.69f, -0.26f, -0.94f, 0,
-R_LINE_TO, -0.94f, 0.94f,
-R_LINE_TO, -0.95f, -0.94f,
-R_CUBIC_TO, -0.25f, -0.26f, -0.69f, -0.27f, -0.95f, -0.01f,
-LINE_TO, 4.22f, 6.43f,
-R_LINE_TO, 0.93f, 0.93f,
-R_LINE_TO, 3.77f, -3.77f,
-R_LINE_TO, 0.49f, 0.49f,
+MOVE_TO, 2, 11.2f,
+R_H_LINE_TO, 1.2f,
+V_LINE_TO, 10,
+H_LINE_TO, 2,
+R_V_LINE_TO, 1.2f,
 CLOSE,
-MOVE_TO, 14, 10,
-R_H_LINE_TO, -1,
-V_LINE_TO, 9,
-R_CUBIC_TO, 0.55f, 0, 1, 0.48f, 1, 1,
+R_MOVE_TO, 5, -8,
+R_H_LINE_TO, 1.2f,
+V_LINE_TO, 2,
+H_LINE_TO, 7,
+R_V_LINE_TO, 1.2f,
 CLOSE,
-R_MOVE_TO, -2, 0,
-R_H_LINE_TO, 1,
-V_LINE_TO, 9,
-R_H_LINE_TO, -1,
-R_V_LINE_TO, 1,
+MOVE_TO, 7.2f, 14,
+R_H_LINE_TO, 1.2f,
+R_V_LINE_TO, -1.2f,
+H_LINE_TO, 7.2f,
+V_LINE_TO, 14,
 CLOSE,
-R_MOVE_TO, -1, 4,
-R_H_LINE_TO, 1,
-R_V_LINE_TO, -1,
-R_H_LINE_TO, -1,
-R_V_LINE_TO, 1,
+MOVE_TO, 2, 8.4f,
+R_H_LINE_TO, 1.2f,
+V_LINE_TO, 7.2f,
+H_LINE_TO, 2,
+R_V_LINE_TO, 1.2f,
 CLOSE,
-R_MOVE_TO, -2, -2,
-R_H_LINE_TO, 1,
-R_V_LINE_TO, -1,
-H_LINE_TO, 9,
-R_V_LINE_TO, 1,
+MOVE_TO, 3.2f, 14,
+R_CUBIC_TO, -0.66f, 0, -1.2f, -0.62f, -1.2f, -1.2f,
+R_H_LINE_TO, 1.2f,
+V_LINE_TO, 14,
 CLOSE,
-R_MOVE_TO, 1, 2,
-R_CUBIC_TO, -0.55f, 0, -1, -0.52f, -1, -1,
-R_H_LINE_TO, 1,
-R_V_LINE_TO, 1,
-CLOSE,
-R_MOVE_TO, 3, -2,
-R_H_LINE_TO, 1,
-R_V_LINE_TO, -1,
-R_H_LINE_TO, -1,
-R_V_LINE_TO, 1,
-CLOSE,
-R_MOVE_TO, 0, 2,
-R_CUBIC_TO, 0.55f, 0, 1, -0.45f, 1, -1,
-R_H_LINE_TO, -1,
-R_V_LINE_TO, 1,
+MOVE_TO, 4.2f, 3.2f,
+H_LINE_TO, 6,
+V_LINE_TO, 2,
+H_LINE_TO, 2,
+R_V_LINE_TO, 4,
+R_H_LINE_TO, 1.2f,
+R_LINE_TO, -0.01f, -1.82f,
+LINE_TO, 5, 5.92f,
+R_LINE_TO, 0.95f, -0.93f,
+MOVE_TO, 11.72f, 12.71f,
+LINE_TO, 10, 12.79f,
+V_LINE_TO, 14,
+R_H_LINE_TO, 4,
+R_V_LINE_TO, -4,
+R_H_LINE_TO, -1.2f,
+R_V_LINE_TO, 1.79f,
+R_LINE_TO, -1.8f, -1.64f,
+R_LINE_TO, -0.95f, 0.91f,
 CLOSE,
 END
diff --git a/ash/resources/vector_icons/palette_tray_icon_capture_region.icon b/ash/resources/vector_icons/palette_tray_icon_capture_region.icon
index 9b723d2..87932fe 100644
--- a/ash/resources/vector_icons/palette_tray_icon_capture_region.icon
+++ b/ash/resources/vector_icons/palette_tray_icon_capture_region.icon
@@ -3,90 +3,81 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 32,
-MOVE_TO, 26, 28,
-CUBIC_TO, 27.1f, 28, 28, 27.1f, 28, 26,
-LINE_TO, 26, 26,
-LINE_TO, 26, 28,
+MOVE_TO, 25, 12,
+R_H_LINE_TO, 3,
+V_LINE_TO, 9,
+R_H_LINE_TO, -3,
+R_V_LINE_TO, 3,
 CLOSE,
-MOVE_TO, 26, 25,
-LINE_TO, 28, 25,
-LINE_TO, 28, 23,
-LINE_TO, 26, 23,
-LINE_TO, 26, 25,
+R_MOVE_TO, 3, -5,
+R_H_LINE_TO, -3,
+V_LINE_TO, 4,
+R_CUBIC_TO, 1.65f, 0, 3, 1.44f, 3, 3,
 CLOSE,
-MOVE_TO, 19, 28,
-CUBIC_TO, 17.9f, 28, 17, 26.96f, 17, 26,
-LINE_TO, 19, 26,
-LINE_TO, 19, 28,
+R_MOVE_TO, -8, 0,
+R_H_LINE_TO, 3,
+V_LINE_TO, 4,
+R_H_LINE_TO, -3,
+R_V_LINE_TO, 3,
 CLOSE,
-MOVE_TO, 17, 23.98f,
-LINE_TO, 19, 23.98f,
-LINE_TO, 19, 21.98f,
-LINE_TO, 17, 21.98f,
-LINE_TO, 17, 23.98f,
+R_MOVE_TO, 5, 11,
+R_H_LINE_TO, 3,
+R_V_LINE_TO, -3,
+R_H_LINE_TO, -3,
+R_V_LINE_TO, 3,
 CLOSE,
-MOVE_TO, 21, 28,
-LINE_TO, 23, 28,
-LINE_TO, 23, 26,
-LINE_TO, 21, 26,
-LINE_TO, 21, 28,
+MOVE_TO, 10, 28,
+R_H_LINE_TO, 3,
+R_V_LINE_TO, -3,
+R_H_LINE_TO, -3,
+R_V_LINE_TO, 3,
 CLOSE,
-MOVE_TO, 26, 22,
-LINE_TO, 28, 22,
-LINE_TO, 28, 20,
-LINE_TO, 26, 20,
-LINE_TO, 26, 22,
+R_MOVE_TO, -6, -6,
+R_H_LINE_TO, 3,
+R_V_LINE_TO, -3,
+H_LINE_TO, 4,
+R_V_LINE_TO, 3,
 CLOSE,
-MOVE_TO, 23, 19,
-LINE_TO, 25, 19,
-LINE_TO, 25, 17,
-LINE_TO, 23, 17,
-LINE_TO, 23, 19,
+MOVE_TO, 14, 7,
+R_H_LINE_TO, 3,
+V_LINE_TO, 4,
+R_H_LINE_TO, -3,
+R_V_LINE_TO, 3,
 CLOSE,
-MOVE_TO, 28, 19,
-LINE_TO, 26.03f, 19,
-LINE_TO, 26.03f, 17.03f,
-CUBIC_TO, 27.11f, 17.03f, 28, 17.98f, 28, 19,
-LINE_TO, 28, 19,
+R_MOVE_TO, 1, 21,
+R_H_LINE_TO, 3,
+R_V_LINE_TO, -3,
+R_H_LINE_TO, -3,
+R_V_LINE_TO, 3,
 CLOSE,
-MOVE_TO, 19, 17,
-LINE_TO, 19, 15,
-LINE_TO, 17, 15,
-LINE_TO, 17, 17,
-LINE_TO, 15, 17,
-LINE_TO, 15, 18.97f,
-LINE_TO, 17, 18.97f,
-LINE_TO, 17, 21,
-LINE_TO, 19, 21,
-LINE_TO, 19, 19,
-LINE_TO, 21, 19,
-LINE_TO, 21, 17,
-LINE_TO, 19, 17,
+MOVE_TO, 4, 17,
+R_H_LINE_TO, 3,
+R_V_LINE_TO, -3,
+H_LINE_TO, 4,
+R_V_LINE_TO, 3,
 CLOSE,
-MOVE_TO, 14.04f, 12.96f,
-LINE_TO, 4, 23,
-LINE_TO, 4, 28,
-LINE_TO, 8.98f, 28,
-LINE_TO, 13.97f, 22.76f,
-LINE_TO, 13.97f, 16.5f,
-CUBIC_TO, 13.97f, 15.62f, 14.39f, 14.88f, 15, 14.33f,
-LINE_TO, 14.04f, 12.96f,
+R_MOVE_TO, 3, 11,
+R_CUBIC_TO, -1.65f, 0, -3, -1.56f, -3, -3,
+R_H_LINE_TO, 3,
+R_V_LINE_TO, 3,
 CLOSE,
-MOVE_TO, 18.82f, 8.16f,
-LINE_TO, 15.45f, 11.53f,
-LINE_TO, 17.99f, 13.99f,
-LINE_TO, 18.82f, 13.99f,
-LINE_TO, 23.35f, 13.99f,
-LINE_TO, 27.62f, 9.4f,
-CUBIC_TO, 28.14f, 8.88f, 28.12f, 8.02f, 27.6f, 7.5f,
-LINE_TO, 24.48f, 4.4f,
-CUBIC_TO, 23.96f, 3.88f, 23.11f, 3.88f, 22.61f, 4.4f,
-LINE_TO, 20.71f, 6.28f,
-LINE_TO, 18.82f, 4.4f,
-CUBIC_TO, 18.31f, 3.88f, 17.45f, 3.86f, 16.93f, 4.38f,
-LINE_TO, 8.44f, 12.86f,
-LINE_TO, 10.3f, 14.73f,
-LINE_TO, 17.85f, 7.18f,
-LINE_TO, 18.82f, 8.16f,
+MOVE_TO, 8.4f, 6.4f,
+H_LINE_TO, 12,
+V_LINE_TO, 4,
+H_LINE_TO, 4,
+R_V_LINE_TO, 8,
+R_H_LINE_TO, 2.4f,
+R_LINE_TO, -0.01f, -3.64f,
+LINE_TO, 10, 11.84f,
+R_LINE_TO, 1.91f, -1.86f,
+MOVE_TO, 23.44f, 25.43f,
+R_LINE_TO, -3.44f, 0.16f,
+V_LINE_TO, 28,
+R_H_LINE_TO, 8,
+R_V_LINE_TO, -8,
+R_H_LINE_TO, -2.4f,
+R_V_LINE_TO, 3.59f,
+R_LINE_TO, -3.6f, -3.28f,
+R_LINE_TO, -1.91f, 1.83f,
 CLOSE,
 END
diff --git a/ash/resources/vector_icons/palette_tray_icon_default.1x.icon b/ash/resources/vector_icons/palette_tray_icon_default.1x.icon
index ff7ea2d..9fbd3357 100644
--- a/ash/resources/vector_icons/palette_tray_icon_default.1x.icon
+++ b/ash/resources/vector_icons/palette_tray_icon_default.1x.icon
@@ -6,9 +6,9 @@
 MOVE_TO, 12.24f, 2.2f,
 R_LINE_TO, 1.56f, 1.55f,
 R_CUBIC_TO, 0.26f, 0.26f, 0.27f, 0.69f, 0.01f, 0.95f,
-R_LINE_TO, -3.58f, 3.57f,
-R_LINE_TO, -2.51f, -2.51f,
-R_LINE_TO, 1.69f, -1.69f,
+LINE_TO, 10.23f, 8.27f,
+LINE_TO, 7.72f, 5.77f,
+LINE_TO, 9.41f, 4.08f,
 R_LINE_TO, -0.49f, -0.49f,
 R_LINE_TO, -3.77f, 3.77f,
 R_LINE_TO, -0.93f, -0.93f,
@@ -21,8 +21,8 @@
 MOVE_TO, 2, 11.5f,
 V_LINE_TO, 14,
 R_H_LINE_TO, 2.49f,
-LINE_TO, 9.52f, 8.98f,
-LINE_TO, 7.02f, 6.48f,
+R_LINE_TO, 5.03f, -5.02f,
+R_LINE_TO, -2.5f, -2.5f,
 LINE_TO, 2, 11.5f,
 CLOSE,
 END
diff --git a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon
index 702ff55..6a155be 100644
--- a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon
+++ b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon
@@ -2,67 +2,42 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-CANVAS_DIMENSIONS, 16,
-NEW_PATH,
-PATH_COLOR_ARGB, 0x4D, 0xFF, 0xFF, 0xFF,
-MOVE_TO, 12.97f, 9.06f,
-LINE_TO, 11, 9,
-R_LINE_TO, 2.61f, -1.66f,
-R_CUBIC_TO, 0.13f, -0.1f, 0.22f, -0.25f, 0.22f, -0.42f,
-R_CUBIC_TO, 0, -0.29f, -0.24f, -0.53f, -0.55f, -0.53f,
-R_CUBIC_TO, -0.11f, 0, -0.22f, 0.03f, -0.3f, 0.09f,
-CUBIC_TO, 12.98f, 6.48f, 8.99f, 9, 8.99f, 9,
-R_CUBIC_TO, -0.05f, 0.03f, -0.15f, 0.2f, -0.15f, 0.45f,
-R_CUBIC_TO, 0, 0.34f, 0.42f, 0.5f, 0.9f, 0.5f,
-LINE_TO, 11, 10,
-R_LINE_TO, -2.16f, 1.79f,
-R_CUBIC_TO, 0.21f, 0, 0.4f, -0.17f, 0.64f, -0.17f,
-R_CUBIC_TO, 0.68f, 0, 1.24f, 0.53f, 1.24f, 1.19f,
-R_CUBIC_TO, 0, 0.33f, -0.14f, 0.62f, -0.35f, 0.83f,
-R_LINE_TO, 3.18f, -2.95f,
-R_CUBIC_TO, 0.07f, -0.04f, 0.14f, -0.09f, 0.19f, -0.15f,
-R_CUBIC_TO, 0.14f, -0.16f, 0.23f, -0.35f, 0.23f, -0.56f,
-R_CUBIC_TO, 0, -0.46f, -0.32f, -0.91f, -0.99f, -0.91f,
+CANVAS_DIMENSIONS, 20,
+PATH_COLOR_ARGB, 0xFF, 0x69, 0x69, 0x69,
+MOVE_TO, 14.96f, 8.04f,
+R_H_LINE_TO, -4.56f,
+R_LINE_TO, 4.56f, -4.8f,
+R_CUBIC_TO, 0.3f, -0.23f, 0.5f, -0.59f, 0.5f, -0.99f,
+R_CUBIC_TO, 0, -0.68f, -0.55f, -1.24f, -1.22f, -1.24f,
+R_CUBIC_TO, -0.25f, 0, -0.48f, 0.08f, -0.68f, 0.21f,
+R_CUBIC_TO, 0, 0, -9.48f, 6.42f, -9.48f, 6.42f,
+R_LINE_TO, -0.36f, 0.24f,
+R_CUBIC_TO, -0.41f, 0.37f, -0.7f, 0.16f, -0.7f, 1.41f,
+R_CUBIC_TO, 0, 0.56f, 0.92f, 1.69f, 2, 1.69f,
+H_LINE_TO, 9.03f,
+R_LINE_TO, -1.18f, 0.69f,
+R_CUBIC_TO, -1.17f, 0.68f, -3.52f, 2.04f, -3.52f, 2.04f,
+R_CUBIC_TO, 0.42f, -0.25f, 0.9f, -0.41f, 1.42f, -0.41f,
+R_CUBIC_TO, 1.52f, 0, 2.75f, 1.25f, 2.75f, 2.79f,
+R_CUBIC_TO, 0, 0.76f, -0.3f, 1.45f, -0.79f, 1.96f,
+R_LINE_TO, 8.26f, -6.98f,
+R_CUBIC_TO, 0.16f, -0.1f, 0.3f, -0.22f, 0.43f, -0.36f,
+R_CUBIC_TO, 0.25f, -0.29f, 0.47f, -0.54f, 0.56f, -0.86f,
+R_CUBIC_TO, 0.03f, -0.1f, 0.04f, -0.2f, 0.04f, -0.32f,
+R_CUBIC_TO, 0, -1.31f, -0.96f, -1.48f, -2.04f, -1.48f,
 CLOSE,
 NEW_PATH,
-MOVE_TO, 9.25f, 11.5f,
-R_CUBIC_TO, -0.24f, 0, -0.45f, 0.07f, -0.64f, 0.18f,
-R_LINE_TO, -0.08f, 0.05f,
-R_LINE_TO, -0.02f, 0.02f,
-R_CUBIC_TO, -0.31f, 0.23f, -0.51f, 0.59f, -0.51f, 1,
-R_CUBIC_TO, 0, 0.69f, 0.56f, 1.25f, 1.25f, 1.25f,
-R_CUBIC_TO, 0.26f, 0, 0.5f, -0.08f, 0.7f, -0.21f,
-R_CUBIC_TO, 0.07f, -0.05f, 0.14f, -0.1f, 0.19f, -0.16f,
-R_CUBIC_TO, 0.22f, -0.23f, 0.36f, -0.53f, 0.36f, -0.88f,
-R_CUBIC_TO, 0, -0.69f, -0.56f, -1.25f, -1.25f, -1.25f,
-CLOSE,
-MOVE_TO, 8, 8.79f,
-R_CUBIC_TO, 0.04f, -0.03f, 0.08f, -0.07f, 0.12f, -0.09f,
-R_CUBIC_TO, 0.06f, -0.05f, 0.13f, -0.09f, 0.2f, -0.13f,
-R_LINE_TO, 0.65f, -0.41f,
-R_LINE_TO, -1.74f, -1.67f,
-LINE_TO, 2, 11.5f,
-V_LINE_TO, 14,
-R_H_LINE_TO, 2.59f,
-R_LINE_TO, 3.23f, -3.1f,
-R_CUBIC_TO, -0.21f, -0.27f, -0.34f, -0.59f, -0.34f, -0.95f,
-R_CUBIC_TO, 0, -0.44f, 0.19f, -0.85f, 0.52f, -1.16f,
-CLOSE,
-R_MOVE_TO, 4.97f, -3.85f,
-R_LINE_TO, 0.83f, -0.6f,
-R_CUBIC_TO, 0.27f, -0.26f, 0.26f, -0.69f, -0.01f, -0.95f,
-LINE_TO, 12.62f, 2.2f,
-R_CUBIC_TO, -0.27f, -0.26f, -0.71f, -0.26f, -0.97f, 0,
-R_LINE_TO, -0.98f, 0.94f,
-R_LINE_TO, -0.98f, -0.94f,
-R_CUBIC_TO, -0.26f, -0.26f, -0.71f, -0.27f, -0.98f, -0.01f,
-R_LINE_TO, -4.4f, 4.24f,
-R_LINE_TO, 0.97f, 0.93f,
-R_LINE_TO, 3.91f, -3.77f,
-R_LINE_TO, 0.51f, 0.49f,
-LINE_TO, 7.94f, 5.76f,
-R_LINE_TO, 1.88f, 1.82f,
-R_LINE_TO, 2.15f, -1.62f,
-R_CUBIC_TO, 0.23f, -0.15f, 1.34f, -1.4f, 1, -1.02f,
+MOVE_TO, 9, 16,
+R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3,
+R_CUBIC_TO, -0.57f, 0, -1.09f, 0.17f, -1.54f, 0.44f,
+R_LINE_TO, -0.18f, 0.11f,
+R_CUBIC_TO, -0.01f, 0.01f, -0.03f, 0.02f, -0.04f, 0.03f,
+CUBIC_TO, 3.49f, 14.13f, 3, 15.01f, 3, 16,
+R_CUBIC_TO, 0, 1.66f, 1.34f, 3, 3, 3,
+R_CUBIC_TO, 0.62f, 0, 1.19f, -0.19f, 1.67f, -0.51f,
+R_H_LINE_TO, 0,
+R_LINE_TO, 0.01f, -0.01f,
+R_CUBIC_TO, 0.16f, -0.11f, 0.32f, -0.24f, 0.45f, -0.38f,
+CUBIC_TO, 8.67f, 17.56f, 9, 16.82f, 9, 16,
 CLOSE,
 END
diff --git a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.icon b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.icon
index 354d777..9d86aca 100644
--- a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.icon
+++ b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.icon
@@ -3,69 +3,45 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 32,
-PATH_COLOR_ARGB, 0x4D, 0xFF, 0xFF, 0xFF,
-MOVE_TO, 26.32f, 18.44f,
-R_H_LINE_TO, -4.11f,
-R_LINE_TO, 4.11f, -3.54f,
-R_CUBIC_TO, 0.26f, -0.19f, 0.43f, -0.5f, 0.43f, -0.85f,
-R_CUBIC_TO, 0, -0.58f, -0.47f, -1.05f, -1.06f, -1.05f,
-R_CUBIC_TO, -0.22f, 0, -0.42f, 0.07f, -0.59f, 0.18f,
-R_LINE_TO, -8.21f, 5.47f,
-R_CUBIC_TO, -0.1f, 0.05f, -0.19f, 0.11f, -0.28f, 0.18f,
-R_LINE_TO, -0.03f, 0.02f,
-R_CUBIC_TO, -0.36f, 0.31f, -0.59f, 0.76f, -0.59f, 1.27f,
-R_CUBIC_TO, 0, 0.93f, 0.76f, 1.68f, 1.69f, 1.68f,
-R_H_LINE_TO, 3.85f,
-R_LINE_TO, -4.41f, 2,
-R_CUBIC_TO, 0.36f, -0.22f, 0.78f, -0.35f, 1.23f, -0.35f,
-R_CUBIC_TO, 1.32f, 0, 2.38f, 1.07f, 2.38f, 2.38f,
-R_CUBIC_TO, 0, 0.65f, -0.26f, 1.24f, -0.68f, 1.67f,
-R_LINE_TO, 7.15f, -5.94f,
-R_CUBIC_TO, 0.14f, -0.08f, 0.26f, -0.19f, 0.37f, -0.31f,
-R_CUBIC_TO, 0.28f, -0.32f, 0.44f, -0.53f, 0.44f, -1.02f,
-R_CUBIC_TO, 0.01f, -1.03f, -0.75f, -1.79f, -1.68f, -1.79f,
+PATH_COLOR_ARGB, 0xFF, 0xD3, 0xD3, 0xD3,
+MOVE_TO, 24.05f, 12,
+H_LINE_TO, 16.38f,
+R_LINE_TO, 7.68f, -7.42f,
+R_CUBIC_TO, 0.48f, -0.38f, 0.8f, -0.99f, 0.8f, -1.68f,
+CUBIC_TO, 24.86f, 1.74f, 23.97f, 0.8f, 22.88f, 0.8f,
+R_CUBIC_TO, -0.4f, 0, -0.78f, 0.13f, -1.1f, 0.35f,
+LINE_TO, 6.47f, 12.02f,
+R_CUBIC_TO, -0.18f, 0.1f, -0.36f, 0.23f, -0.51f, 0.37f,
+R_LINE_TO, -0.06f, 0.04f,
+R_CUBIC_TO, -0.67f, 0.62f, -1.1f, 1.52f, -1.1f, 2.53f,
+R_CUBIC_TO, 0, 1.85f, 1.41f, 3.34f, 3.15f, 3.44f,
+R_H_LINE_TO, 4.98f,
+R_LINE_TO, -6.03f, 3.87f,
+R_CUBIC_TO, 0.67f, -0.43f, 1.45f, -0.69f, 2.29f, -0.69f,
+R_CUBIC_TO, 2.46f, 0, 4.44f, 2.11f, 4.44f, 4.72f,
+R_CUBIC_TO, 0, 1.29f, -0.49f, 2.45f, -1.28f, 3.31f,
+R_LINE_TO, 13.35f, -11.8f,
+R_CUBIC_TO, 0.26f, -0.17f, 0.49f, -0.37f, 0.69f, -0.61f,
+R_CUBIC_TO, 0.52f, -0.64f, 0.82f, -1.4f, 0.82f, -2.23f,
+R_CUBIC_TO, 0, -1.84f, -1.41f, -2.94f, -3.15f, -2.96f,
+CLOSE,
 NEW_PATH,
-CLOSE,
-MOVE_TO, 20.75f, 25.6f,
-R_CUBIC_TO, 0, -1.31f, -1.06f, -2.37f, -2.37f, -2.37f,
-R_CUBIC_TO, -0.45f, 0, -0.86f, 0.13f, -1.22f, 0.35f,
-R_LINE_TO, -0.14f, 0.09f,
-R_CUBIC_TO, -0.01f, 0.01f, -0.02f, 0.02f, -0.03f, 0.03f,
-R_CUBIC_TO, -0.59f, 0.43f, -0.98f, 1.13f, -0.98f, 1.91f,
-R_CUBIC_TO, 0, 1.31f, 1.06f, 2.38f, 2.37f, 2.38f,
-R_CUBIC_TO, 0.49f, 0, 0.95f, -0.15f, 1.32f, -0.41f,
+MOVE_TO, 14.4f, 26.05f,
+R_CUBIC_TO, 0, -2.65f, -2.15f, -4.8f, -4.8f, -4.8f,
+R_CUBIC_TO, -0.91f, 0, -1.75f, 0.27f, -2.47f, 0.71f,
+R_LINE_TO, -0.29f, 0.18f,
+R_CUBIC_TO, -0.02f, 0.02f, -0.04f, 0.04f, -0.07f, 0.05f,
+R_CUBIC_TO, -1.19f, 0.88f, -1.97f, 2.27f, -1.97f, 3.86f,
+R_CUBIC_TO, 0, 2.65f, 2.15f, 4.8f, 4.8f, 4.8f,
+R_CUBIC_TO, 0.99f, 0, 1.91f, -0.3f, 2.67f, -0.82f,
 R_H_LINE_TO, 0,
-R_LINE_TO, 0.01f, 0,
-R_CUBIC_TO, 0.13f, -0.09f, 0.25f, -0.19f, 0.36f, -0.3f,
-R_CUBIC_TO, 0.42f, -0.43f, 0.68f, -1.01f, 0.68f, -1.66f,
+R_LINE_TO, 0.02f, -0.01f,
+R_CUBIC_TO, 0.26f, -0.18f, 0.51f, -0.38f, 0.73f, -0.61f,
+R_CUBIC_TO, 0.85f, -0.87f, 1.38f, -2.05f, 1.38f, -3.36f,
 CLOSE,
-R_MOVE_TO, -5.21f, -8.02f,
-R_CUBIC_TO, 0.07f, -0.07f, 0.14f, -0.13f, 0.23f, -0.19f,
-R_CUBIC_TO, 0.12f, -0.1f, 0.25f, -0.18f, 0.38f, -0.26f,
-R_LINE_TO, 1.24f, -0.83f,
-R_LINE_TO, -3.35f, -3.35f,
-LINE_TO, 4, 23,
-V_LINE_TO, 28,
-R_H_LINE_TO, 4.99f,
-R_LINE_TO, 6.21f, -6.2f,
-R_CUBIC_TO, -0.4f, -0.53f, -0.66f, -1.18f, -0.66f, -1.9f,
-R_CUBIC_TO, 0, -0.88f, 0.37f, -1.71f, 1.01f, -2.31f,
-CLOSE,
-R_MOVE_TO, 10.16f, -6.31f,
-R_CUBIC_TO, 0.02f, 0, 1.93f, -1.87f, 1.93f, -1.87f,
-R_CUBIC_TO, 0.52f, -0.52f, 0.35f, -1.55f, -0.24f, -2.1f,
-R_LINE_TO, -2.89f, -2.9f,
-R_CUBIC_TO, -0.52f, -0.52f, -1.37f, -0.52f, -1.88f, 0,
-R_LINE_TO, -1.89f, 1.88f,
-R_LINE_TO, -1.89f, -1.88f,
-R_CUBIC_TO, -0.51f, -0.52f, -1.37f, -0.53f, -1.89f, -0.01f,
-R_LINE_TO, -8.49f, 8.48f,
-R_LINE_TO, 1.87f, 1.87f,
-R_LINE_TO, 7.55f, -7.55f,
-R_LINE_TO, 0.97f, 0.97f,
-R_LINE_TO, -3.37f, 3.37f,
-R_LINE_TO, 3.64f, 3.64f,
-R_LINE_TO, 5.18f, -3.46f,
-R_CUBIC_TO, 0.45f, -0.29f, 0.93f, -0.43f, 1.42f, -0.43f,
+MOVE_TO, 0, 0,
+R_H_LINE_TO, 32,
+R_V_LINE_TO, 32,
+H_LINE_TO, 0,
 CLOSE,
 END
diff --git a/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon b/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon
index af9487c4..b9ec73e6 100644
--- a/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon
+++ b/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon
@@ -2,61 +2,35 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-CANVAS_DIMENSIONS, 16,
-MOVE_TO, 12, 10,
-R_H_LINE_TO, -1,
-R_V_LINE_TO, -1,
-R_H_LINE_TO, -1,
-R_V_LINE_TO, 1,
-R_H_LINE_TO, -1,
-R_V_LINE_TO, 1,
-R_H_LINE_TO, 1,
-R_V_LINE_TO, 1,
-R_H_LINE_TO, 1,
-R_V_LINE_TO, -1,
-R_H_LINE_TO, 1,
-R_V_LINE_TO, -1,
-CLOSE,
-R_MOVE_TO, -1.5f, -1.5f,
-R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2,
-R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2,
-R_CUBIC_TO, 1.1f, 0, 2, -0.89f, 2, -2,
-R_CUBIC_TO, 0, -1.11f, -0.9f, -2, -2, -2,
-CLOSE,
-R_MOVE_TO, 3.31f, -3.8f,
-R_CUBIC_TO, 0.26f, -0.26f, 0.25f, -0.69f, -0.01f, -0.95f,
-R_LINE_TO, -1.56f, -1.55f,
-R_CUBIC_TO, -0.26f, -0.26f, -0.69f, -0.26f, -0.94f, 0,
-R_LINE_TO, -0.95f, 0.94f,
-R_LINE_TO, -0.95f, -0.94f,
-R_CUBIC_TO, -0.25f, -0.26f, -0.69f, -0.27f, -0.95f, -0.01f,
-R_LINE_TO, -4.25f, 4.24f,
-R_LINE_TO, 0.93f, 0.93f,
-R_LINE_TO, 3.77f, -3.77f,
-R_LINE_TO, 0.49f, 0.49f,
-R_LINE_TO, -1.69f, 1.69f,
-R_LINE_TO, 0.74f, 1.1f,
-R_LINE_TO, 0.65f, -0.84f,
-R_CUBIC_TO, 0, 0, 2.49f, -0.21f, 2.98f, 0,
-R_LINE_TO, 1.72f, -1.33f,
-CLOSE,
-R_MOVE_TO, -6.79f, 1.78f,
-R_LINE_TO, -5.02f, 5.02f,
+CANVAS_DIMENSIONS, 20,
+MOVE_TO, 8, 10,
+H_LINE_TO, 5.5f,
+V_LINE_TO, 8,
+H_LINE_TO, 8,
+V_LINE_TO, 5.5f,
+R_H_LINE_TO, 2,
+V_LINE_TO, 8,
+R_H_LINE_TO, 2.5f,
+R_V_LINE_TO, 2,
+H_LINE_TO, 10,
 R_V_LINE_TO, 2.5f,
-R_H_LINE_TO, 2.49f,
-R_LINE_TO, 1.54f, -1.48f,
-R_V_LINE_TO, -3.07f,
-R_CUBIC_TO, 0.48f, -0.95f, 0.79f, -1.49f, 1.72f, -2.22f,
-R_LINE_TO, -0.74f, -0.74f,
+H_LINE_TO, 8,
+V_LINE_TO, 10,
 CLOSE,
-R_MOVE_TO, 5.21f, 6.47f,
-R_LINE_TO, 1.1f, 1.05f,
-R_LINE_TO, 0.67f, -0.76f,
-R_LINE_TO, -1.05f, -1,
-R_CUBIC_TO, 0.35f, -0.49f, 0.55f, -1.09f, 0.55f, -1.73f,
-R_CUBIC_TO, 0, -1.65f, -1.35f, -3, -3, -3,
-R_CUBIC_TO, -1.65f, 0, -3, 1.35f, -3, 3,
-R_CUBIC_TO, 0, 1.65f, 1.35f, 3, 3, 3,
-R_CUBIC_TO, 0.64f, 0, 1.24f, -0.2f, 1.73f, -0.55f,
+R_MOVE_TO, 8.32f, 7.9f,
+R_LINE_TO, 1.65f, -1.8f,
+R_LINE_TO, -3.29f, -3.01f,
+R_CUBIC_TO, 0.83f, -1.15f, 1.32f, -2.56f, 1.32f, -4.09f,
+R_CUBIC_TO, 0, -3.86f, -3.14f, -7, -7, -7,
+CUBIC_TO, 5.14f, 2, 2, 5.14f, 2, 9,
+R_CUBIC_TO, 0, 3.86f, 3.14f, 7, 7, 7,
+R_CUBIC_TO, 1.45f, 0, 2.81f, -0.45f, 3.93f, -1.21f,
+R_LINE_TO, 3.39f, 3.11f,
+CLOSE,
+MOVE_TO, 9, 4,
+CUBIC_TO, 6.24f, 4, 4, 6.24f, 4, 9,
+R_CUBIC_TO, 0, 2.76f, 2.24f, 5, 5, 5,
+R_CUBIC_TO, 2.76f, 0, 5, -2.24f, 5, -5,
+R_CUBIC_TO, 0, -2.76f, -2.24f, -5, -5, -5,
 CLOSE,
 END
diff --git a/ash/resources/vector_icons/palette_tray_icon_magnify.icon b/ash/resources/vector_icons/palette_tray_icon_magnify.icon
index 09b9f10..53f1c380 100644
--- a/ash/resources/vector_icons/palette_tray_icon_magnify.icon
+++ b/ash/resources/vector_icons/palette_tray_icon_magnify.icon
@@ -2,61 +2,35 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-CANVAS_DIMENSIONS, 32,
-MOVE_TO, 24.45f, 25.91f,
-LINE_TO, 26.65f, 28,
-LINE_TO, 28, 26.48f,
-R_LINE_TO, -2.11f, -2.01f,
-CUBIC_TO, 26.59f, 23.49f, 27, 22.29f, 27, 21,
-CUBIC_TO, 27, 17.69f, 24.31f, 15, 21, 15,
-R_CUBIC_TO, -3.31f, 0, -6, 2.69f, -6, 6,
-CUBIC_TO, 15, 24.31f, 17.69f, 27, 21, 27,
-R_CUBIC_TO, 1.28f, 0, 2.48f, -0.41f, 3.45f, -1.09f,
-CLOSE,
-R_MOVE_TO, -8.94f, -11.47f,
-R_LINE_TO, -1.48f, -1.48f,
-LINE_TO, 4, 23,
+CANVAS_DIMENSIONS, 40,
+MOVE_TO, 16, 20,
+R_H_LINE_TO, -5,
+R_V_LINE_TO, -4,
+R_H_LINE_TO, 5,
+R_V_LINE_TO, -5,
+R_H_LINE_TO, 4,
 R_V_LINE_TO, 5,
-R_H_LINE_TO, 4.99f,
-LINE_TO, 13.09f, 23.9f,
-R_CUBIC_TO, -0.42f, -0.97f, -0.65f, -2.04f, -0.65f, -3.16f,
-R_CUBIC_TO, 0, -2.56f, 1.21f, -4.83f, 3.08f, -6.3f,
+R_H_LINE_TO, 5,
+R_V_LINE_TO, 4,
+R_H_LINE_TO, -5,
+R_V_LINE_TO, 5,
+R_H_LINE_TO, -4,
+R_V_LINE_TO, -5,
 CLOSE,
-R_MOVE_TO, 8.1f, -1.04f,
-R_LINE_TO, 4, -4,
-R_CUBIC_TO, 0.52f, -0.52f, 0.51f, -1.37f, -0.01f, -1.89f,
-R_LINE_TO, -3.12f, -3.11f,
-R_CUBIC_TO, -0.52f, -0.52f, -1.37f, -0.52f, -1.88f, 0,
-R_LINE_TO, -1.89f, 1.88f,
-R_LINE_TO, -1.89f, -1.88f,
-R_CUBIC_TO, -0.51f, -0.52f, -1.37f, -0.53f, -1.89f, -0.01f,
-R_LINE_TO, -8.49f, 8.48f,
-R_LINE_TO, 1.87f, 1.87f,
-LINE_TO, 17.85f, 7.19f,
-R_LINE_TO, 0.97f, 0.97f,
-R_LINE_TO, -3.37f, 3.37f,
-R_LINE_TO, 1.85f, 1.85f,
-R_CUBIC_TO, 0.97f, -0.41f, 2.03f, -0.64f, 3.14f, -0.64f,
-R_CUBIC_TO, 1.13f, 0, 2.2f, 0.24f, 3.18f, 0.66f,
+R_MOVE_TO, 16.63f, 15.8f,
+LINE_TO, 35.93f, 32.2f,
+R_LINE_TO, -6.57f, -6.02f,
+R_CUBIC_TO, 1.66f, -2.3f, 2.64f, -5.13f, 2.64f, -8.18f,
+R_CUBIC_TO, 0, -7.72f, -6.28f, -14, -14, -14,
+R_CUBIC_TO, -7.72f, 0, -14, 6.28f, -14, 14,
+R_CUBIC_TO, 0, 7.72f, 6.28f, 14, 14, 14,
+R_CUBIC_TO, 2.91f, 0, 5.61f, -0.89f, 7.86f, -2.42f,
+R_LINE_TO, 6.78f, 6.22f,
 CLOSE,
-MOVE_TO, 21, 17.01f,
-R_CUBIC_TO, -2.2f, 0, -3.99f, 1.79f, -3.99f, 3.99f,
-R_CUBIC_TO, 0, 2.2f, 1.79f, 3.99f, 3.99f, 3.99f,
-R_CUBIC_TO, 2.2f, 0, 3.99f, -1.79f, 3.99f, -3.99f,
-R_CUBIC_TO, 0, -2.2f, -1.79f, -3.99f, -3.99f, -3.99f,
-CLOSE,
-MOVE_TO, 24, 20,
-R_H_LINE_TO, -2,
-R_V_LINE_TO, -2,
-R_H_LINE_TO, -2,
-R_V_LINE_TO, 2,
-R_H_LINE_TO, -2,
-R_V_LINE_TO, 2,
-R_H_LINE_TO, 2,
-R_V_LINE_TO, 2,
-R_H_LINE_TO, 2,
-R_V_LINE_TO, -2,
-R_H_LINE_TO, 2,
-R_V_LINE_TO, -2,
+MOVE_TO, 18, 8,
+CUBIC_TO, 12.48f, 8, 8, 12.49f, 8, 18,
+R_CUBIC_TO, 0, 5.51f, 4.49f, 10, 10, 10,
+R_CUBIC_TO, 5.51f, 0, 10, -4.49f, 10, -10,
+R_CUBIC_TO, 0, -5.51f, -4.49f, -10, -10, -10,
 CLOSE,
 END
diff --git a/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon b/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon
index 2116990..dcb19c2 100644
--- a/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon
+++ b/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon
@@ -24,4 +24,5 @@
 CUBIC_TO, 1.77f, 7.64f, 3.3f, 9.16f, 5.18f, 9.16f,
 CUBIC_TO, 7.07f, 9.16f, 8.6f, 7.64f, 8.6f, 5.75f,
 CLOSE,
+ROUND_RECT, 0, 0, 16, 16, 0,
 END
diff --git a/ash/resources/vector_icons/palette_tray_icon_metalayer.icon b/ash/resources/vector_icons/palette_tray_icon_metalayer.icon
index 326b4430..9655241cc 100644
--- a/ash/resources/vector_icons/palette_tray_icon_metalayer.icon
+++ b/ash/resources/vector_icons/palette_tray_icon_metalayer.icon
@@ -24,4 +24,5 @@
 CUBIC_TO, 3.54f, 15.27f, 6.59f, 18.33f, 10.36f, 18.33f,
 CUBIC_TO, 14.13f, 18.33f, 17.19f, 15.27f, 17.19f, 11.5f,
 CLOSE,
+ROUND_RECT, 0, 0, 32, 32, 0,
 END
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc
index bb6565e..84807f5 100644
--- a/ash/root_window_controller_unittest.cc
+++ b/ash/root_window_controller_unittest.cc
@@ -100,8 +100,6 @@
 
 }  // namespace
 
-namespace test {
-
 class RootWindowControllerTest : public AshTestBase {
  public:
   views::Widget* CreateTestWidget(const gfx::Rect& bounds) {
@@ -685,14 +683,14 @@
   void SetUp() override {
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         keyboard::switches::kEnableVirtualKeyboard);
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     keyboard::SetTouchKeyboardEnabled(true);
     Shell::Get()->CreateKeyboard();
   }
 
   void TearDown() override {
     keyboard::SetTouchKeyboardEnabled(false);
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
  private:
@@ -975,7 +973,7 @@
       display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
 
   // Notify keyboard bounds changing.
-  controller->NotifyKeyboardBoundsChanging(keyboard_container->bounds());
+  controller->NotifyContentsBoundsChanging(keyboard_container->bounds());
 
   if (!keyboard::IsKeyboardOverscrollEnabled()) {
     gfx::Rect after =
@@ -1226,5 +1224,4 @@
   EXPECT_EQ("0,600 600x200", keyboard_container->bounds().ToString());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/rotator/screen_rotation_animation_unittest.cc b/ash/rotator/screen_rotation_animation_unittest.cc
index 63f1476..c4efaa0 100644
--- a/ash/rotator/screen_rotation_animation_unittest.cc
+++ b/ash/rotator/screen_rotation_animation_unittest.cc
@@ -20,7 +20,6 @@
 #include "ui/gfx/transform.h"
 
 namespace ash {
-namespace test {
 
 class ScreenRotationAnimationTest : public AshTestBase {
  public:
@@ -95,5 +94,4 @@
   layer.reset();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/rotator/screen_rotation_animator.cc b/ash/rotator/screen_rotation_animator.cc
index 0d2edb8a6e..31cae7a 100644
--- a/ash/rotator/screen_rotation_animator.cc
+++ b/ash/rotator/screen_rotation_animator.cc
@@ -410,8 +410,8 @@
       base::MakeUnique<ui::LayerAnimationSequence>(
           std::move(old_layer_screen_rotation));
 
-  // In unit test, we can use ash::test::ScreenRotationAnimatorTestApi to
-  // control the animation.
+  // In unit tests, we can use ash::ScreenRotationAnimatorTestApi to control the
+  // animation.
   if (disable_animation_timers_for_test_) {
     if (new_layer_tree_owner_)
       new_layer_animator->set_disable_timer_for_test(true);
diff --git a/ash/rotator/screen_rotation_animator.h b/ash/rotator/screen_rotation_animator.h
index 6f122dc0..23b0ddb 100644
--- a/ash/rotator/screen_rotation_animator.h
+++ b/ash/rotator/screen_rotation_animator.h
@@ -29,9 +29,6 @@
 }  // namespace ui
 
 namespace ash {
-namespace test {
-class ScreenRotationAnimatorTestApi;
-}  // namespace test
 
 class ScreenRotationAnimatorObserver;
 
@@ -98,7 +95,7 @@
       std::unique_ptr<ScreenRotationRequest> rotation_request);
 
  private:
-  friend class ash::test::ScreenRotationAnimatorTestApi;
+  friend class ScreenRotationAnimatorTestApi;
 
   void StartRotationAnimation(
       std::unique_ptr<ScreenRotationRequest> rotation_request);
diff --git a/ash/rotator/screen_rotation_animator_unittest.cc b/ash/rotator/screen_rotation_animator_unittest.cc
index b779fdae..1949dce 100644
--- a/ash/rotator/screen_rotation_animator_unittest.cc
+++ b/ash/rotator/screen_rotation_animator_unittest.cc
@@ -136,7 +136,7 @@
 
 }  // namespace
 
-class ScreenRotationAnimatorSlowAnimationTest : public test::AshTestBase {
+class ScreenRotationAnimatorSlowAnimationTest : public AshTestBase {
  public:
   ScreenRotationAnimatorSlowAnimationTest() {}
   ~ScreenRotationAnimatorSlowAnimationTest() override {}
@@ -149,14 +149,14 @@
 
   ScreenRotationAnimator* animator() { return animator_.get(); }
 
-  test::ScreenRotationAnimatorTestApi* test_api() { return test_api_.get(); }
+  ScreenRotationAnimatorTestApi* test_api() { return test_api_.get(); }
 
  private:
   display::Display display_;
 
   std::unique_ptr<ScreenRotationAnimator> animator_;
 
-  std::unique_ptr<test::ScreenRotationAnimatorTestApi> test_api_;
+  std::unique_ptr<ScreenRotationAnimatorTestApi> test_api_;
 
   std::unique_ptr<ui::ScopedAnimationDurationScaleMode> non_zero_duration_mode_;
 
@@ -169,15 +169,14 @@
   display_ = display::Screen::GetScreen()->GetPrimaryDisplay();
   animator_ = base::MakeUnique<ScreenRotationAnimator>(
       Shell::GetRootWindowForDisplayId(display_.id()));
-  test_api_ =
-      base::MakeUnique<test::ScreenRotationAnimatorTestApi>(animator_.get());
+  test_api_ = base::MakeUnique<ScreenRotationAnimatorTestApi>(animator_.get());
   test_api()->DisableAnimationTimers();
   non_zero_duration_mode_ =
       base::MakeUnique<ui::ScopedAnimationDurationScaleMode>(
           ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
 }
 
-class ScreenRotationAnimatorSmoothAnimationTest : public test::AshTestBase {
+class ScreenRotationAnimatorSmoothAnimationTest : public AshTestBase {
  public:
   ScreenRotationAnimatorSmoothAnimationTest() {}
   ~ScreenRotationAnimatorSmoothAnimationTest() override {}
@@ -197,7 +196,7 @@
                                  const base::Closure& before_callback,
                                  const base::Closure& after_callback);
 
-  test::ScreenRotationAnimatorTestApi* test_api() { return test_api_.get(); }
+  ScreenRotationAnimatorTestApi* test_api() { return test_api_.get(); }
 
   void WaitForCopyCallback();
 
@@ -208,7 +207,7 @@
 
   std::unique_ptr<TestScreenRotationAnimator> animator_;
 
-  std::unique_ptr<test::ScreenRotationAnimatorTestApi> test_api_;
+  std::unique_ptr<ScreenRotationAnimatorTestApi> test_api_;
 
   std::unique_ptr<ui::ScopedAnimationDurationScaleMode> non_zero_duration_mode_;
 
@@ -248,8 +247,7 @@
     const base::Closure& after_callback) {
   animator_ = base::MakeUnique<TestScreenRotationAnimator>(
       root_window, before_callback, after_callback);
-  test_api_ =
-      base::MakeUnique<test::ScreenRotationAnimatorTestApi>(animator_.get());
+  test_api_ = base::MakeUnique<ScreenRotationAnimatorTestApi>(animator_.get());
   test_api()->DisableAnimationTimers();
 }
 
diff --git a/ash/rotator/test/screen_rotation_animator_test_api.cc b/ash/rotator/test/screen_rotation_animator_test_api.cc
index 0d3d679..30aa67b0 100644
--- a/ash/rotator/test/screen_rotation_animator_test_api.cc
+++ b/ash/rotator/test/screen_rotation_animator_test_api.cc
@@ -9,7 +9,6 @@
 #include "ui/compositor/layer_tree_owner.h"
 
 namespace ash {
-namespace test {
 
 ScreenRotationAnimatorTestApi::ScreenRotationAnimatorTestApi(
     ScreenRotationAnimator* animator)
@@ -35,5 +34,4 @@
   return animators;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/rotator/test/screen_rotation_animator_test_api.h b/ash/rotator/test/screen_rotation_animator_test_api.h
index e75be79..2fdf3c1e 100644
--- a/ash/rotator/test/screen_rotation_animator_test_api.h
+++ b/ash/rotator/test/screen_rotation_animator_test_api.h
@@ -18,8 +18,6 @@
 namespace ash {
 class ScreenRotationAnimator;
 
-namespace test {
-
 // Test API to provide internal access to a ScreenRotationAnimator instance.
 // This can also be used to control the screen rotation animations via the
 // ui::test::MultiLayerAnimatorTestController API.
@@ -43,7 +41,6 @@
   DISALLOW_COPY_AND_ASSIGN(ScreenRotationAnimatorTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_ROTATOR_TEST_SCREEN_ROTATION_ANIMATOR_TEST_API_H_
diff --git a/ash/screen_util_unittest.cc b/ash/screen_util_unittest.cc
index 4a0b4c4..621e3704 100644
--- a/ash/screen_util_unittest.cc
+++ b/ash/screen_util_unittest.cc
@@ -17,7 +17,6 @@
 #include "ui/wm/core/coordinate_conversion.h"
 
 namespace ash {
-namespace test {
 
 using ScreenUtilTest = AshTestBase;
 
@@ -134,5 +133,4 @@
             ScreenUtil::GetDisplayBoundsWithShelf(window).ToString());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/shelf/app_list_button_unittest.cc b/ash/shelf/app_list_button_unittest.cc
index 71b9577..c995792 100644
--- a/ash/shelf/app_list_button_unittest.cc
+++ b/ash/shelf/app_list_button_unittest.cc
@@ -16,7 +16,6 @@
 #include "ui/events/event_constants.h"
 
 namespace ash {
-namespace test {
 
 ui::GestureEvent CreateGestureEvent(ui::GestureEventDetails details) {
   return ui::GestureEvent(0, 0, ui::EF_NONE, base::TimeTicks(), details);
@@ -87,5 +86,4 @@
   EXPECT_EQ(1u, test_app_list_presenter.voice_session_count());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/shelf/overflow_bubble_view.h b/ash/shelf/overflow_bubble_view.h
index 6a173f3..486bf76a 100644
--- a/ash/shelf/overflow_bubble_view.h
+++ b/ash/shelf/overflow_bubble_view.h
@@ -18,10 +18,6 @@
 namespace ash {
 class Shelf;
 
-namespace test {
-class OverflowBubbleViewTestAPI;
-}
-
 // OverflowBubbleView hosts a ShelfView to display overflown items.
 // Exports to access this class from OverflowBubbleViewTestAPI.
 class ASH_EXPORT OverflowBubbleView : public views::BubbleDialogDelegateView,
@@ -39,7 +35,7 @@
   gfx::Rect GetBubbleBounds() override;
 
  private:
-  friend class test::OverflowBubbleViewTestAPI;
+  friend class OverflowBubbleViewTestAPI;
 
   void ScrollByXOffset(int x_offset);
   void ScrollByYOffset(int y_offset);
diff --git a/ash/shelf/overflow_button.h b/ash/shelf/overflow_button.h
index a189406..c6ab5810 100644
--- a/ash/shelf/overflow_button.h
+++ b/ash/shelf/overflow_button.h
@@ -12,9 +12,6 @@
 #include "ui/views/controls/button/custom_button.h"
 
 namespace ash {
-namespace test {
-class OverflowButtonTestApi;
-}  // namespace test
 
 class Shelf;
 class ShelfView;
@@ -34,7 +31,7 @@
   void UpdateShelfItemBackground(SkColor color);
 
  private:
-  friend class test::OverflowButtonTestApi;
+  friend class OverflowButtonTestApi;
 
   enum class ChevronDirection { UP, DOWN, LEFT, RIGHT };
 
diff --git a/ash/shelf/shelf_button_pressed_metric_tracker.h b/ash/shelf/shelf_button_pressed_metric_tracker.h
index 4105da7..fad0a94 100644
--- a/ash/shelf/shelf_button_pressed_metric_tracker.h
+++ b/ash/shelf/shelf_button_pressed_metric_tracker.h
@@ -20,10 +20,6 @@
 
 namespace ash {
 
-namespace test {
-class ShelfButtonPressedMetricTrackerTestAPI;
-}  // namespace test
-
 // Tracks UMA metrics based on shelf button press actions. More specifically
 // data is added to the following user actions and histograms:
 //
@@ -50,7 +46,7 @@
                      ShelfAction performed_action);
 
  private:
-  friend class test::ShelfButtonPressedMetricTrackerTestAPI;
+  friend class ShelfButtonPressedMetricTrackerTestAPI;
 
   // Records UMA metrics for the input source when a button is pressed.
   void RecordButtonPressedSource(const ui::Event& event);
diff --git a/ash/shelf/shelf_button_pressed_metric_tracker_unittest.cc b/ash/shelf/shelf_button_pressed_metric_tracker_unittest.cc
index 849a8c7..5703bbd 100644
--- a/ash/shelf/shelf_button_pressed_metric_tracker_unittest.cc
+++ b/ash/shelf/shelf_button_pressed_metric_tracker_unittest.cc
@@ -21,7 +21,6 @@
 #include "ui/views/controls/button/button.h"
 
 namespace ash {
-namespace test {
 namespace {
 
 // A simple light weight test double dummy for a views::Button.
@@ -312,5 +311,4 @@
       kTimeDeltaInMilliseconds, 1);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/shelf/shelf_controller_unittest.cc b/ash/shelf/shelf_controller_unittest.cc
index 879cf3c..53bfcca 100644
--- a/ash/shelf/shelf_controller_unittest.cc
+++ b/ash/shelf/shelf_controller_unittest.cc
@@ -63,8 +63,8 @@
   DISALLOW_COPY_AND_ASSIGN(TestShelfObserver);
 };
 
-using ShelfControllerTest = test::AshTestBase;
-using NoSessionShelfControllerTest = test::NoSessionAshTestBase;
+using ShelfControllerTest = AshTestBase;
+using NoSessionShelfControllerTest = NoSessionAshTestBase;
 
 TEST_F(ShelfControllerTest, IntializesAppListItemDelegate) {
   ShelfModel* model = Shell::Get()->shelf_controller()->model();
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc
index 5c31cda..703f119 100644
--- a/ash/shelf/shelf_layout_manager_unittest.cc
+++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -61,11 +61,11 @@
 }
 
 ShelfWidget* GetShelfWidget() {
-  return test::AshTestBase::GetPrimaryShelf()->shelf_widget();
+  return AshTestBase::GetPrimaryShelf()->shelf_widget();
 }
 
 ShelfLayoutManager* GetShelfLayoutManager() {
-  return test::AshTestBase::GetPrimaryShelf()->shelf_layout_manager();
+  return AshTestBase::GetPrimaryShelf()->shelf_layout_manager();
 }
 
 // Class which waits till the shelf finishes animating to the target size and
@@ -155,7 +155,7 @@
     if (type == ui::ET_GESTURE_SCROLL_UPDATE)
       scroll_.Add(delta);
 
-    Shelf* shelf = test::AshTestBase::GetPrimaryShelf();
+    Shelf* shelf = AshTestBase::GetPrimaryShelf();
     gfx::Rect shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
     if (shelf->IsHorizontalAlignment()) {
       EXPECT_EQ(auto_hidden_shelf_widget_bounds_.bottom(),
@@ -239,7 +239,7 @@
 
 }  // namespace
 
-class ShelfLayoutManagerTest : public test::AshTestBase {
+class ShelfLayoutManagerTest : public AshTestBase {
  public:
   ShelfLayoutManagerTest() {}
 
@@ -999,7 +999,7 @@
   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
 
   // The tested behavior relies on the app list presenter implementation.
-  test::TestAppListViewPresenterImpl app_list_presenter_impl;
+  TestAppListViewPresenterImpl app_list_presenter_impl;
 
   // Create a normal unmaximized window; the shelf should be visible.
   aura::Window* window = CreateTestWindow();
@@ -1030,7 +1030,7 @@
   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
 
   // The tested behavior relies on the app list presenter implementation.
-  test::TestAppListViewPresenterImpl app_list_presenter_impl;
+  TestAppListViewPresenterImpl app_list_presenter_impl;
 
   // Create a normal unmaximized window; the shelf should be hidden.
   aura::Window* window = CreateTestWindow();
@@ -1097,7 +1097,7 @@
   wm::ActivateWindow(window_1);
 
   // The tested behavior relies on the app list presenter implementation.
-  test::TestAppListViewPresenterImpl app_list_presenter_impl;
+  TestAppListViewPresenterImpl app_list_presenter_impl;
 
   Shell::Get()->UpdateShelfVisibility();
   EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility());
@@ -1135,7 +1135,7 @@
   Shelf* shelf = GetPrimaryShelf();
 
   // The tested behavior relies on the app list presenter implementation.
-  test::TestAppListViewPresenterImpl app_list_presenter_impl;
+  TestAppListViewPresenterImpl app_list_presenter_impl;
 
   // Create a window and make it full screen; the shelf should be hidden.
   aura::Window* window = CreateTestWindow();
@@ -1793,22 +1793,22 @@
   EXPECT_EQ(gfx::Point(500, 400), status_area_bounds.bottom_right());
 }
 
-class ShelfLayoutManagerKeyboardTest : public test::AshTestBase {
+class ShelfLayoutManagerKeyboardTest : public AshTestBase {
  public:
   ShelfLayoutManagerKeyboardTest() {}
   ~ShelfLayoutManagerKeyboardTest() override {}
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     UpdateDisplay("800x600");
     keyboard::SetAccessibilityKeyboardEnabled(true);
   }
 
-  // test::AshTestBase:
+  // AshTestBase:
   void TearDown() override {
     keyboard::SetAccessibilityKeyboardEnabled(false);
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
   void InitKeyboardBounds() {
diff --git a/ash/shelf/shelf_locking_manager_unittest.cc b/ash/shelf/shelf_locking_manager_unittest.cc
index 27c49dd..4e3da54 100644
--- a/ash/shelf/shelf_locking_manager_unittest.cc
+++ b/ash/shelf/shelf_locking_manager_unittest.cc
@@ -11,7 +11,7 @@
 namespace {
 
 // Tests the shelf behavior when the screen or session is locked.
-class ShelfLockingManagerTest : public test::AshTestBase {
+class ShelfLockingManagerTest : public AshTestBase {
  public:
   ShelfLockingManagerTest() {}
 
diff --git a/ash/shelf/shelf_tooltip_manager.h b/ash/shelf/shelf_tooltip_manager.h
index f4d5bc8..4db79bff 100644
--- a/ash/shelf/shelf_tooltip_manager.h
+++ b/ash/shelf/shelf_tooltip_manager.h
@@ -21,11 +21,6 @@
 namespace ash {
 class ShelfView;
 
-namespace test {
-class ShelfTooltipManagerTest;
-class ShelfViewTest;
-}
-
 // ShelfTooltipManager manages the tooltip bubble that appears for shelf items.
 class ASH_EXPORT ShelfTooltipManager : public ui::EventHandler,
                                        public views::PointerWatcher,
@@ -68,8 +63,8 @@
 
  private:
   class ShelfTooltipBubble;
-  friend class test::ShelfViewTest;
-  friend class test::ShelfTooltipManagerTest;
+  friend class ShelfViewTest;
+  friend class ShelfTooltipManagerTest;
 
   // A helper function to check for shelf visibility and view validity.
   bool ShouldShowTooltipForView(views::View* view);
diff --git a/ash/shelf/shelf_tooltip_manager_unittest.cc b/ash/shelf/shelf_tooltip_manager_unittest.cc
index 62501f4..429ebd0 100644
--- a/ash/shelf/shelf_tooltip_manager_unittest.cc
+++ b/ash/shelf/shelf_tooltip_manager_unittest.cc
@@ -19,7 +19,6 @@
 #include "ui/views/widget/widget.h"
 
 namespace ash {
-namespace test {
 
 class ShelfTooltipManagerTest : public AshTestBase {
  public:
@@ -29,7 +28,7 @@
   void SetUp() override {
     AshTestBase::SetUp();
     shelf_view_ = GetPrimaryShelf()->GetShelfViewForTesting();
-    tooltip_manager_ = test::ShelfViewTestAPI(shelf_view_).tooltip_manager();
+    tooltip_manager_ = ShelfViewTestAPI(shelf_view_).tooltip_manager();
     tooltip_manager_->set_timer_delay_for_test(0);
   }
 
@@ -240,5 +239,4 @@
   EXPECT_TRUE(tooltip_manager_->IsVisible());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/shelf/shelf_unittest.cc b/ash/shelf/shelf_unittest.cc
index 73c5d8a7..6b370cbf 100644
--- a/ash/shelf/shelf_unittest.cc
+++ b/ash/shelf/shelf_unittest.cc
@@ -15,28 +15,28 @@
 
 namespace ash {
 
-class ShelfTest : public test::AshTestBase {
+class ShelfTest : public AshTestBase {
  public:
   ShelfTest() : shelf_model_(nullptr) {}
 
   ~ShelfTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
     ShelfView* shelf_view = GetPrimaryShelf()->GetShelfViewForTesting();
     shelf_model_ = shelf_view->model();
 
-    test_.reset(new test::ShelfViewTestAPI(shelf_view));
+    test_.reset(new ShelfViewTestAPI(shelf_view));
   }
 
   ShelfModel* shelf_model() { return shelf_model_; }
 
-  test::ShelfViewTestAPI* test_api() { return test_.get(); }
+  ShelfViewTestAPI* test_api() { return test_.get(); }
 
  private:
   ShelfModel* shelf_model_;
-  std::unique_ptr<test::ShelfViewTestAPI> test_;
+  std::unique_ptr<ShelfViewTestAPI> test_;
 
   DISALLOW_COPY_AND_ASSIGN(ShelfTest);
 };
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h
index 15fd7bd..ca63fe5 100644
--- a/ash/shelf/shelf_view.h
+++ b/ash/shelf/shelf_view.h
@@ -49,10 +49,6 @@
 struct ShelfItem;
 class ShelfWidget;
 
-namespace test {
-class ShelfViewTestAPI;
-}
-
 enum ShelfAlignmentUmaEnumValue {
   SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM,
   SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT,
@@ -172,7 +168,7 @@
   const ShelfButton* drag_view() const { return drag_view_; }
 
  private:
-  friend class ash::test::ShelfViewTestAPI;
+  friend class ShelfViewTestAPI;
 
   class FadeOutAnimationDelegate;
   class StartFadeAnimationDelegate;
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc
index c18c2140..2b4dbaf 100644
--- a/ash/shelf/shelf_view_unittest.cc
+++ b/ash/shelf/shelf_view_unittest.cc
@@ -72,7 +72,6 @@
 using testing::IsEmpty;
 
 namespace ash {
-namespace test {
 namespace {
 
 int64_t GetPrimaryDisplayId() {
@@ -1641,7 +1640,7 @@
 }
 
 TEST_F(ShelfViewTest, OverflowShelfColorIsDerivedFromWallpaper) {
-  test::WallpaperControllerTestApi wallpaper_test_api(
+  WallpaperControllerTestApi wallpaper_test_api(
       Shell::Get()->wallpaper_controller());
   const SkColor opaque_expected_color =
       wallpaper_test_api.ApplyColorProducingWallpaper();
@@ -3204,5 +3203,4 @@
   ASSERT_TRUE(test_api_->IsShowingOverflowBubble());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/shelf/shelf_widget_unittest.cc b/ash/shelf/shelf_widget_unittest.cc
index 0d05732a..4623f35 100644
--- a/ash/shelf/shelf_widget_unittest.cc
+++ b/ash/shelf/shelf_widget_unittest.cc
@@ -26,7 +26,7 @@
 namespace {
 
 ShelfWidget* GetShelfWidget() {
-  return test::AshTestBase::GetPrimaryShelf()->shelf_widget();
+  return AshTestBase::GetPrimaryShelf()->shelf_widget();
 }
 
 ShelfLayoutManager* GetShelfLayoutManager() {
@@ -43,7 +43,7 @@
                                      .ToString());
 }
 
-using ShelfWidgetTest = test::AshTestBase;
+using ShelfWidgetTest = AshTestBase;
 
 TEST_F(ShelfWidgetTest, TestAlignment) {
   UpdateDisplay("400x400");
@@ -320,7 +320,7 @@
   }
 }
 
-class ShelfWidgetAfterLoginTest : public test::AshTestBase {
+class ShelfWidgetAfterLoginTest : public AshTestBase {
  public:
   ShelfWidgetAfterLoginTest() { set_start_session(false); }
   ~ShelfWidgetAfterLoginTest() override = default;
diff --git a/ash/shelf/shelf_window_watcher_unittest.cc b/ash/shelf/shelf_window_watcher_unittest.cc
index 09c15f0..722963f 100644
--- a/ash/shelf/shelf_window_watcher_unittest.cc
+++ b/ash/shelf/shelf_window_watcher_unittest.cc
@@ -36,19 +36,19 @@
   return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
 }
 
-class ShelfWindowWatcherTest : public test::AshTestBase {
+class ShelfWindowWatcherTest : public AshTestBase {
  public:
   ShelfWindowWatcherTest() : model_(nullptr) {}
   ~ShelfWindowWatcherTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     model_ = Shell::Get()->shelf_model();
   }
 
   void TearDown() override {
     model_ = nullptr;
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
   static ShelfID CreateShelfItem(aura::Window* window) {
@@ -441,7 +441,7 @@
 }
 
 // Ensures ShelfWindowWatcher supports windows opened prior to session start.
-using ShelfWindowWatcherSessionStartTest = test::NoSessionAshTestBase;
+using ShelfWindowWatcherSessionStartTest = NoSessionAshTestBase;
 TEST_F(ShelfWindowWatcherSessionStartTest, PreExistingWindow) {
   ShelfModel* model = Shell::Get()->shelf_model();
   ASSERT_FALSE(
diff --git a/ash/shell.h b/ash/shell.h
index bc6949b3..88bf2b85 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -172,11 +172,6 @@
 enum class Config;
 enum class LoginStatus;
 
-namespace test {
-class ShellTestApi;
-class SmsObserverTest;
-}
-
 // Shell is a singleton object that presents the Shell API and implements the
 // RootWindow's delegate interface.
 //
@@ -623,8 +618,8 @@
   friend class AcceleratorControllerTest;
   friend class RootWindowController;
   friend class ScopedRootWindowForNewWindows;
+  friend class ShellTestApi;
   friend class SmsObserverTest;
-  friend class test::ShellTestApi;
 
   Shell(std::unique_ptr<ShellDelegate> shell_delegate,
         std::unique_ptr<ShellPort> shell_port);
diff --git a/ash/shell/example_session_controller_client.h b/ash/shell/example_session_controller_client.h
index bb350798..cd71a3b2 100644
--- a/ash/shell/example_session_controller_client.h
+++ b/ash/shell/example_session_controller_client.h
@@ -14,8 +14,7 @@
 
 namespace shell {
 
-class ExampleSessionControllerClient
-    : public test::TestSessionControllerClient {
+class ExampleSessionControllerClient : public TestSessionControllerClient {
  public:
   explicit ExampleSessionControllerClient(SessionController* controller);
   ~ExampleSessionControllerClient() override;
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc
index 6b7d87f4..28a9ac71 100644
--- a/ash/shell_unittest.cc
+++ b/ash/shell_unittest.cc
@@ -131,7 +131,7 @@
 
 }  // namespace
 
-class ShellTest : public test::AshTestBase {
+class ShellTest : public AshTestBase {
  public:
   views::Widget* CreateTestWindow(views::Widget::InitParams params) {
     views::Widget* widget = new views::Widget;
@@ -466,7 +466,7 @@
 
   Shell* shell = Shell::Get();
   ui::EventTargetTestApi test_api(shell);
-  test::ShellTestApi shell_test_api(shell);
+  ShellTestApi shell_test_api(shell);
 
   const ui::EventHandlerList& handlers = test_api.pre_target_handlers();
   ui::EventHandlerList::const_iterator cursor_filter =
@@ -512,7 +512,7 @@
 // everything is ok, we won't crash. If there is a bug, window's destructor will
 // notify some deleted object (say VideoDetector or ActivationController) and
 // this will crash.
-class ShellTest2 : public test::AshTestBase {
+class ShellTest2 : public AshTestBase {
  public:
   ShellTest2() {}
   ~ShellTest2() override {}
diff --git a/ash/sticky_keys/sticky_keys_overlay_unittest.cc b/ash/sticky_keys/sticky_keys_overlay_unittest.cc
index f99cee4..f9ff7ae 100644
--- a/ash/sticky_keys/sticky_keys_overlay_unittest.cc
+++ b/ash/sticky_keys/sticky_keys_overlay_unittest.cc
@@ -16,7 +16,7 @@
 
 namespace ash {
 
-using StickyKeysOverlayTest = test::AshTestBase;
+using StickyKeysOverlayTest = AshTestBase;
 
 TEST_F(StickyKeysOverlayTest, OverlayVisibility) {
   StickyKeysOverlay overlay;
diff --git a/ash/sticky_keys/sticky_keys_unittest.cc b/ash/sticky_keys/sticky_keys_unittest.cc
index c1f32a9..2c07f749 100644
--- a/ash/sticky_keys/sticky_keys_unittest.cc
+++ b/ash/sticky_keys/sticky_keys_unittest.cc
@@ -32,12 +32,12 @@
 
 }  // namespace
 
-class StickyKeysTest : public test::AshTestBase {
+class StickyKeysTest : public AshTestBase {
  protected:
   StickyKeysTest() : target_(NULL), root_window_(NULL) {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
     // |target_| owned by root window of shell. It is still safe to delete
     // it ourselves.
@@ -49,7 +49,7 @@
 #endif
   }
 
-  void TearDown() override { test::AshTestBase::TearDown(); }
+  void TearDown() override { AshTestBase::TearDown(); }
 
   virtual void OnShortcutPressed() {
     if (target_) {
diff --git a/ash/system/audio/tray_audio_unittest.cc b/ash/system/audio/tray_audio_unittest.cc
index 1e26c6d..0b61152 100644
--- a/ash/system/audio/tray_audio_unittest.cc
+++ b/ash/system/audio/tray_audio_unittest.cc
@@ -11,7 +11,7 @@
 
 namespace ash {
 
-using TrayAudioTest = test::AshTestBase;
+using TrayAudioTest = AshTestBase;
 
 // Tests that the volume popup view can be explicitly shown.
 TEST_F(TrayAudioTest, ShowPopUpVolumeView) {
diff --git a/ash/system/bluetooth/tray_bluetooth_helper_unittest.cc b/ash/system/bluetooth/tray_bluetooth_helper_unittest.cc
index c9107e36..0b37ac57 100644
--- a/ash/system/bluetooth/tray_bluetooth_helper_unittest.cc
+++ b/ash/system/bluetooth/tray_bluetooth_helper_unittest.cc
@@ -17,7 +17,7 @@
 namespace ash {
 namespace {
 
-using TrayBluetoothHelperTest = test::AshTestBase;
+using TrayBluetoothHelperTest = AshTestBase;
 
 // Tests basic functionality like turning Bluetooth on and off.
 TEST_F(TrayBluetoothHelperTest, Basics) {
diff --git a/ash/system/brightness/tray_brightness_unittest.cc b/ash/system/brightness/tray_brightness_unittest.cc
index e1f4e08..757cd483 100644
--- a/ash/system/brightness/tray_brightness_unittest.cc
+++ b/ash/system/brightness/tray_brightness_unittest.cc
@@ -15,7 +15,7 @@
 
 namespace ash {
 
-class TrayBrightnessTest : public test::AshTestBase {
+class TrayBrightnessTest : public AshTestBase {
  public:
   TrayBrightnessTest() {}
   ~TrayBrightnessTest() override {}
diff --git a/ash/system/date/date_view_unittest.cc b/ash/system/date/date_view_unittest.cc
index ea6df969..6b3a76b 100644
--- a/ash/system/date/date_view_unittest.cc
+++ b/ash/system/date/date_view_unittest.cc
@@ -10,7 +10,7 @@
 namespace ash {
 namespace tray {
 
-class TimeViewTest : public test::AshTestBase {
+class TimeViewTest : public AshTestBase {
  public:
   TimeViewTest() {}
   ~TimeViewTest() override {}
diff --git a/ash/system/enterprise/tray_enterprise_unittest.cc b/ash/system/enterprise/tray_enterprise_unittest.cc
index 9ccedc9..d03657b1 100644
--- a/ash/system/enterprise/tray_enterprise_unittest.cc
+++ b/ash/system/enterprise/tray_enterprise_unittest.cc
@@ -13,7 +13,7 @@
 
 namespace ash {
 
-using TrayEnterpriseTest = test::AshTestBase;
+using TrayEnterpriseTest = AshTestBase;
 
 TEST_F(TrayEnterpriseTest, ItemVisible) {
   SystemTray* system_tray = GetPrimarySystemTray();
diff --git a/ash/system/ime/tray_ime_chromeos_unittest.cc b/ash/system/ime/tray_ime_chromeos_unittest.cc
index 533c3e5..6597c66 100644
--- a/ash/system/ime/tray_ime_chromeos_unittest.cc
+++ b/ash/system/ime/tray_ime_chromeos_unittest.cc
@@ -22,7 +22,7 @@
 
 namespace ash {
 
-class TrayIMETest : public test::AshTestBase {
+class TrayIMETest : public AshTestBase {
  public:
   TrayIMETest() {}
   ~TrayIMETest() override {}
@@ -51,7 +51,7 @@
   void SuppressKeyboard();
   void RestoreKeyboard();
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override;
   void TearDown() override;
 
@@ -140,7 +140,7 @@
 }
 
 void TrayIMETest::SetUp() {
-  test::AshTestBase::SetUp();
+  AshTestBase::SetUp();
   tray_.reset(new TrayIME(GetPrimarySystemTray()));
   default_view_.reset(tray_->CreateDefaultView(LoginStatus::USER));
   detailed_view_.reset(tray_->CreateDetailedView(LoginStatus::USER));
@@ -167,7 +167,7 @@
   tray_.reset();
   default_view_.reset();
   detailed_view_.reset();
-  test::AshTestBase::TearDown();
+  AshTestBase::TearDown();
 }
 
 // Tests that if the keyboard is not suppressed the default view is hidden
diff --git a/ash/system/ime_menu/ime_menu_tray_unittest.cc b/ash/system/ime_menu/ime_menu_tray_unittest.cc
index ce8e9a7..fb2a9a98 100644
--- a/ash/system/ime_menu/ime_menu_tray_unittest.cc
+++ b/ash/system/ime_menu/ime_menu_tray_unittest.cc
@@ -48,13 +48,13 @@
 
 }  // namespace
 
-class ImeMenuTrayTest : public test::AshTestBase {
+class ImeMenuTrayTest : public AshTestBase {
  public:
   ImeMenuTrayTest() {}
   ~ImeMenuTrayTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     // MockInputMethodManager enables emoji, handwriting and voice input by
     // default.
     InputMethodManager::Initialize(new MockInputMethodManager);
@@ -62,7 +62,7 @@
 
   void TearDown() override {
     InputMethodManager::Shutdown();
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
  protected:
diff --git a/ash/system/keyboard_brightness/tray_keyboard_brightness_unittest.cc b/ash/system/keyboard_brightness/tray_keyboard_brightness_unittest.cc
index ecc0383a..b720a24 100644
--- a/ash/system/keyboard_brightness/tray_keyboard_brightness_unittest.cc
+++ b/ash/system/keyboard_brightness/tray_keyboard_brightness_unittest.cc
@@ -15,7 +15,7 @@
 
 namespace ash {
 
-class TrayKeyboardBrightnessTest : public test::AshTestBase {
+class TrayKeyboardBrightnessTest : public AshTestBase {
  public:
   TrayKeyboardBrightnessTest() {}
   ~TrayKeyboardBrightnessTest() override {}
diff --git a/ash/system/lock_screen_action/lock_screen_action_tray_unittest.cc b/ash/system/lock_screen_action/lock_screen_action_tray_unittest.cc
index 2ae1ce8..c2ed06e 100644
--- a/ash/system/lock_screen_action/lock_screen_action_tray_unittest.cc
+++ b/ash/system/lock_screen_action/lock_screen_action_tray_unittest.cc
@@ -53,7 +53,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestTrayActionClient);
 };
 
-class LockScreenActionTrayTest : public test::AshTestBase {
+class LockScreenActionTrayTest : public AshTestBase {
  public:
   LockScreenActionTrayTest() = default;
   ~LockScreenActionTrayTest() override = default;
diff --git a/ash/system/media_security/multi_profile_media_tray_item_unittest.cc b/ash/system/media_security/multi_profile_media_tray_item_unittest.cc
index 2be1cca5..d0b96ed 100644
--- a/ash/system/media_security/multi_profile_media_tray_item_unittest.cc
+++ b/ash/system/media_security/multi_profile_media_tray_item_unittest.cc
@@ -21,7 +21,7 @@
 
 namespace ash {
 
-class MultiProfileMediaTrayItemTest : public test::AshTestBase {
+class MultiProfileMediaTrayItemTest : public AshTestBase {
  public:
   MultiProfileMediaTrayItemTest() {}
   ~MultiProfileMediaTrayItemTest() override {}
diff --git a/ash/system/network/network_icon_unittest.cc b/ash/system/network/network_icon_unittest.cc
index ef1cdcd5..c9081d66 100644
--- a/ash/system/network/network_icon_unittest.cc
+++ b/ash/system/network/network_icon_unittest.cc
@@ -18,13 +18,13 @@
 
 namespace network_icon {
 
-class NetworkIconTest : public test::AshTestBase {
+class NetworkIconTest : public AshTestBase {
  public:
   NetworkIconTest() {}
   ~NetworkIconTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     chromeos::NetworkHandler::Initialize();
 
     tether_network =
@@ -47,7 +47,7 @@
   void TearDown() override {
     PurgeNetworkIconCache();
     chromeos::NetworkHandler::Shutdown();
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
   gfx::Image ImageForNetwork(chromeos::NetworkState* network) {
diff --git a/ash/system/network/sms_observer_unittest.cc b/ash/system/network/sms_observer_unittest.cc
index 069c4f4..9cd75c0 100644
--- a/ash/system/network/sms_observer_unittest.cc
+++ b/ash/system/network/sms_observer_unittest.cc
@@ -38,7 +38,7 @@
 
 }  // namespace
 
-class SmsObserverTest : public test::AshTestBase {
+class SmsObserverTest : public AshTestBase {
  public:
   SmsObserverTest() {}
   ~SmsObserverTest() override {}
diff --git a/ash/system/network/tray_network_unittest.cc b/ash/system/network/tray_network_unittest.cc
index ac421aad..81ea231 100644
--- a/ash/system/network/tray_network_unittest.cc
+++ b/ash/system/network/tray_network_unittest.cc
@@ -22,7 +22,7 @@
 namespace ash {
 namespace {
 
-class TrayNetworkTest : public test::AshTestBase {
+class TrayNetworkTest : public AshTestBase {
  public:
   TrayNetworkTest() = default;
   ~TrayNetworkTest() override = default;
@@ -32,7 +32,7 @@
     chromeos::DBusThreadManager::Initialize();
     // Initializing NetworkHandler before ash is more like production.
     chromeos::NetworkHandler::Initialize();
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     // Mash doesn't do this yet, so don't do it in tests either.
     // http://crbug.com/718072
     if (Shell::GetAshConfig() != Config::MASH) {
@@ -48,7 +48,7 @@
     if (Shell::GetAshConfig() != Config::MASH) {
       chromeos::NetworkHandler::Get()->ShutdownPrefServices();
     }
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
     chromeos::NetworkHandler::Shutdown();
     chromeos::DBusThreadManager::Shutdown();
   }
diff --git a/ash/system/night_light/night_light_controller_unittest.cc b/ash/system/night_light/night_light_controller_unittest.cc
index c3427a1f..c8813b7 100644
--- a/ash/system/night_light/night_light_controller_unittest.cc
+++ b/ash/system/night_light/night_light_controller_unittest.cc
@@ -109,7 +109,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestDelegate);
 };
 
-class NightLightTest : public test::AshTestBase {
+class NightLightTest : public AshTestBase {
  public:
   NightLightTest() = default;
   ~NightLightTest() override = default;
@@ -123,9 +123,9 @@
 
   TestDelegate* delegate() const { return delegate_; }
 
-  // ash::test::AshTestBase:
+  // AshTestBase:
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     CreateTestUserSessions();
     Shell::RegisterPrefs(user1_pref_service_.registry());
     Shell::RegisterPrefs(user2_pref_service_.registry());
diff --git a/ash/system/night_light/tray_night_light_unittest.cc b/ash/system/night_light/tray_night_light_unittest.cc
index 3a8ca56..02885af 100644
--- a/ash/system/night_light/tray_night_light_unittest.cc
+++ b/ash/system/night_light/tray_night_light_unittest.cc
@@ -20,14 +20,14 @@
 
 constexpr char kFakeUserEmail[] = "fake_user@nightlight";
 
-class TrayNightLightTest : public test::AshTestBase {
+class TrayNightLightTest : public AshTestBase {
  public:
   TrayNightLightTest() = default;
   ~TrayNightLightTest() override = default;
 
-  // ash::test::AshTestBase:
+  // AshTestBase:
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     GetSessionControllerClient()->Reset();
     GetSessionControllerClient()->AddUserSession(kFakeUserEmail);
     Shell::RegisterPrefs(pref_service_.registry());
diff --git a/ash/system/overview/overview_button_tray_unittest.cc b/ash/system/overview/overview_button_tray_unittest.cc
index 97f2a72..f6c1a19 100644
--- a/ash/system/overview/overview_button_tray_unittest.cc
+++ b/ash/system/overview/overview_button_tray_unittest.cc
@@ -67,7 +67,7 @@
 
 }  // namespace
 
-class OverviewButtonTrayTest : public test::AshTestBase {
+class OverviewButtonTrayTest : public AshTestBase {
  public:
   OverviewButtonTrayTest() {}
   ~OverviewButtonTrayTest() override {}
diff --git a/ash/system/palette/tools/create_note_unittest.cc b/ash/system/palette/tools/create_note_unittest.cc
index 26712d4..1d01a1b 100644
--- a/ash/system/palette/tools/create_note_unittest.cc
+++ b/ash/system/palette/tools/create_note_unittest.cc
@@ -19,16 +19,15 @@
 namespace {
 
 // Base class for all create note ash tests.
-class CreateNoteTest : public test::AshTestBase {
+class CreateNoteTest : public AshTestBase {
  public:
   CreateNoteTest() {}
   ~CreateNoteTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
-    test::ShellTestApi().SetPaletteDelegate(
-        base::MakeUnique<TestPaletteDelegate>());
+    ShellTestApi().SetPaletteDelegate(base::MakeUnique<TestPaletteDelegate>());
 
     palette_tool_delegate_ = base::MakeUnique<MockPaletteToolDelegate>();
     tool_ = base::MakeUnique<CreateNoteAction>(palette_tool_delegate_.get());
diff --git a/ash/system/palette/tools/metalayer_unittest.cc b/ash/system/palette/tools/metalayer_unittest.cc
index f50fde8..9cd44899 100644
--- a/ash/system/palette/tools/metalayer_unittest.cc
+++ b/ash/system/palette/tools/metalayer_unittest.cc
@@ -19,16 +19,15 @@
 namespace {
 
 // Base class for all metalayer ash tests.
-class MetalayerToolTest : public test::AshTestBase {
+class MetalayerToolTest : public AshTestBase {
  public:
   MetalayerToolTest() {}
   ~MetalayerToolTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
-    test::ShellTestApi().SetPaletteDelegate(
-        base::MakeUnique<TestPaletteDelegate>());
+    ShellTestApi().SetPaletteDelegate(base::MakeUnique<TestPaletteDelegate>());
 
     palette_tool_delegate_ = base::MakeUnique<MockPaletteToolDelegate>();
     tool_ = base::MakeUnique<MetalayerMode>(palette_tool_delegate_.get());
diff --git a/ash/system/palette/tools/screenshot_unittest.cc b/ash/system/palette/tools/screenshot_unittest.cc
index 0bdee1f..3b5f012a5 100644
--- a/ash/system/palette/tools/screenshot_unittest.cc
+++ b/ash/system/palette/tools/screenshot_unittest.cc
@@ -19,16 +19,15 @@
 namespace {
 
 // Base class for all create note ash tests.
-class ScreenshotToolTest : public test::AshTestBase {
+class ScreenshotToolTest : public AshTestBase {
  public:
   ScreenshotToolTest() {}
   ~ScreenshotToolTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
-    test::ShellTestApi().SetPaletteDelegate(
-        base::MakeUnique<TestPaletteDelegate>());
+    ShellTestApi().SetPaletteDelegate(base::MakeUnique<TestPaletteDelegate>());
 
     palette_tool_delegate_ = base::MakeUnique<MockPaletteToolDelegate>();
   }
diff --git a/ash/system/power/power_event_observer_unittest.cc b/ash/system/power/power_event_observer_unittest.cc
index 17b58667..ad4ef01 100644
--- a/ash/system/power/power_event_observer_unittest.cc
+++ b/ash/system/power/power_event_observer_unittest.cc
@@ -17,20 +17,20 @@
 
 namespace ash {
 
-class PowerEventObserverTest : public test::AshTestBase {
+class PowerEventObserverTest : public AshTestBase {
  public:
   PowerEventObserverTest() {}
   ~PowerEventObserverTest() override {}
 
-  // test::AshTestBase::SetUp() overrides:
+  // AshTestBase:
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     observer_.reset(new PowerEventObserver());
   }
 
   void TearDown() override {
     observer_.reset();
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
  protected:
diff --git a/ash/system/power/power_status_view_unittest.cc b/ash/system/power/power_status_view_unittest.cc
index 99907e8f..3c5a441 100644
--- a/ash/system/power/power_status_view_unittest.cc
+++ b/ash/system/power/power_status_view_unittest.cc
@@ -16,20 +16,20 @@
 
 namespace ash {
 
-class PowerStatusViewTest : public test::AshTestBase {
+class PowerStatusViewTest : public AshTestBase {
  public:
   PowerStatusViewTest() {}
   ~PowerStatusViewTest() override {}
 
   // Overridden from testing::Test:
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     view_.reset(new PowerStatusView());
   }
 
   void TearDown() override {
     view_.reset();
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
  protected:
diff --git a/ash/system/power/tablet_power_button_controller_unittest.cc b/ash/system/power/tablet_power_button_controller_unittest.cc
index 239248a0..76615a20 100644
--- a/ash/system/power/tablet_power_button_controller_unittest.cc
+++ b/ash/system/power/tablet_power_button_controller_unittest.cc
@@ -28,7 +28,6 @@
 #include "ui/events/test/event_generator.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -705,5 +704,4 @@
   EXPECT_FALSE(GetBacklightsForcedOff());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/system/power/tray_power_unittest.cc b/ash/system/power/tray_power_unittest.cc
index fcdbb4a..6041294 100644
--- a/ash/system/power/tray_power_unittest.cc
+++ b/ash/system/power/tray_power_unittest.cc
@@ -68,7 +68,7 @@
 
 namespace ash {
 
-class TrayPowerTest : public test::AshTestBase {
+class TrayPowerTest : public AshTestBase {
  public:
   TrayPowerTest() {}
   ~TrayPowerTest() override {}
@@ -76,9 +76,9 @@
   MockMessageCenter* message_center() { return message_center_.get(); }
   TrayPower* tray_power() { return tray_power_.get(); }
 
-  // test::AshTestBase::SetUp() overrides:
+  // AshTestBase:
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     message_center_.reset(new MockMessageCenter());
     tray_power_.reset(new TrayPower(NULL, message_center_.get()));
   }
@@ -86,7 +86,7 @@
   void TearDown() override {
     tray_power_.reset();
     message_center_.reset();
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
   TrayPower::NotificationState notification_state() const {
diff --git a/ash/system/power/video_activity_notifier_unittest.cc b/ash/system/power/video_activity_notifier_unittest.cc
index cb8d8650..dea54c5 100644
--- a/ash/system/power/video_activity_notifier_unittest.cc
+++ b/ash/system/power/video_activity_notifier_unittest.cc
@@ -14,13 +14,13 @@
 
 namespace ash {
 
-class VideoActivityNotifierTest : public test::AshTestBase {
+class VideoActivityNotifierTest : public AshTestBase {
  public:
   VideoActivityNotifierTest() {}
   ~VideoActivityNotifierTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     power_client_ = static_cast<chromeos::FakePowerManagerClient*>(
         chromeos::DBusThreadManager::Get()->GetPowerManagerClient());
     detector_.reset(new VideoDetector());
@@ -30,7 +30,7 @@
   void TearDown() override {
     notifier_.reset();
     detector_.reset();
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
  protected:
diff --git a/ash/system/rotation/tray_rotation_lock_unittest.cc b/ash/system/rotation/tray_rotation_lock_unittest.cc
index a48b59e5..f463c0d 100644
--- a/ash/system/rotation/tray_rotation_lock_unittest.cc
+++ b/ash/system/rotation/tray_rotation_lock_unittest.cc
@@ -26,7 +26,7 @@
 
 namespace ash {
 
-class TrayRotationLockTest : public test::AshTestBase {
+class TrayRotationLockTest : public AshTestBase {
  public:
   TrayRotationLockTest() {}
   ~TrayRotationLockTest() override {}
@@ -55,7 +55,7 @@
   // SetUpForStatusAreaWidget in order to initial the components.
   void TearDownViews();
 
-  // test::AshTestBase:
+  // AshTestBase:
   void SetUp() override;
   void TearDown() override;
 
@@ -99,13 +99,13 @@
   // visible on internal primary displays.
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       ::switches::kUseFirstDisplayAsInternal);
-  test::AshTestBase::SetUp();
+  AshTestBase::SetUp();
   SetUpForStatusAreaWidget(StatusAreaWidgetTestHelper::GetStatusAreaWidget());
 }
 
 void TrayRotationLockTest::TearDown() {
   TearDownViews();
-  test::AshTestBase::TearDown();
+  AshTestBase::TearDown();
 }
 
 // Tests that when the tray view is initially created, that it is created
diff --git a/ash/system/screen_layout_observer_unittest.cc b/ash/system/screen_layout_observer_unittest.cc
index 502fb39b..f0079ace 100644
--- a/ash/system/screen_layout_observer_unittest.cc
+++ b/ash/system/screen_layout_observer_unittest.cc
@@ -25,7 +25,7 @@
 
 namespace ash {
 
-class ScreenLayoutObserverTest : public test::AshTestBase {
+class ScreenLayoutObserverTest : public AshTestBase {
  public:
   ScreenLayoutObserverTest();
   ~ScreenLayoutObserverTest() override;
diff --git a/ash/system/screen_security/screen_tray_item_unittest.cc b/ash/system/screen_security/screen_tray_item_unittest.cc
index 122c478..62c655c 100644
--- a/ash/system/screen_security/screen_tray_item_unittest.cc
+++ b/ash/system/screen_security/screen_tray_item_unittest.cc
@@ -36,7 +36,7 @@
       ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE));
 }
 
-class ScreenTrayItemTest : public test::AshTestBase {
+class ScreenTrayItemTest : public AshTestBase {
  public:
   ScreenTrayItemTest() : tray_item_(NULL), stop_callback_hit_count_(0) {}
   ~ScreenTrayItemTest() override {}
@@ -192,7 +192,7 @@
   EXPECT_FALSE(tray_item->tray_view()->visible());
 
   std::vector<SystemTrayItem*> tray_items =
-      test::AshTestBase::GetPrimarySystemTray()->GetTrayItems();
+      AshTestBase::GetPrimarySystemTray()->GetTrayItems();
   EXPECT_NE(std::find(tray_items.begin(), tray_items.end(), tray_item),
             tray_items.end());
 
@@ -200,16 +200,16 @@
   EXPECT_TRUE(tray_item->tray_view()->visible());
 
   // The default view should be created in a new bubble.
-  test::AshTestBase::GetPrimarySystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
+  AshTestBase::GetPrimarySystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
   EXPECT_TRUE(tray_item->default_view());
-  test::AshTestBase::GetPrimarySystemTray()->CloseSystemBubble();
+  AshTestBase::GetPrimarySystemTray()->CloseSystemBubble();
   EXPECT_FALSE(tray_item->default_view());
 
   test->StopSession();
   EXPECT_FALSE(tray_item->tray_view()->visible());
 
   // The default view should not be visible because session is stopped.
-  test::AshTestBase::GetPrimarySystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
+  AshTestBase::GetPrimarySystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
   EXPECT_FALSE(tray_item->default_view()->visible());
 }
 
diff --git a/ash/system/session/tray_session_length_limit.h b/ash/system/session/tray_session_length_limit.h
index 3bd8032a..c4476ccf 100644
--- a/ash/system/session/tray_session_length_limit.h
+++ b/ash/system/session/tray_session_length_limit.h
@@ -15,9 +15,6 @@
 #include "base/timer/timer.h"
 
 namespace ash {
-namespace test {
-class TraySessionLengthLimitTest;
-}
 
 class LabelTrayView;
 
@@ -39,7 +36,7 @@
   void OnSessionLengthLimitChanged() override;
 
  private:
-  friend class test::TraySessionLengthLimitTest;
+  friend class TraySessionLengthLimitTest;
 
   static const char kNotificationId[];
 
diff --git a/ash/system/session/tray_session_length_limit_unittest.cc b/ash/system/session/tray_session_length_limit_unittest.cc
index f27574d..4015aaf 100644
--- a/ash/system/session/tray_session_length_limit_unittest.cc
+++ b/ash/system/session/tray_session_length_limit_unittest.cc
@@ -17,7 +17,6 @@
 #include "ui/message_center/notification_types.h"
 
 namespace ash {
-namespace test {
 
 class TraySessionLengthLimitTest : public AshTestBase {
  public:
@@ -183,5 +182,4 @@
   EXPECT_TRUE(GetNotification());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/system/status_area_widget_unittest.cc b/ash/system/status_area_widget_unittest.cc
index 873f0488..7db3a02c 100644
--- a/ash/system/status_area_widget_unittest.cc
+++ b/ash/system/status_area_widget_unittest.cc
@@ -28,7 +28,7 @@
 
 namespace ash {
 
-using StatusAreaWidgetTest = test::AshTestBase;
+using StatusAreaWidgetTest = AshTestBase;
 
 // Tests that status area trays are constructed.
 TEST_F(StatusAreaWidgetTest, Basics) {
@@ -74,7 +74,7 @@
   int reverse_focus_out_count() { return reverse_focus_out_count_; }
 
  protected:
-  // StatusAreaFocusObserver overridden:
+  // StatusAreaFocusObserver:
   void OnFocusOut(bool reverse) override {
     reverse ? ++reverse_focus_out_count_ : ++focus_out_count_;
   }
@@ -86,12 +86,12 @@
   DISALLOW_COPY_AND_ASSIGN(StatusAreaFocusTestObserver);
 };
 
-class StatusAreaWidgetFocusTest : public test::AshTestBase {
+class StatusAreaWidgetFocusTest : public AshTestBase {
  public:
   StatusAreaWidgetFocusTest() {}
   ~StatusAreaWidgetFocusTest() override {}
 
-  // test::AshTestBase overridden:
+  // AshTestBase:
   void SetUp() override {
     AshTestBase::SetUp();
     test_observer_.reset(new StatusAreaFocusTestObserver);
@@ -99,7 +99,7 @@
         test_observer_.get());
   }
 
-  // test::AshTestBase overridden:
+  // AshTestBase:
   void TearDown() override {
     Shell::Get()->system_tray_notifier()->RemoveStatusAreaFocusObserver(
         test_observer_.get());
@@ -126,7 +126,7 @@
   // Set session state to LOCKED.
   SessionController* session = Shell::Get()->session_controller();
   ASSERT_TRUE(session->IsActiveUserSessionStarted());
-  test::TestSessionControllerClient* client = GetSessionControllerClient();
+  TestSessionControllerClient* client = GetSessionControllerClient();
   client->SetSessionState(SessionState::LOCKED);
   ASSERT_TRUE(session->IsScreenLocked());
 
@@ -177,7 +177,7 @@
   EXPECT_EQ(1, test_observer_->reverse_focus_out_count());
 }
 
-class StatusAreaWidgetPaletteTest : public test::AshTestBase {
+class StatusAreaWidgetPaletteTest : public AshTestBase {
  public:
   StatusAreaWidgetPaletteTest() {}
   ~StatusAreaWidgetPaletteTest() override {}
diff --git a/ash/system/supervised/tray_supervised_user_unittest.cc b/ash/system/supervised/tray_supervised_user_unittest.cc
index 8faf755..b3e419a 100644
--- a/ash/system/supervised/tray_supervised_user_unittest.cc
+++ b/ash/system/supervised/tray_supervised_user_unittest.cc
@@ -25,7 +25,7 @@
 namespace ash {
 
 // Tests handle creating their own sessions.
-class TraySupervisedUserTest : public test::NoSessionAshTestBase {
+class TraySupervisedUserTest : public NoSessionAshTestBase {
  public:
   TraySupervisedUserTest() {}
   ~TraySupervisedUserTest() override {}
@@ -57,7 +57,7 @@
   ASSERT_FALSE(session->IsActiveUserSessionStarted());
 
   // Simulate a supervised user logging in.
-  test::TestSessionControllerClient* client = GetSessionControllerClient();
+  TestSessionControllerClient* client = GetSessionControllerClient();
   client->Reset();
   client->AddUserSession("child@test.com", user_manager::USER_TYPE_SUPERVISED);
   client->SetSessionState(session_manager::SessionState::ACTIVE);
@@ -108,7 +108,7 @@
   EXPECT_FALSE(tray->CreateDefaultView(unused));
 
   // Simulate a supervised user logging in.
-  test::TestSessionControllerClient* client = GetSessionControllerClient();
+  TestSessionControllerClient* client = GetSessionControllerClient();
   client->Reset();
   client->AddUserSession("child@test.com", user_manager::USER_TYPE_SUPERVISED);
   client->SetSessionState(session_manager::SessionState::ACTIVE);
diff --git a/ash/system/tiles/tray_tiles_unittest.cc b/ash/system/tiles/tray_tiles_unittest.cc
index 50a4920..160f1622 100644
--- a/ash/system/tiles/tray_tiles_unittest.cc
+++ b/ash/system/tiles/tray_tiles_unittest.cc
@@ -18,19 +18,19 @@
 namespace ash {
 
 // Tests manually control their session state.
-class TrayTilesTest : public test::NoSessionAshTestBase {
+class TrayTilesTest : public NoSessionAshTestBase {
  public:
   TrayTilesTest() {}
   ~TrayTilesTest() override {}
 
   void SetUp() override {
-    test::NoSessionAshTestBase::SetUp();
+    NoSessionAshTestBase::SetUp();
     tray_tiles_.reset(new TrayTiles(GetPrimarySystemTray()));
   }
 
   void TearDown() override {
     tray_tiles_.reset();
-    test::NoSessionAshTestBase::TearDown();
+    NoSessionAshTestBase::TearDown();
   }
 
   views::CustomButton* GetSettingsButton() {
diff --git a/ash/system/toast/toast_manager_unittest.cc b/ash/system/toast/toast_manager_unittest.cc
index 30c9bfd0d..1cf1135 100644
--- a/ash/system/toast/toast_manager_unittest.cc
+++ b/ash/system/toast/toast_manager_unittest.cc
@@ -26,14 +26,14 @@
   ~DummyEvent() override {}
 };
 
-class ToastManagerTest : public test::AshTestBase {
+class ToastManagerTest : public AshTestBase {
  public:
   ToastManagerTest() {}
   ~ToastManagerTest() override {}
 
  private:
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
     manager_ = Shell::Get()->toast_manager();
 
diff --git a/ash/system/tray/system_tray_unittest.cc b/ash/system/tray/system_tray_unittest.cc
index 773f710a..41e30c25 100644
--- a/ash/system/tray/system_tray_unittest.cc
+++ b/ash/system/tray/system_tray_unittest.cc
@@ -38,7 +38,6 @@
 #include "ui/views/widget/widget_delegate.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -853,5 +852,4 @@
   EXPECT_EQ(kSeparatorWidth, views::Separator::kThickness);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/system/tray/tray_details_view.h b/ash/system/tray/tray_details_view.h
index f046fcdc..e7f3162 100644
--- a/ash/system/tray/tray_details_view.h
+++ b/ash/system/tray/tray_details_view.h
@@ -28,9 +28,6 @@
 }  // namespace views
 
 namespace ash {
-namespace test {
-class TrayDetailsViewTest;
-}  // namespace test
 
 class HoverHighlightView;
 class ScrollBorder;
@@ -135,7 +132,7 @@
   views::View* scroll_content() const { return scroll_content_; }
 
  private:
-  friend class test::TrayDetailsViewTest;
+  friend class TrayDetailsViewTest;
 
   // Overridden to handle clicks on subclass-specific views.
   virtual void HandleViewClicked(views::View* view);
diff --git a/ash/system/tray/tray_details_view_unittest.cc b/ash/system/tray/tray_details_view_unittest.cc
index 374062e..90559fe3 100644
--- a/ash/system/tray/tray_details_view_unittest.cc
+++ b/ash/system/tray/tray_details_view_unittest.cc
@@ -22,7 +22,6 @@
 #include "ui/views/widget/widget.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -230,5 +229,4 @@
   EXPECT_EQ(view2->layer(), layers[2]);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/system/tray/tray_event_filter_unittest.cc b/ash/system/tray/tray_event_filter_unittest.cc
index a002f30d..038f0fb 100644
--- a/ash/system/tray/tray_event_filter_unittest.cc
+++ b/ash/system/tray/tray_event_filter_unittest.cc
@@ -17,7 +17,7 @@
 
 namespace {
 
-class TrayEventFilterTest : public test::AshTestBase {
+class TrayEventFilterTest : public AshTestBase {
  public:
   TrayEventFilterTest() {}
   ~TrayEventFilterTest() override {}
diff --git a/ash/system/tray_tracing_unittest.cc b/ash/system/tray_tracing_unittest.cc
index f981191..a73231f 100644
--- a/ash/system/tray_tracing_unittest.cc
+++ b/ash/system/tray_tracing_unittest.cc
@@ -13,7 +13,7 @@
 namespace ash {
 namespace {
 
-using TrayTracingTest = test::AshTestBase;
+using TrayTracingTest = AshTestBase;
 
 // Tests that the icon becomes visible when the tray controller toggles it.
 TEST_F(TrayTracingTest, Visibility) {
diff --git a/ash/system/update/tray_update_unittest.cc b/ash/system/update/tray_update_unittest.cc
index df0d5c9..eeee000 100644
--- a/ash/system/update/tray_update_unittest.cc
+++ b/ash/system/update/tray_update_unittest.cc
@@ -15,7 +15,7 @@
 
 namespace ash {
 
-using TrayUpdateTest = test::AshTestBase;
+using TrayUpdateTest = AshTestBase;
 
 // Tests that the update icon becomes visible when an update becomes
 // available.
diff --git a/ash/system/user/tray_user_unittest.cc b/ash/system/user/tray_user_unittest.cc
index 82918c5..7e482c4 100644
--- a/ash/system/user/tray_user_unittest.cc
+++ b/ash/system/user/tray_user_unittest.cc
@@ -47,7 +47,7 @@
   return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
 }
 
-class TrayUserTest : public test::AshTestBase {
+class TrayUserTest : public AshTestBase {
  public:
   TrayUserTest() = default;
 
@@ -81,7 +81,7 @@
 };
 
 void TrayUserTest::SetUp() {
-  test::AshTestBase::SetUp();
+  AshTestBase::SetUp();
   tray_ = GetPrimarySystemTray();
 }
 
@@ -97,8 +97,8 @@
   GetSessionControllerClient()->SetSessionState(
       session_manager::SessionState::ACTIVE);
 
-  test::TestShellDelegate* shell_delegate =
-      static_cast<test::TestShellDelegate*>(Shell::Get()->shell_delegate());
+  TestShellDelegate* shell_delegate =
+      static_cast<TestShellDelegate*>(Shell::Get()->shell_delegate());
   shell_delegate->set_multi_profiles_enabled(multiprofile);
 
   // Instead of using the existing tray panels we create new ones which makes
diff --git a/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc b/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc
index f3218d6..9ccbe6e 100644
--- a/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc
+++ b/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc
@@ -25,7 +25,7 @@
 
 namespace ash {
 
-class AshPopupAlignmentDelegateTest : public test::AshTestBase {
+class AshPopupAlignmentDelegateTest : public AshTestBase {
  public:
   AshPopupAlignmentDelegateTest() {}
   ~AshPopupAlignmentDelegateTest() override {}
@@ -33,14 +33,14 @@
   void SetUp() override {
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         keyboard::switches::kEnableVirtualKeyboard);
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     SetAlignmentDelegate(
         base::MakeUnique<AshPopupAlignmentDelegate>(GetPrimaryShelf()));
   }
 
   void TearDown() override {
     alignment_delegate_.reset();
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
  protected:
diff --git a/ash/system/web_notification/web_notification_tray_unittest.cc b/ash/system/web_notification/web_notification_tray_unittest.cc
index 5a5d7ca..8a07cab 100644
--- a/ash/system/web_notification/web_notification_tray_unittest.cc
+++ b/ash/system/web_notification/web_notification_tray_unittest.cc
@@ -83,7 +83,7 @@
 
 }  // namespace
 
-class WebNotificationTrayTest : public test::AshTestBase {
+class WebNotificationTrayTest : public AshTestBase {
  public:
   WebNotificationTrayTest() {}
   ~WebNotificationTrayTest() override {}
@@ -91,7 +91,7 @@
   void TearDown() override {
     GetMessageCenter()->RemoveAllNotifications(
         false /* by_user */, message_center::MessageCenter::RemoveType::ALL);
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
  protected:
diff --git a/ash/test/ash_interactive_ui_test_base.cc b/ash/test/ash_interactive_ui_test_base.cc
index 4a7e6c0..02da1d4b 100644
--- a/ash/test/ash_interactive_ui_test_base.cc
+++ b/ash/test/ash_interactive_ui_test_base.cc
@@ -13,7 +13,6 @@
 #include "ui/gl/test/gl_surface_test_support.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -51,13 +50,12 @@
       resources_pack_path, ui::SCALE_FACTOR_NONE);
   env_ = aura::Env::CreateInstance();
 
-  test::AshTestBase::SetUp();
+  AshTestBase::SetUp();
 }
 
 void AshInteractiveUITestBase::TearDown() {
-  test::AshTestBase::TearDown();
+  AshTestBase::TearDown();
   env_.reset();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/ash_interactive_ui_test_base.h b/ash/test/ash_interactive_ui_test_base.h
index 0fb8cf8..7e5b0a4 100644
--- a/ash/test/ash_interactive_ui_test_base.h
+++ b/ash/test/ash_interactive_ui_test_base.h
@@ -16,7 +16,6 @@
 }
 
 namespace ash {
-namespace test {
 
 class AshInteractiveUITestBase : public AshTestBase {
  public:
@@ -30,10 +29,10 @@
 
  private:
   std::unique_ptr<aura::Env> env_;
+
   DISALLOW_COPY_AND_ASSIGN(AshInteractiveUITestBase);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_ASH_INTERACTIVE_UI_TEST_BASE_H_
diff --git a/ash/test/ash_perftests.cc b/ash/test/ash_perftests.cc
index a6a3e19..2bee2a0 100644
--- a/ash/test/ash_perftests.cc
+++ b/ash/test/ash_perftests.cc
@@ -11,7 +11,7 @@
 
 namespace {
 
-int RunHelper(ash::test::AshTestSuite* test_suite) {
+int RunHelper(ash::AshTestSuite* test_suite) {
   // In ash_perftests we want to use hardware GL. By adding this switch we can
   // set |use_software_gl| to false in gl_surface_test_support.cc.
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
@@ -22,7 +22,7 @@
 }  // namespace
 
 int main(int argc, char** argv) {
-  ash::test::AshTestSuite test_suite(argc, argv);
+  ash::AshTestSuite test_suite(argc, argv);
 
   mojo::edk::Init();
   return base::LaunchUnitTestsSerially(
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc
index 59e4992..8fd9c4f 100644
--- a/ash/test/ash_test_base.cc
+++ b/ash/test/ash_test_base.cc
@@ -54,7 +54,6 @@
 #endif
 
 namespace ash {
-namespace test {
 namespace {
 
 class AshEventGeneratorDelegate
@@ -494,5 +493,4 @@
   return ash_test_helper_->GetSecondaryDisplay();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h
index 9ed7c09..68ef2c23 100644
--- a/ash/test/ash_test_base.h
+++ b/ash/test/ash_test_base.h
@@ -49,13 +49,11 @@
 }
 
 namespace ash {
-class Shelf;
-class SystemTray;
-
-namespace test {
 
 class AshTestEnvironment;
 class AshTestHelper;
+class Shelf;
+class SystemTray;
 class TestScreenshotDelegate;
 class TestSessionControllerClient;
 
@@ -79,7 +77,7 @@
   static SystemTray* GetPrimarySystemTray();
 
   // Update the display configuration as given in |display_specs|.
-  // See ash::test::DisplayManagerTestApi::UpdateDisplay for more details.
+  // See ash::DisplayManagerTestApi::UpdateDisplay for more details.
   void UpdateDisplay(const std::string& display_specs);
 
   // Returns a root Window. Usually this is the active root Window, but that
@@ -220,7 +218,6 @@
   DISALLOW_COPY_AND_ASSIGN(NoSessionAshTestBase);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_ASH_TEST_BASE_H_
diff --git a/ash/test/ash_test_environment.h b/ash/test/ash_test_environment.h
index 7f5621f..11ac414 100644
--- a/ash/test/ash_test_environment.h
+++ b/ash/test/ash_test_environment.h
@@ -9,7 +9,6 @@
 #include <string>
 
 namespace ash {
-namespace test {
 
 class AshTestViewsDelegate;
 
@@ -42,7 +41,6 @@
   AshTestEnvironment() {}
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_ASH_TEST_ENVIRONMENT_H_
diff --git a/ash/test/ash_test_environment_content.cc b/ash/test/ash_test_environment_content.cc
index 9e484a3a..fd05e29 100644
--- a/ash/test/ash_test_environment_content.cc
+++ b/ash/test/ash_test_environment_content.cc
@@ -11,7 +11,6 @@
 #include "content/public/test/web_contents_tester.h"
 
 namespace ash {
-namespace test {
 namespace {
 
 class AshTestViewsDelegateContent : public AshTestViewsDelegate {
@@ -66,5 +65,4 @@
   return base::MakeUnique<AshTestViewsDelegateContent>();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/ash_test_environment_content.h b/ash/test/ash_test_environment_content.h
index dc4ff6b6..ec13f13 100644
--- a/ash/test/ash_test_environment_content.h
+++ b/ash/test/ash_test_environment_content.h
@@ -15,9 +15,6 @@
 namespace ash {
 
 class ShellContentState;
-
-namespace test {
-
 class TestShellContentState;
 
 // AshTestEnvironment implementation for tests that use content.
@@ -53,7 +50,6 @@
   DISALLOW_COPY_AND_ASSIGN(AshTestEnvironmentContent);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_ASH_TEST_ENVIRONMENT_CONTENT_H_
diff --git a/ash/test/ash_test_environment_default.cc b/ash/test/ash_test_environment_default.cc
index 225b6def..bcba280 100644
--- a/ash/test/ash_test_environment_default.cc
+++ b/ash/test/ash_test_environment_default.cc
@@ -10,7 +10,6 @@
 #include "base/test/scoped_task_environment.h"
 
 namespace ash {
-namespace test {
 namespace {
 
 class AshTestEnvironmentDefault : public AshTestEnvironment {
@@ -46,5 +45,4 @@
   return "ash_test_resources_100_percent.pak";
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
index 6cf9d7a..d48ec7c 100644
--- a/ash/test/ash_test_helper.cc
+++ b/ash/test/ash_test_helper.cc
@@ -57,7 +57,6 @@
 #include "ui/wm/core/wm_state.h"
 
 namespace ash {
-namespace test {
 
 // static
 Config AshTestHelper::config_ = Config::CLASSIC;
@@ -308,5 +307,4 @@
   Shell::CreateInstance(init_params);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/ash_test_helper.h b/ash/test/ash_test_helper.h
index 8390dda5..4c2f7621 100644
--- a/ash/test/ash_test_helper.h
+++ b/ash/test/ash_test_helper.h
@@ -44,7 +44,12 @@
 
 namespace ash {
 
+class AshTestEnvironment;
+class AshTestViewsDelegate;
 class RootWindowController;
+class TestScreenshotDelegate;
+class TestShellDelegate;
+class TestSessionControllerClient;
 
 enum class Config;
 
@@ -52,14 +57,6 @@
 class WindowManagerApplication;
 }
 
-namespace test {
-
-class AshTestEnvironment;
-class AshTestViewsDelegate;
-class TestScreenshotDelegate;
-class TestShellDelegate;
-class TestSessionControllerClient;
-
 // A helper class that does common initialization required for Ash. Creates a
 // root window and an ash::Shell instance with a test delegate.
 class AshTestHelper {
@@ -167,7 +164,6 @@
   DISALLOW_COPY_AND_ASSIGN(AshTestHelper);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_ASH_TEST_HELPER_H_
diff --git a/ash/test/ash_test_helper_unittest.cc b/ash/test/ash_test_helper_unittest.cc
index fc4986b..81933764f 100644
--- a/ash/test/ash_test_helper_unittest.cc
+++ b/ash/test/ash_test_helper_unittest.cc
@@ -20,9 +20,8 @@
 
   void SetUp() override {
     testing::Test::SetUp();
-    ash_test_environment_ = test::AshTestEnvironment::Create();
-    ash_test_helper_.reset(
-        new test::AshTestHelper(ash_test_environment_.get()));
+    ash_test_environment_ = AshTestEnvironment::Create();
+    ash_test_helper_.reset(new AshTestHelper(ash_test_environment_.get()));
     ash_test_helper_->SetUp(true);
   }
 
@@ -31,13 +30,13 @@
     testing::Test::TearDown();
   }
 
-  test::AshTestHelper* ash_test_helper() { return ash_test_helper_.get(); }
+  AshTestHelper* ash_test_helper() { return ash_test_helper_.get(); }
 
  protected:
-  std::unique_ptr<test::AshTestEnvironment> ash_test_environment_;
+  std::unique_ptr<AshTestEnvironment> ash_test_environment_;
 
  private:
-  std::unique_ptr<test::AshTestHelper> ash_test_helper_;
+  std::unique_ptr<AshTestHelper> ash_test_helper_;
 
   DISALLOW_COPY_AND_ASSIGN(AshTestHelperTest);
 };
diff --git a/ash/test/ash_test_suite.cc b/ash/test/ash_test_suite.cc
index 56e5c8b0..a4ea1f3 100644
--- a/ash/test/ash_test_suite.cc
+++ b/ash/test/ash_test_suite.cc
@@ -26,7 +26,6 @@
 #include "ui/gl/test/gl_surface_test_support.h"
 
 namespace ash {
-namespace test {
 namespace {
 
 class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient {
@@ -131,7 +130,7 @@
   const bool is_mus = base::CommandLine::ForCurrentProcess()->HasSwitch("mus");
   const bool is_mash =
       base::CommandLine::ForCurrentProcess()->HasSwitch("mash");
-  ash::test::AshTestHelper::config_ =
+  AshTestHelper::config_ =
       is_mus ? Config::MUS : is_mash ? Config::MASH : Config::CLASSIC;
 
   base::DiscardableMemoryAllocator::SetInstance(&discardable_memory_allocator_);
@@ -151,5 +150,4 @@
   base::TestSuite::Shutdown();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/ash_test_suite.h b/ash/test/ash_test_suite.h
index 4fac4285..06ced79 100644
--- a/ash/test/ash_test_suite.h
+++ b/ash/test/ash_test_suite.h
@@ -17,7 +17,6 @@
 }
 
 namespace ash {
-namespace test {
 
 class AshTestSuite : public base::TestSuite {
  public:
@@ -41,7 +40,6 @@
   DISALLOW_COPY_AND_ASSIGN(AshTestSuite);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_ASH_TEST_SUITE_H_
diff --git a/ash/test/ash_test_views_delegate.cc b/ash/test/ash_test_views_delegate.cc
index 980b6d32..9cc768f 100644
--- a/ash/test/ash_test_views_delegate.cc
+++ b/ash/test/ash_test_views_delegate.cc
@@ -8,7 +8,6 @@
 #include "ash/shell.h"
 
 namespace ash {
-namespace test {
 
 AshTestViewsDelegate::AshTestViewsDelegate() {}
 
@@ -35,5 +34,4 @@
   }
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/ash_test_views_delegate.h b/ash/test/ash_test_views_delegate.h
index f1539465..6486ccf9 100644
--- a/ash/test/ash_test_views_delegate.h
+++ b/ash/test/ash_test_views_delegate.h
@@ -9,7 +9,6 @@
 #include "ui/views/test/test_views_delegate.h"
 
 namespace ash {
-namespace test {
 
 class TestAccessibilityEventDelegate {
  public:
@@ -47,7 +46,6 @@
   DISALLOW_COPY_AND_ASSIGN(AshTestViewsDelegate);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_ASH_TEST_VIEWS_DELEGATE_H_
diff --git a/ash/test/ash_unittests.cc b/ash/test/ash_unittests.cc
index 6c2d8212..4f7557b 100644
--- a/ash/test/ash_unittests.cc
+++ b/ash/test/ash_unittests.cc
@@ -8,10 +8,10 @@
 #include "mojo/edk/embedder/embedder.h"
 
 int main(int argc, char** argv) {
-  ash::test::AshTestSuite test_suite(argc, argv);
+  ash::AshTestSuite test_suite(argc, argv);
 
   mojo::edk::Init();
   return base::LaunchUnitTests(
       argc, argv,
-      base::Bind(&ash::test::AshTestSuite::Run, base::Unretained(&test_suite)));
+      base::Bind(&ash::AshTestSuite::Run, base::Unretained(&test_suite)));
 }
diff --git a/ash/test/content/test_shell_content_state.cc b/ash/test/content/test_shell_content_state.cc
index b34200a..9566af4 100644
--- a/ash/test/content/test_shell_content_state.cc
+++ b/ash/test/content/test_shell_content_state.cc
@@ -7,7 +7,6 @@
 #include "content/public/test/test_browser_context.h"
 
 namespace ash {
-namespace test {
 
 TestShellContentState::TestShellContentState() {}
 TestShellContentState::~TestShellContentState() {}
@@ -33,5 +32,4 @@
   return nullptr;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/content/test_shell_content_state.h b/ash/test/content/test_shell_content_state.h
index 28869d1..5a6cc4c 100644
--- a/ash/test/content/test_shell_content_state.h
+++ b/ash/test/content/test_shell_content_state.h
@@ -15,7 +15,6 @@
 }
 
 namespace ash {
-namespace test {
 
 class TestShellContentState : public ShellContentState {
  public:
@@ -41,7 +40,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestShellContentState);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_CONTENT_TEST_SHELL_CONTENT_STATE_H_
diff --git a/ash/test/cursor_manager_test_api.cc b/ash/test/cursor_manager_test_api.cc
index 77ad774..ed972ab 100644
--- a/ash/test/cursor_manager_test_api.cc
+++ b/ash/test/cursor_manager_test_api.cc
@@ -12,7 +12,6 @@
 #include "ui/wm/core/cursor_manager.h"
 
 namespace ash {
-namespace test {
 
 CursorManagerTestApi::CursorManagerTestApi(::wm::CursorManager* cursor_manager)
     : cursor_manager_(cursor_manager) {}
@@ -37,5 +36,4 @@
   return ShellTestApi(Shell::Get()).native_cursor_manager_ash()->GetScale();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/cursor_manager_test_api.h b/ash/test/cursor_manager_test_api.h
index 47310b21..ec50117a 100644
--- a/ash/test/cursor_manager_test_api.h
+++ b/ash/test/cursor_manager_test_api.h
@@ -15,7 +15,6 @@
 }
 
 namespace ash {
-namespace test {
 
 // Use the api in this class to test CursorManager.
 class CursorManagerTestApi {
@@ -34,7 +33,6 @@
   DISALLOW_COPY_AND_ASSIGN(CursorManagerTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_CURSOR_MANAGER_TEST_API_H_
diff --git a/ash/test/display_configuration_controller_test_api.cc b/ash/test/display_configuration_controller_test_api.cc
index ad4a41c4..3035afe 100644
--- a/ash/test/display_configuration_controller_test_api.cc
+++ b/ash/test/display_configuration_controller_test_api.cc
@@ -7,7 +7,6 @@
 #include "ash/display/display_configuration_controller.h"
 
 namespace ash {
-namespace test {
 
 DisplayConfigurationControllerTestApi::DisplayConfigurationControllerTestApi(
     DisplayConfigurationController* controller)
@@ -23,5 +22,4 @@
   return controller_->GetScreenRotationAnimatorForDisplay(display_id);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/display_configuration_controller_test_api.h b/ash/test/display_configuration_controller_test_api.h
index 0ba2e1e..c0f5628 100644
--- a/ash/test/display_configuration_controller_test_api.h
+++ b/ash/test/display_configuration_controller_test_api.h
@@ -13,8 +13,6 @@
 class DisplayConfigurationController;
 class ScreenRotationAnimator;
 
-namespace test {
-
 // Accesses private data from a DisplayConfigurationController for testing.
 class DisplayConfigurationControllerTestApi {
  public:
@@ -32,7 +30,6 @@
   DISALLOW_COPY_AND_ASSIGN(DisplayConfigurationControllerTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_DISPLAY_CONFIGURATION_CONTROLLER_TEST_API_H_
diff --git a/ash/test/lock_state_controller_test_api.cc b/ash/test/lock_state_controller_test_api.cc
index bab5468d..8ef36d6 100644
--- a/ash/test/lock_state_controller_test_api.cc
+++ b/ash/test/lock_state_controller_test_api.cc
@@ -4,13 +4,7 @@
 
 #include "ash/test/lock_state_controller_test_api.h"
 
-#include <memory>
-#include <utility>
-
-#include "ash/public/interfaces/shutdown.mojom.h"
-
 namespace ash {
-namespace test {
 
 LockStateControllerTestApi::LockStateControllerTestApi(
     LockStateController* controller)
@@ -20,5 +14,4 @@
 
 LockStateControllerTestApi::~LockStateControllerTestApi() {}
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/lock_state_controller_test_api.h b/ash/test/lock_state_controller_test_api.h
index 3778184..d4e8c74 100644
--- a/ash/test/lock_state_controller_test_api.h
+++ b/ash/test/lock_state_controller_test_api.h
@@ -13,8 +13,6 @@
 
 namespace ash {
 
-namespace test {
-
 // Helper class used by tests to access internal state.
 class LockStateControllerTestApi {
  public:
@@ -65,7 +63,6 @@
   DISALLOW_COPY_AND_ASSIGN(LockStateControllerTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_LOCK_STATE_CONTROLLER_TEST_API_H_
diff --git a/ash/test/mirror_window_test_api.cc b/ash/test/mirror_window_test_api.cc
index 534eecf3..dbae7ef9 100644
--- a/ash/test/mirror_window_test_api.cc
+++ b/ash/test/mirror_window_test_api.cc
@@ -13,7 +13,6 @@
 #include "ui/gfx/geometry/point.h"
 
 namespace ash {
-namespace test {
 
 const aura::WindowTreeHost* MirrorWindowTestApi::GetHost() const {
   aura::Window* window = Shell::Get()
@@ -56,5 +55,4 @@
   return point;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/mirror_window_test_api.h b/ash/test/mirror_window_test_api.h
index 2812e4de..a9a0d23b 100644
--- a/ash/test/mirror_window_test_api.h
+++ b/ash/test/mirror_window_test_api.h
@@ -22,8 +22,6 @@
 
 namespace ash {
 
-namespace test {
-
 class MirrorWindowTestApi {
  public:
   MirrorWindowTestApi() {}
@@ -48,7 +46,6 @@
   DISALLOW_COPY_AND_ASSIGN(MirrorWindowTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_MIRROR_WINDOW_TEST_API_H_
diff --git a/ash/test/overflow_bubble_view_test_api.cc b/ash/test/overflow_bubble_view_test_api.cc
index 7063669..f18df467 100644
--- a/ash/test/overflow_bubble_view_test_api.cc
+++ b/ash/test/overflow_bubble_view_test_api.cc
@@ -7,7 +7,6 @@
 #include "ash/shelf/overflow_bubble_view.h"
 
 namespace ash {
-namespace test {
 
 OverflowBubbleViewTestAPI::OverflowBubbleViewTestAPI(
     OverflowBubbleView* bubble_view)
@@ -28,5 +27,4 @@
   return bubble_view_->GetBubbleFrameView();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/overflow_bubble_view_test_api.h b/ash/test/overflow_bubble_view_test_api.h
index a7869c0..5bfcf74 100644
--- a/ash/test/overflow_bubble_view_test_api.h
+++ b/ash/test/overflow_bubble_view_test_api.h
@@ -18,8 +18,6 @@
 namespace ash {
 class OverflowBubbleView;
 
-namespace test {
-
 class OverflowBubbleViewTestAPI {
  public:
   explicit OverflowBubbleViewTestAPI(OverflowBubbleView* bubble_view);
@@ -41,7 +39,6 @@
   DISALLOW_COPY_AND_ASSIGN(OverflowBubbleViewTestAPI);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_OVERFLOW_BUBBLE_VIEW_TEST_API_
diff --git a/ash/test/overflow_button_test_api.cc b/ash/test/overflow_button_test_api.cc
index 5823d6b..03443f7 100644
--- a/ash/test/overflow_button_test_api.cc
+++ b/ash/test/overflow_button_test_api.cc
@@ -5,7 +5,6 @@
 #include "ash/test/overflow_button_test_api.h"
 
 namespace ash {
-namespace test {
 namespace {
 
 std::string ToString(OverflowButtonTestApi::ChevronDirection direction) {
@@ -36,5 +35,4 @@
   return result;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/overflow_button_test_api.h b/ash/test/overflow_button_test_api.h
index 23af20a..5fd56eb 100644
--- a/ash/test/overflow_button_test_api.h
+++ b/ash/test/overflow_button_test_api.h
@@ -12,7 +12,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace ash {
-namespace test {
 
 // Use the api in this class to test OverflowButton.
 class OverflowButtonTestApi {
@@ -29,7 +28,6 @@
   DISALLOW_COPY_AND_ASSIGN(OverflowButtonTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_OVERFLOW_BUTTON_TEST_API_H_
diff --git a/ash/test/screen_orientation_controller_test_api.cc b/ash/test/screen_orientation_controller_test_api.cc
index 743d23b..a4a8ef1 100644
--- a/ash/test/screen_orientation_controller_test_api.cc
+++ b/ash/test/screen_orientation_controller_test_api.cc
@@ -7,7 +7,6 @@
 #include "ash/display/screen_orientation_controller_chromeos.h"
 
 namespace ash {
-namespace test {
 
 ScreenOrientationControllerTestApi::ScreenOrientationControllerTestApi(
     ScreenOrientationController* controller)
@@ -33,5 +32,4 @@
   return controller_->GetCurrentOrientationForTest();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/screen_orientation_controller_test_api.h b/ash/test/screen_orientation_controller_test_api.h
index 64a8453..d6bab86 100644
--- a/ash/test/screen_orientation_controller_test_api.h
+++ b/ash/test/screen_orientation_controller_test_api.h
@@ -12,8 +12,6 @@
 namespace ash {
 class ScreenOrientationController;
 
-namespace test {
-
 class ScreenOrientationControllerTestApi {
  public:
   explicit ScreenOrientationControllerTestApi(
@@ -34,7 +32,6 @@
   DISALLOW_COPY_AND_ASSIGN(ScreenOrientationControllerTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_SCREEN_ORIENTATION_CONTROLLER_TEST_API_H_
diff --git a/ash/test/shelf_button_pressed_metric_tracker_test_api.cc b/ash/test/shelf_button_pressed_metric_tracker_test_api.cc
index 6deddd65..72f6ad1d 100644
--- a/ash/test/shelf_button_pressed_metric_tracker_test_api.cc
+++ b/ash/test/shelf_button_pressed_metric_tracker_test_api.cc
@@ -7,7 +7,6 @@
 #include "base/time/tick_clock.h"
 
 namespace ash {
-namespace test {
 
 ShelfButtonPressedMetricTrackerTestAPI::ShelfButtonPressedMetricTrackerTestAPI(
     ShelfButtonPressedMetricTracker* shelf_button_pressed_metric_tracker)
@@ -22,5 +21,4 @@
   shelf_button_pressed_metric_tracker_->tick_clock_ = std::move(tick_clock);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/shelf_button_pressed_metric_tracker_test_api.h b/ash/test/shelf_button_pressed_metric_tracker_test_api.h
index 874365b..ad72040 100644
--- a/ash/test/shelf_button_pressed_metric_tracker_test_api.h
+++ b/ash/test/shelf_button_pressed_metric_tracker_test_api.h
@@ -17,7 +17,6 @@
 }  // namespace base
 
 namespace ash {
-namespace test {
 
 class ShelfButtonPressedMetricTrackerTestAPI {
  public:
@@ -34,7 +33,6 @@
   DISALLOW_COPY_AND_ASSIGN(ShelfButtonPressedMetricTrackerTestAPI);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_SHELF_BUTTON_PRESSED_METRIC_TRACKER_TEST_API _H_
diff --git a/ash/test/shelf_view_test_api.cc b/ash/test/shelf_view_test_api.cc
index 7601397b..7f1dd5c 100644
--- a/ash/test/shelf_view_test_api.cc
+++ b/ash/test/shelf_view_test_api.cc
@@ -36,7 +36,6 @@
 }  // namespace
 
 namespace ash {
-namespace test {
 
 ShelfViewTestAPI::ShelfViewTestAPI(ShelfView* shelf_view)
     : shelf_view_(shelf_view) {}
@@ -157,5 +156,4 @@
   return &(shelf_view_->shelf_button_pressed_metric_tracker_);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/shelf_view_test_api.h b/ash/test/shelf_view_test_api.h
index 5c882c3..d87d83d60 100644
--- a/ash/test/shelf_view_test_api.h
+++ b/ash/test/shelf_view_test_api.h
@@ -24,8 +24,6 @@
 class ShelfTooltipManager;
 class ShelfView;
 
-namespace test {
-
 // Use the api in this class to test ShelfView.
 class ShelfViewTestAPI {
  public:
@@ -110,7 +108,6 @@
   DISALLOW_COPY_AND_ASSIGN(ShelfViewTestAPI);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_SHELF_VIEW_TEST_API_H_
diff --git a/ash/test/shell_test_api.cc b/ash/test/shell_test_api.cc
index 2d1d5bd..9dd82d8 100644
--- a/ash/test/shell_test_api.cc
+++ b/ash/test/shell_test_api.cc
@@ -11,7 +11,6 @@
 #include "ash/shell.h"
 
 namespace ash {
-namespace test {
 
 ShellTestApi::ShellTestApi() : ShellTestApi(Shell::Get()) {}
 
@@ -42,5 +41,4 @@
   shell_->palette_delegate_ = std::move(palette_delegate);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/shell_test_api.h b/ash/test/shell_test_api.h
index 094e0df0..a85d51ee 100644
--- a/ash/test/shell_test_api.h
+++ b/ash/test/shell_test_api.h
@@ -19,8 +19,6 @@
 class SystemGestureEventFilter;
 class WorkspaceController;
 
-namespace test {
-
 // Accesses private data from a Shell for testing.
 class ShellTestApi {
  public:
@@ -42,7 +40,6 @@
   DISALLOW_COPY_AND_ASSIGN(ShellTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_SHELL_TEST_API_H_
diff --git a/ash/test/task_switch_time_tracker_test_api.cc b/ash/test/task_switch_time_tracker_test_api.cc
index 654d399..7ba1238 100644
--- a/ash/test/task_switch_time_tracker_test_api.cc
+++ b/ash/test/task_switch_time_tracker_test_api.cc
@@ -8,7 +8,6 @@
 #include "base/test/simple_test_tick_clock.h"
 
 namespace ash {
-namespace test {
 
 TaskSwitchTimeTrackerTestAPI::TaskSwitchTimeTrackerTestAPI(
     const std::string& histogram_name) {
@@ -29,5 +28,4 @@
   return time_tracker_->HasLastActionTime();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/task_switch_time_tracker_test_api.h b/ash/test/task_switch_time_tracker_test_api.h
index c9a617eea..62156fbc 100644
--- a/ash/test/task_switch_time_tracker_test_api.h
+++ b/ash/test/task_switch_time_tracker_test_api.h
@@ -19,8 +19,6 @@
 
 class TaskSwitchTimeTracker;
 
-namespace test {
-
 // Provides access TaskSwitchTimeTracker's internals.
 class TaskSwitchTimeTrackerTestAPI {
  public:
@@ -48,7 +46,6 @@
   DISALLOW_COPY_AND_ASSIGN(TaskSwitchTimeTrackerTestAPI);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TASK_SWITCH_TIME_TRACKER_TEST_API_H_
diff --git a/ash/test/test_accessibility_delegate.cc b/ash/test/test_accessibility_delegate.cc
index d5f3418..92ff689 100644
--- a/ash/test/test_accessibility_delegate.cc
+++ b/ash/test/test_accessibility_delegate.cc
@@ -5,7 +5,6 @@
 #include "ash/test/test_accessibility_delegate.h"
 
 namespace ash {
-namespace test {
 
 void TestAccessibilityDelegate::PlayEarcon(int sound_key) {
   sound_key_ = sound_key;
@@ -17,5 +16,4 @@
   return tmp;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_accessibility_delegate.h b/ash/test/test_accessibility_delegate.h
index ab117b8a..4615f57 100644
--- a/ash/test/test_accessibility_delegate.h
+++ b/ash/test/test_accessibility_delegate.h
@@ -10,7 +10,6 @@
 #include "ui/gfx/image/image_skia.h"
 
 namespace ash {
-namespace test {
 
 class TestAccessibilityDelegate : public DefaultAccessibilityDelegate {
  public:
@@ -28,7 +27,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestAccessibilityDelegate);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TEST_ACCESSIBILITY_DELEGATE_H_
diff --git a/ash/test/test_activation_delegate.cc b/ash/test/test_activation_delegate.cc
index daab400..b296dce 100644
--- a/ash/test/test_activation_delegate.cc
+++ b/ash/test/test_activation_delegate.cc
@@ -10,10 +10,6 @@
 #include "ui/events/event.h"
 
 namespace ash {
-namespace test {
-
-////////////////////////////////////////////////////////////////////////////////
-// TestActivationDelegate
 
 TestActivationDelegate::TestActivationDelegate()
     : window_(NULL),
@@ -55,5 +51,4 @@
   }
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_activation_delegate.h b/ash/test/test_activation_delegate.h
index 8a3d233..714e79c 100644
--- a/ash/test/test_activation_delegate.h
+++ b/ash/test/test_activation_delegate.h
@@ -17,7 +17,6 @@
 }
 
 namespace ash {
-namespace test {
 
 // A test ActivationDelegate that can be used to track activation changes for
 // an aura::Window.
@@ -60,7 +59,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestActivationDelegate);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TEST_ACTIVATION_DELEGATE_H_
diff --git a/ash/test/test_app_list_view_presenter_impl.cc b/ash/test/test_app_list_view_presenter_impl.cc
index 579babf..4692af7 100644
--- a/ash/test/test_app_list_view_presenter_impl.cc
+++ b/ash/test/test_app_list_view_presenter_impl.cc
@@ -9,7 +9,6 @@
 #include "ui/app_list/presenter/test/test_app_list_view_delegate_factory.h"
 
 namespace ash {
-namespace test {
 
 TestAppListViewPresenterImpl::TestAppListViewPresenterImpl()
     : app_list::AppListPresenterImpl(base::MakeUnique<
@@ -19,5 +18,4 @@
 
 TestAppListViewPresenterImpl::~TestAppListViewPresenterImpl() {}
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_app_list_view_presenter_impl.h b/ash/test/test_app_list_view_presenter_impl.h
index 6d414f9..b1b3a3c 100644
--- a/ash/test/test_app_list_view_presenter_impl.h
+++ b/ash/test/test_app_list_view_presenter_impl.h
@@ -10,7 +10,6 @@
 #include "ui/app_list/presenter/app_list_presenter_impl.h"
 
 namespace ash {
-namespace test {
 
 // An app list presenter impl subclass that presents a no-op test app list view.
 // Some tests rely on the presenter and delegate implementations' behavior.
@@ -23,7 +22,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestAppListViewPresenterImpl);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TEST_APP_LIST_VIEW_PRESENTER_IMPL_H_
diff --git a/ash/test/test_overlay_delegate.cc b/ash/test/test_overlay_delegate.cc
index e8ba639..8fa80953 100644
--- a/ash/test/test_overlay_delegate.cc
+++ b/ash/test/test_overlay_delegate.cc
@@ -5,9 +5,9 @@
 #include "ash/test/test_overlay_delegate.h"
 
 namespace ash {
-namespace test {
 
 TestOverlayDelegate::TestOverlayDelegate() : cancel_count_(0) {}
+
 TestOverlayDelegate::~TestOverlayDelegate() {}
 
 int TestOverlayDelegate::GetCancelCountAndReset() {
@@ -28,5 +28,4 @@
   return NULL;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_overlay_delegate.h b/ash/test/test_overlay_delegate.h
index 3211765..b7c74b4 100644
--- a/ash/test/test_overlay_delegate.h
+++ b/ash/test/test_overlay_delegate.h
@@ -9,7 +9,6 @@
 #include "base/macros.h"
 
 namespace ash {
-namespace test {
 
 class TestOverlayDelegate : public OverlayEventFilter::Delegate {
  public:
@@ -29,7 +28,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestOverlayDelegate);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TEST_OVERLAY_DELEGATE_H_
diff --git a/ash/test/test_screenshot_delegate.cc b/ash/test/test_screenshot_delegate.cc
index a817419..b0ba55c 100644
--- a/ash/test/test_screenshot_delegate.cc
+++ b/ash/test/test_screenshot_delegate.cc
@@ -5,7 +5,6 @@
 #include "ash/test/test_screenshot_delegate.h"
 
 namespace ash {
-namespace test {
 
 TestScreenshotDelegate::TestScreenshotDelegate()
     : handle_take_screenshot_count_(0),
@@ -40,5 +39,4 @@
   return result;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_screenshot_delegate.h b/ash/test/test_screenshot_delegate.h
index 1db8072..9ef8cd8 100644
--- a/ash/test/test_screenshot_delegate.h
+++ b/ash/test/test_screenshot_delegate.h
@@ -11,7 +11,6 @@
 #include "ui/gfx/geometry/rect.h"
 
 namespace ash {
-namespace test {
 
 class TestScreenshotDelegate : public ScreenshotDelegate {
  public:
@@ -51,7 +50,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestScreenshotDelegate);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TEST_SCREENSHOT_DELEGATE_H_
diff --git a/ash/test/test_session_controller_client.cc b/ash/test/test_session_controller_client.cc
index 8ccd13c..d5308d3 100644
--- a/ash/test/test_session_controller_client.cc
+++ b/ash/test/test_session_controller_client.cc
@@ -17,7 +17,6 @@
 #include "components/user_manager/user_type.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -181,5 +180,4 @@
 
 void TestSessionControllerClient::ShowMultiProfileLogin() {}
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_session_controller_client.h b/ash/test/test_session_controller_client.h
index 7acd5a1..b935294f 100644
--- a/ash/test/test_session_controller_client.h
+++ b/ash/test/test_session_controller_client.h
@@ -20,8 +20,6 @@
 
 class SessionController;
 
-namespace test {
-
 // Implement SessionControllerClient mojo interface to simulate chrome behavior
 // in tests. This breaks the ash/chrome dependency to allow testing ash code in
 // isolation. Note that tests that have an instance of SessionControllerClient
@@ -81,7 +79,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestSessionControllerClient);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TEST_SESSION_CONTROLLER_CLIENT_H_
diff --git a/ash/test/test_session_state_animator.cc b/ash/test/test_session_state_animator.cc
index 4aa3f31..86c4085 100644
--- a/ash/test/test_session_state_animator.cc
+++ b/ash/test/test_session_state_animator.cc
@@ -11,7 +11,6 @@
 #include "base/bind.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 // A no-op callback that can be used when managing an animation that didn't
@@ -302,5 +301,4 @@
   }
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_session_state_animator.h b/ash/test/test_session_state_animator.h
index 8854cc9e..ad9450e 100644
--- a/ash/test/test_session_state_animator.h
+++ b/ash/test/test_session_state_animator.h
@@ -16,7 +16,6 @@
 #include "base/time/time.h"
 
 namespace ash {
-namespace test {
 
 // A SessionStateAnimator that offers control over the lifetime of active
 // animations.
@@ -158,7 +157,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestSessionStateAnimator);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TEST_SESSION_STATE_ANIMATOR_H_
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc
index c9b1f10..4edb20f9 100644
--- a/ash/test/test_shell_delegate.cc
+++ b/ash/test/test_shell_delegate.cc
@@ -26,7 +26,6 @@
 #include "ui/gfx/image/image.h"
 
 namespace ash {
-namespace test {
 
 // A ShellObserver that sets the shelf alignment and auto hide behavior when the
 // shelf is created, to simulate ChromeLauncherController's behavior.
@@ -168,5 +167,4 @@
 }
 #endif
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h
index 679a609..f1cb2b9 100644
--- a/ash/test/test_shell_delegate.h
+++ b/ash/test/test_shell_delegate.h
@@ -18,7 +18,6 @@
 }
 
 namespace ash {
-namespace test {
 
 class ShelfInitializer;
 
@@ -89,7 +88,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestShellDelegate);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TEST_SHELL_DELEGATE_H_
diff --git a/ash/test/test_system_tray_item.cc b/ash/test/test_system_tray_item.cc
index 8be316c..53d8e5e 100644
--- a/ash/test/test_system_tray_item.cc
+++ b/ash/test/test_system_tray_item.cc
@@ -11,7 +11,6 @@
 #include "ui/views/view.h"
 
 namespace ash {
-namespace test {
 
 TestSystemTrayItem::TestSystemTrayItem() : TestSystemTrayItem(UMA_TEST) {}
 
@@ -76,5 +75,4 @@
 
 void TestSystemTrayItem::UpdateAfterLoginStatusChange(LoginStatus status) {}
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_system_tray_item.h b/ash/test/test_system_tray_item.h
index 4f95e043..450f430f 100644
--- a/ash/test/test_system_tray_item.h
+++ b/ash/test/test_system_tray_item.h
@@ -8,7 +8,6 @@
 #include "ash/system/tray/system_tray_item.h"
 
 namespace ash {
-namespace test {
 
 // Trivial item implementation that tracks its views for testing. By default
 // views are created and returned by the Create*View() methods and they are
@@ -46,7 +45,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestSystemTrayItem);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_COMMON_SYSTEM_TRAY_TEST_TEST_SYSTEM_TRAY_ITEM_H_
diff --git a/ash/test/test_wallpaper_delegate.cc b/ash/test/test_wallpaper_delegate.cc
index 3f7e430..03e4a1a 100644
--- a/ash/test/test_wallpaper_delegate.cc
+++ b/ash/test/test_wallpaper_delegate.cc
@@ -8,7 +8,6 @@
 #include "ash/wallpaper/wallpaper_controller.h"
 
 namespace ash {
-namespace test {
 
 TestWallpaperDelegate::TestWallpaperDelegate() : update_wallpaper_count_(0) {}
 
@@ -29,5 +28,4 @@
   return count;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_wallpaper_delegate.h b/ash/test/test_wallpaper_delegate.h
index a3d2c1eea..829119f1 100644
--- a/ash/test/test_wallpaper_delegate.h
+++ b/ash/test/test_wallpaper_delegate.h
@@ -6,12 +6,10 @@
 #define ASH_TEST_TEST_WALLPAPER_DELEGATE_H_
 
 #include "ash/default_wallpaper_delegate.h"
-
 #include "base/macros.h"
 #include "ui/gfx/image/image_skia.h"
 
 namespace ash {
-namespace test {
 
 class TestWallpaperDelegate : public DefaultWallpaperDelegate {
  public:
@@ -38,7 +36,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestWallpaperDelegate);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_TEST_WALLPAPER_DELEGATE_H_
diff --git a/ash/test/user_metrics_recorder_test_api.cc b/ash/test/user_metrics_recorder_test_api.cc
index 8622df1..2bdd6f2c 100644
--- a/ash/test/user_metrics_recorder_test_api.cc
+++ b/ash/test/user_metrics_recorder_test_api.cc
@@ -5,7 +5,6 @@
 #include "ash/test/user_metrics_recorder_test_api.h"
 
 namespace ash {
-namespace test {
 
 UserMetricsRecorderTestAPI::UserMetricsRecorderTestAPI()
     : user_metrics_recorder_(false) {}
@@ -20,5 +19,4 @@
   return user_metrics_recorder_.IsUserInActiveDesktopEnvironment();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/user_metrics_recorder_test_api.h b/ash/test/user_metrics_recorder_test_api.h
index 35b4bd7..acaa2ca7 100644
--- a/ash/test/user_metrics_recorder_test_api.h
+++ b/ash/test/user_metrics_recorder_test_api.h
@@ -9,7 +9,6 @@
 #include "base/macros.h"
 
 namespace ash {
-namespace test {
 
 // Test API to access internals of the UserMetricsRecorder class.
 class UserMetricsRecorderTestAPI {
@@ -30,7 +29,6 @@
   DISALLOW_COPY_AND_ASSIGN(UserMetricsRecorderTestAPI);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_USER_METRICS_RECORDER_TEST_API_H_
diff --git a/ash/test/wallpaper_controller_test_api.cc b/ash/test/wallpaper_controller_test_api.cc
index 5cdc88b1..6ef3a614 100644
--- a/ash/test/wallpaper_controller_test_api.cc
+++ b/ash/test/wallpaper_controller_test_api.cc
@@ -9,7 +9,6 @@
 #include "ui/gfx/image/image_skia.h"
 
 namespace ash {
-namespace test {
 
 WallpaperControllerTestApi::WallpaperControllerTestApi(
     WallpaperController* controller)
@@ -29,5 +28,4 @@
   return expected_color;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/wallpaper_controller_test_api.h b/ash/test/wallpaper_controller_test_api.h
index 4e0b4f6..719a445 100644
--- a/ash/test/wallpaper_controller_test_api.h
+++ b/ash/test/wallpaper_controller_test_api.h
@@ -10,8 +10,6 @@
 
 class WallpaperController;
 
-namespace test {
-
 class ASH_EXPORT WallpaperControllerTestApi {
  public:
   explicit WallpaperControllerTestApi(WallpaperController* controller);
@@ -31,5 +29,4 @@
   DISALLOW_COPY_AND_ASSIGN(WallpaperControllerTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/workspace_controller_test_api.cc b/ash/test/workspace_controller_test_api.cc
index ecc54aff..8e86431b 100644
--- a/ash/test/workspace_controller_test_api.cc
+++ b/ash/test/workspace_controller_test_api.cc
@@ -11,7 +11,6 @@
 #include "ui/aura/window.h"
 
 namespace ash {
-namespace test {
 
 WorkspaceControllerTestApi::WorkspaceControllerTestApi(
     WorkspaceController* controller)
@@ -32,5 +31,4 @@
   return controller_->layout_manager_->backdrop_controller_->backdrop_window_;
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/test/workspace_controller_test_api.h b/ash/test/workspace_controller_test_api.h
index c561886..813e2a7 100644
--- a/ash/test/workspace_controller_test_api.h
+++ b/ash/test/workspace_controller_test_api.h
@@ -13,8 +13,6 @@
 class MultiWindowResizeController;
 class WorkspaceEventHandler;
 
-namespace test {
-
 class ASH_EXPORT WorkspaceControllerTestApi {
  public:
   explicit WorkspaceControllerTestApi(WorkspaceController* controller);
@@ -30,7 +28,6 @@
   DISALLOW_COPY_AND_ASSIGN(WorkspaceControllerTestApi);
 };
 
-}  // namespace test
 }  // namespace ash
 
 #endif  // ASH_TEST_WORKSPACE_CONTROLLER_TEST_API_H_
diff --git a/ash/tooltips/tooltip_controller_unittest.cc b/ash/tooltips/tooltip_controller_unittest.cc
index f95d74c..a8e5b06 100644
--- a/ash/tooltips/tooltip_controller_unittest.cc
+++ b/ash/tooltips/tooltip_controller_unittest.cc
@@ -28,7 +28,6 @@
 // to be installed.
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -169,5 +168,4 @@
   EXPECT_TRUE(helper_->IsTooltipVisible());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/touch/touch_observer_hud_unittest.cc b/ash/touch/touch_observer_hud_unittest.cc
index 8b35578..1f9d702 100644
--- a/ash/touch/touch_observer_hud_unittest.cc
+++ b/ash/touch/touch_observer_hud_unittest.cc
@@ -21,16 +21,16 @@
 
 namespace ash {
 
-class TouchHudTestBase : public test::AshTestBase {
+class TouchHudTestBase : public AshTestBase {
  public:
   TouchHudTestBase() {}
   ~TouchHudTestBase() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
     // Initialize display infos. They should be initialized after Ash
-    // environment is set up, i.e., after test::AshTestBase::SetUp().
+    // environment is set up, i.e., after AshTestBase::SetUp().
     internal_display_id_ =
         display::test::DisplayManagerTestApi(Shell::Get()->display_manager())
             .SetFirstDisplayAsInternalDisplay();
diff --git a/ash/tray_action/tray_action_unittest.cc b/ash/tray_action/tray_action_unittest.cc
index 4be30466..10e63987 100644
--- a/ash/tray_action/tray_action_unittest.cc
+++ b/ash/tray_action/tray_action_unittest.cc
@@ -73,7 +73,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestTrayActionClient);
 };
 
-using TrayActionTest = test::AshTestBase;
+using TrayActionTest = AshTestBase;
 
 }  // namespace
 
diff --git a/ash/utility/screenshot_controller_unittest.cc b/ash/utility/screenshot_controller_unittest.cc
index bac14b8..e85077cd 100644
--- a/ash/utility/screenshot_controller_unittest.cc
+++ b/ash/utility/screenshot_controller_unittest.cc
@@ -21,7 +21,7 @@
 
 namespace ash {
 
-class ScreenshotControllerTest : public test::AshTestBase {
+class ScreenshotControllerTest : public AshTestBase {
  public:
   ScreenshotControllerTest() {}
   ~ScreenshotControllerTest() override {}
@@ -32,8 +32,8 @@
   }
 
   bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) {
-    return test::AshTestBase::TestIfMouseWarpsAt(GetEventGenerator(),
-                                                 point_in_screen);
+    return AshTestBase::TestIfMouseWarpsAt(GetEventGenerator(),
+                                           point_in_screen);
   }
 
   void StartPartialScreenshotSession() {
@@ -73,7 +73,7 @@
 
 TEST_F(PartialScreenshotControllerTest, BasicMouse) {
   StartPartialScreenshotSession();
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
 
   generator.MoveMouseTo(100, 100);
@@ -98,7 +98,7 @@
 // crbug.com/581432.
 TEST_F(PartialScreenshotControllerTest, StartSessionWhileMousePressed) {
   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
 
   generator.MoveMouseTo(100, 100);
   generator.PressLeftButton();
@@ -132,7 +132,7 @@
 
 TEST_F(PartialScreenshotControllerTest, JustClick) {
   StartPartialScreenshotSession();
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
 
   generator.MoveMouseTo(100, 100);
@@ -147,7 +147,7 @@
 
 TEST_F(PartialScreenshotControllerTest, BasicTouch) {
   StartPartialScreenshotSession();
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
 
   generator.set_current_location(gfx::Point(100, 100));
@@ -173,7 +173,7 @@
 TEST_F(PartialScreenshotControllerTest,
        PointerEventsWorkWhenPointerOnlyActive) {
   StartPartialScreenshotSession();
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
   screenshot_controller()->set_pen_events_only(true);
   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
 
@@ -202,7 +202,7 @@
        TouchMousePointerHoverIgnoredWithPointerEvents) {
   StartPartialScreenshotSession();
   screenshot_controller()->set_pen_events_only(true);
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
   generator.set_current_location(gfx::Point(100, 100));
 
@@ -234,7 +234,7 @@
 
 TEST_F(PartialScreenshotControllerTest, TwoFingerTouch) {
   StartPartialScreenshotSession();
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
 
   generator.set_current_location(gfx::Point(100, 100));
@@ -303,7 +303,7 @@
       ->SetCursorCompositingEnabled(true);
 
   // Large cursor is represented as cursor window.
-  test::MirrorWindowTestApi test_api;
+  MirrorWindowTestApi test_api;
   ASSERT_NE(nullptr, test_api.GetCursorWindow());
 
   ui::test::EventGenerator event_generator(Shell::GetPrimaryRootWindow());
@@ -333,7 +333,7 @@
 
 TEST_F(WindowScreenshotControllerTest, KeyboardOperation) {
   ui::test::EventGenerator& generator(GetEventGenerator());
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
 
   StartWindowScreenshotSession();
   generator.PressKey(ui::VKEY_ESCAPE, 0);
@@ -367,7 +367,7 @@
 
 TEST_F(WindowScreenshotControllerTest, MouseOperation) {
   ui::test::EventGenerator& generator(GetEventGenerator());
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
   StartWindowScreenshotSession();
   EXPECT_TRUE(IsActive());
   generator.ClickLeftButton();
@@ -418,7 +418,7 @@
   UpdateDisplay("400x400,500x500");
 
   ui::test::EventGenerator& generator(GetEventGenerator());
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
 
   std::unique_ptr<aura::Window> window1(
       CreateSelectableWindow(gfx::Rect(100, 100, 100, 100)));
diff --git a/ash/virtual_keyboard_controller.cc b/ash/virtual_keyboard_controller.cc
index f60412bf..69cd0300 100644
--- a/ash/virtual_keyboard_controller.cc
+++ b/ash/virtual_keyboard_controller.cc
@@ -26,8 +26,8 @@
 namespace ash {
 namespace {
 
-// Checks whether smart deployment is enabled.
-bool IsSmartVirtualKeyboardEnabled() {
+// Checks if virtual keyboard is force-enabled by enable-virtual-keyboard flag.
+bool IsVirtualKeyboardEnabled() {
   return !base::CommandLine::ForCurrentProcess()->HasSwitch(
       keyboard::switches::kEnableVirtualKeyboard);
 }
@@ -80,7 +80,7 @@
 }
 
 void VirtualKeyboardController::OnMaximizeModeStarted() {
-  if (!IsSmartVirtualKeyboardEnabled()) {
+  if (!IsVirtualKeyboardEnabled()) {
     SetKeyboardEnabled(true);
   } else {
     UpdateKeyboardEnabled();
@@ -88,7 +88,7 @@
 }
 
 void VirtualKeyboardController::OnMaximizeModeEnded() {
-  if (!IsSmartVirtualKeyboardEnabled()) {
+  if (!IsVirtualKeyboardEnabled()) {
     SetKeyboardEnabled(false);
   } else {
     UpdateKeyboardEnabled();
@@ -185,7 +185,7 @@
 }
 
 void VirtualKeyboardController::UpdateKeyboardEnabled() {
-  if (!IsSmartVirtualKeyboardEnabled()) {
+  if (!IsVirtualKeyboardEnabled()) {
     SetKeyboardEnabled(Shell::Get()
                            ->maximize_mode_controller()
                            ->IsMaximizeModeWindowManagerEnabled());
diff --git a/ash/virtual_keyboard_controller_unittest.cc b/ash/virtual_keyboard_controller_unittest.cc
index 3956022..4091de9 100644
--- a/ash/virtual_keyboard_controller_unittest.cc
+++ b/ash/virtual_keyboard_controller_unittest.cc
@@ -23,7 +23,6 @@
 #include "ui/keyboard/keyboard_util.h"
 
 namespace ash {
-namespace test {
 
 class VirtualKeyboardControllerTest : public AshTestBase {
  public:
@@ -313,5 +312,4 @@
   ASSERT_TRUE(keyboard::IsKeyboardEnabled());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index f8d1599..0d247bf 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -131,14 +131,14 @@
 
 }  // namespace
 
-class WallpaperControllerTest : public test::AshTestBase {
+class WallpaperControllerTest : public AshTestBase {
  public:
   WallpaperControllerTest()
       : controller_(nullptr), wallpaper_delegate_(nullptr) {}
   ~WallpaperControllerTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     // Ash shell initialization creates wallpaper. Reset it so we can manually
     // control wallpaper creation and animation in our tests.
     RootWindowController* root_window_controller =
@@ -146,8 +146,8 @@
     root_window_controller->SetWallpaperWidgetController(nullptr);
     root_window_controller->SetAnimatingWallpaperWidgetController(nullptr);
     controller_ = Shell::Get()->wallpaper_controller();
-    wallpaper_delegate_ = static_cast<test::TestWallpaperDelegate*>(
-        Shell::Get()->wallpaper_delegate());
+    wallpaper_delegate_ =
+        static_cast<TestWallpaperDelegate*>(Shell::Get()->wallpaper_delegate());
     controller_->set_wallpaper_reload_delay_for_test(0);
   }
 
@@ -242,7 +242,7 @@
 
   WallpaperController* controller_;  // Not owned.
 
-  test::TestWallpaperDelegate* wallpaper_delegate_;
+  TestWallpaperDelegate* wallpaper_delegate_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(WallpaperControllerTest);
diff --git a/ash/window_user_data_unittest.cc b/ash/window_user_data_unittest.cc
index d4d2de2..39a2def1 100644
--- a/ash/window_user_data_unittest.cc
+++ b/ash/window_user_data_unittest.cc
@@ -30,7 +30,7 @@
 
 }  // namespace
 
-using WindowUserDataTest = test::AshTestBase;
+using WindowUserDataTest = AshTestBase;
 
 // Verifies clear() deletes the data associated with a window.
 TEST_F(WindowUserDataTest, ClearDestroys) {
diff --git a/ash/wm/always_on_top_controller_unittest.cc b/ash/wm/always_on_top_controller_unittest.cc
index ee17b411..a6fcd7f 100644
--- a/ash/wm/always_on_top_controller_unittest.cc
+++ b/ash/wm/always_on_top_controller_unittest.cc
@@ -17,7 +17,6 @@
 #include "ui/keyboard/keyboard_ui.h"
 
 namespace ash {
-namespace test {
 
 class VirtualKeyboardAlwaysOnTopControllerTest : public AshTestBase {
  public:
@@ -27,7 +26,7 @@
   void SetUp() override {
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         keyboard::switches::kEnableVirtualKeyboard);
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
   }
 
  private:
@@ -84,10 +83,9 @@
       root_window->bounds(), kKeyboardHeight);
   contents_window->SetBounds(keyboard_bounds);
   contents_window->Show();
-  keyboard_controller->NotifyKeyboardBoundsChanging(keyboard_bounds);
+  keyboard_controller->NotifyContentsBoundsChanging(keyboard_bounds);
   // Verify that test manager was notified of bounds change.
   ASSERT_TRUE(manager->keyboard_bounds_changed());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/ash_focus_rules_unittest.cc b/ash/wm/ash_focus_rules_unittest.cc
index 37899d9..0c796474 100644
--- a/ash/wm/ash_focus_rules_unittest.cc
+++ b/ash/wm/ash_focus_rules_unittest.cc
@@ -20,7 +20,6 @@
 #include "ui/views/widget/widget.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -198,5 +197,4 @@
   EXPECT_TRUE(delegate.view()->HasFocus());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/container_finder_unittest.cc b/ash/wm/container_finder_unittest.cc
index 36c2f8e..d00db8a 100644
--- a/ash/wm/container_finder_unittest.cc
+++ b/ash/wm/container_finder_unittest.cc
@@ -14,7 +14,7 @@
 
 namespace ash {
 
-using ContainerFinderTest = test::AshTestBase;
+using ContainerFinderTest = AshTestBase;
 
 TEST_F(ContainerFinderTest, GetContainerForWindow) {
   // Create a normal widget in the default container.
diff --git a/ash/wm/drag_window_resizer_unittest.cc b/ash/wm/drag_window_resizer_unittest.cc
index 9a42060c..f0bd6a5 100644
--- a/ash/wm/drag_window_resizer_unittest.cc
+++ b/ash/wm/drag_window_resizer_unittest.cc
@@ -58,7 +58,7 @@
 
 }  // namespace
 
-class DragWindowResizerTest : public test::AshTestBase {
+class DragWindowResizerTest : public AshTestBase {
  public:
   DragWindowResizerTest() : transient_child_(nullptr) {}
   ~DragWindowResizerTest() override {}
@@ -145,8 +145,8 @@
   }
 
   bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) {
-    return test::AshTestBase::TestIfMouseWarpsAt(GetEventGenerator(),
-                                                 point_in_screen);
+    return AshTestBase::TestIfMouseWarpsAt(GetEventGenerator(),
+                                           point_in_screen);
   }
 
   aura::test::TestWindowDelegate delegate_;
@@ -589,7 +589,7 @@
   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
   ASSERT_EQ(2U, root_windows.size());
 
-  test::CursorManagerTestApi cursor_test_api(Shell::Get()->cursor_manager());
+  CursorManagerTestApi cursor_test_api(Shell::Get()->cursor_manager());
   // Move window from the root window with 1.0 device scale factor to the root
   // window with 2.0 device scale factor.
   {
diff --git a/ash/wm/gestures/overview_gesture_handler_unittest.cc b/ash/wm/gestures/overview_gesture_handler_unittest.cc
index 5b3a362..3bebbdc 100644
--- a/ash/wm/gestures/overview_gesture_handler_unittest.cc
+++ b/ash/wm/gestures/overview_gesture_handler_unittest.cc
@@ -18,7 +18,7 @@
 
 namespace ash {
 
-class OverviewGestureHandlerTest : public test::AshTestBase {
+class OverviewGestureHandlerTest : public AshTestBase {
  public:
   OverviewGestureHandlerTest() {}
   ~OverviewGestureHandlerTest() override {}
diff --git a/ash/wm/immersive_fullscreen_controller_unittest.cc b/ash/wm/immersive_fullscreen_controller_unittest.cc
index 8881b03..464f8f7 100644
--- a/ash/wm/immersive_fullscreen_controller_unittest.cc
+++ b/ash/wm/immersive_fullscreen_controller_unittest.cc
@@ -104,7 +104,7 @@
 
 /////////////////////////////////////////////////////////////////////////////
 
-class ImmersiveFullscreenControllerTest : public ash::test::AshTestBase {
+class ImmersiveFullscreenControllerTest : public AshTestBase {
  public:
   enum Modality {
     MODALITY_MOUSE,
@@ -138,9 +138,9 @@
     return controller_->mouse_x_when_hit_top_in_screen_;
   }
 
-  // ash::test::AshTestBase overrides:
+  // AshTestBase:
   void SetUp() override {
-    ash::test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
     widget_ = new views::Widget();
     views::Widget::InitParams params;
diff --git a/ash/wm/lock_action_handler_layout_manager_unittest.cc b/ash/wm/lock_action_handler_layout_manager_unittest.cc
index fc6bbb8..dacdbc1 100644
--- a/ash/wm/lock_action_handler_layout_manager_unittest.cc
+++ b/ash/wm/lock_action_handler_layout_manager_unittest.cc
@@ -85,7 +85,7 @@
 
 }  // namespace
 
-class LockActionHandlerLayoutManagerTest : public test::AshTestBase {
+class LockActionHandlerLayoutManagerTest : public AshTestBase {
  public:
   LockActionHandlerLayoutManagerTest() = default;
   ~LockActionHandlerLayoutManagerTest() override = default;
diff --git a/ash/wm/lock_layout_manager_unittest.cc b/ash/wm/lock_layout_manager_unittest.cc
index 4b62f6b96..2c15f3d 100644
--- a/ash/wm/lock_layout_manager_unittest.cc
+++ b/ash/wm/lock_layout_manager_unittest.cc
@@ -23,7 +23,6 @@
 #include "ui/views/widget/widget_delegate.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -292,5 +291,4 @@
   EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/lock_state_controller.h b/ash/wm/lock_state_controller.h
index fb23bc7..5921b7d 100644
--- a/ash/wm/lock_state_controller.h
+++ b/ash/wm/lock_state_controller.h
@@ -23,10 +23,6 @@
 class ShutdownController;
 enum class ShutdownReason;
 
-namespace test {
-class LockStateControllerTestApi;
-}
-
 // Displays onscreen animations and locks or suspends the system in response to
 // the power button being pressed or released.
 // Lock workflow:
@@ -118,7 +114,7 @@
   }
 
  private:
-  friend class test::LockStateControllerTestApi;
+  friend class LockStateControllerTestApi;
 
   struct UnlockedStateProperties {
     bool wallpaper_is_hidden;
diff --git a/ash/wm/lock_state_controller_unittest.cc b/ash/wm/lock_state_controller_unittest.cc
index 2a26022..e79b375 100644
--- a/ash/wm/lock_state_controller_unittest.cc
+++ b/ash/wm/lock_state_controller_unittest.cc
@@ -32,7 +32,6 @@
 #include "ui/gfx/geometry/size.h"
 
 namespace ash {
-namespace test {
 namespace {
 
 bool cursor_visible() {
@@ -1036,7 +1035,7 @@
   if (Shell::GetAshConfig() == Config::MASH)
     return;
 
-  test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
+  TestScreenshotDelegate* delegate = GetScreenshotDelegate();
   delegate->set_can_take_screenshot(true);
 
   EnableMaximizeMode(false);
@@ -1081,5 +1080,4 @@
   EXPECT_EQ(1, delegate->handle_take_screenshot_count());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.h b/ash/wm/maximize_mode/maximize_mode_controller.h
index 88f9da4c..cbcaaf34 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller.h
+++ b/ash/wm/maximize_mode/maximize_mode_controller.h
@@ -37,15 +37,8 @@
 
 namespace ash {
 
-class MaximizeModeControllerTest;
 class ScopedDisableInternalMouseAndKeyboard;
 class MaximizeModeWindowManager;
-class MaximizeModeWindowManagerTest;
-
-namespace test {
-class MultiUserWindowManagerChromeOSTest;
-class VirtualKeyboardControllerTest;
-}
 
 // MaximizeModeController listens to accelerometer events and automatically
 // enters and exits maximize mode when the lid is opened beyond the triggering
@@ -119,8 +112,8 @@
  private:
   friend class MaximizeModeControllerTest;
   friend class MaximizeModeWindowManagerTest;
-  friend class test::MultiUserWindowManagerChromeOSTest;
-  friend class test::VirtualKeyboardControllerTest;
+  friend class MultiUserWindowManagerChromeOSTest;
+  friend class VirtualKeyboardControllerTest;
 
   // Used for recording metrics for intervals of time spent in
   // and out of TouchView.
diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
index 4b813e4f..870cba83 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
@@ -70,7 +70,7 @@
 extern const float kAccelerometerVerticalHingeUnstableAnglesTestData[];
 extern const size_t kAccelerometerVerticalHingeUnstableAnglesTestDataLength;
 
-class MaximizeModeControllerTest : public test::AshTestBase {
+class MaximizeModeControllerTest : public AshTestBase {
  public:
   MaximizeModeControllerTest() {}
   ~MaximizeModeControllerTest() override {}
@@ -78,7 +78,7 @@
   void SetUp() override {
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kAshEnableTouchView);
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     chromeos::AccelerometerReader::GetInstance()->RemoveObserver(
         maximize_mode_controller());
 
@@ -91,7 +91,7 @@
   void TearDown() override {
     chromeos::AccelerometerReader::GetInstance()->AddObserver(
         maximize_mode_controller());
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
   MaximizeModeController* maximize_mode_controller() {
diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
index db2beab..e27be2c 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
@@ -39,7 +39,7 @@
 
 namespace ash {
 
-class MaximizeModeWindowManagerTest : public test::AshTestBase {
+class MaximizeModeWindowManagerTest : public AshTestBase {
  public:
   MaximizeModeWindowManagerTest() {}
   ~MaximizeModeWindowManagerTest() override {}
diff --git a/ash/wm/maximize_mode/touchpad_and_keyboard_disabler_unittest.cc b/ash/wm/maximize_mode/touchpad_and_keyboard_disabler_unittest.cc
index 4f59bc0..4ce4023 100644
--- a/ash/wm/maximize_mode/touchpad_and_keyboard_disabler_unittest.cc
+++ b/ash/wm/maximize_mode/touchpad_and_keyboard_disabler_unittest.cc
@@ -78,19 +78,19 @@
 
 }  // namespace
 
-class TouchpadAndKeyboardDisablerTest : public test::AshTestBase {
+class TouchpadAndKeyboardDisablerTest : public AshTestBase {
  public:
   TouchpadAndKeyboardDisablerTest() {}
 
   // AshTestBase:
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     disabler_ = CreateDisablerAndDelegate(&counts_, &test_delegate_);
   }
 
   void TearDown() override {
     EXPECT_TRUE(counts_.delegate_destroyed);
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
  protected:
@@ -207,10 +207,10 @@
 
 TEST_F(TouchpadAndKeyboardDisablerTest2,
        DisableCallbackSucceedsAfterShellDestroyed) {
-  std::unique_ptr<test::AshTestEnvironment> ash_test_environment =
-      test::AshTestEnvironment::Create();
-  std::unique_ptr<test::AshTestHelper> ash_test_helper =
-      base::MakeUnique<test::AshTestHelper>(ash_test_environment.get());
+  std::unique_ptr<AshTestEnvironment> ash_test_environment =
+      AshTestEnvironment::Create();
+  std::unique_ptr<AshTestHelper> ash_test_helper =
+      base::MakeUnique<AshTestHelper>(ash_test_environment.get());
   const bool start_session = true;
   ash_test_helper->SetUp(start_session);
 
diff --git a/ash/wm/mru_window_tracker_unittest.cc b/ash/wm/mru_window_tracker_unittest.cc
index b0e69da2..210df70 100644
--- a/ash/wm/mru_window_tracker_unittest.cc
+++ b/ash/wm/mru_window_tracker_unittest.cc
@@ -13,7 +13,7 @@
 
 namespace ash {
 
-class MruWindowTrackerTest : public test::AshTestBase {
+class MruWindowTrackerTest : public AshTestBase {
  public:
   MruWindowTrackerTest() {}
   ~MruWindowTrackerTest() override {}
diff --git a/ash/wm/native_cursor_manager_ash_classic.h b/ash/wm/native_cursor_manager_ash_classic.h
index 07065a6..e5c4405 100644
--- a/ash/wm/native_cursor_manager_ash_classic.h
+++ b/ash/wm/native_cursor_manager_ash_classic.h
@@ -13,10 +13,6 @@
 
 namespace ash {
 
-namespace test {
-class CursorManagerTestApi;
-}
-
 // This does the ash-specific setting of cursor details like cursor
 // visibility. It communicates back with the CursorManager through the
 // NativeCursorManagerDelegate interface, which receives messages about what
@@ -27,7 +23,7 @@
   ~NativeCursorManagerAshClassic() override;
 
  private:
-  friend class test::CursorManagerTestApi;
+  friend class CursorManagerTestApi;
 
   // Overridden from NativeCursorManagerAsh:
   void SetNativeCursorEnabled(bool enabled) override;
diff --git a/ash/wm/native_cursor_manager_ash_interactive_uitest.cc b/ash/wm/native_cursor_manager_ash_interactive_uitest.cc
index f23ce3e9..50f87bb 100644
--- a/ash/wm/native_cursor_manager_ash_interactive_uitest.cc
+++ b/ash/wm/native_cursor_manager_ash_interactive_uitest.cc
@@ -22,7 +22,7 @@
 
 namespace ash {
 
-using NativeCursorManagerAshTest = test::AshInteractiveUITestBase;
+using NativeCursorManagerAshTest = AshInteractiveUITestBase;
 
 namespace {
 
@@ -58,7 +58,7 @@
 
 TEST_F(NativeCursorManagerAshTest, MAYBE_CursorChangeOnEnterNotify) {
   ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
-  test::CursorManagerTestApi test_api(cursor_manager);
+  CursorManagerTestApi test_api(cursor_manager);
 
   display::ManagedDisplayInfo display_info1 =
       CreateDisplayInfo(10, gfx::Rect(0, 0, 500, 300), 1.0f);
diff --git a/ash/wm/native_cursor_manager_ash_unittest.cc b/ash/wm/native_cursor_manager_ash_unittest.cc
index efd768c..f742516 100644
--- a/ash/wm/native_cursor_manager_ash_unittest.cc
+++ b/ash/wm/native_cursor_manager_ash_unittest.cc
@@ -24,7 +24,6 @@
 #endif
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -53,7 +52,7 @@
 
 }  // namespace
 
-using NativeCursorManagerAshTest = test::AshTestBase;
+using NativeCursorManagerAshTest = AshTestBase;
 
 TEST_F(NativeCursorManagerAshTest, LockCursor) {
   ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
@@ -200,5 +199,4 @@
 }
 #endif
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/overlay_event_filter_unittest.cc b/ash/wm/overlay_event_filter_unittest.cc
index 37a2294..20cb1d74 100644
--- a/ash/wm/overlay_event_filter_unittest.cc
+++ b/ash/wm/overlay_event_filter_unittest.cc
@@ -9,9 +9,8 @@
 #include "ash/test/test_overlay_delegate.h"
 
 namespace ash {
-namespace test {
 
-typedef AshTestBase OverlayEventFilterTest;
+using OverlayEventFilterTest = AshTestBase;
 
 // Tests of the multiple overlay delegates attempt to activate, in that case
 // Cancel() of the existing delegate should be called.
@@ -33,5 +32,4 @@
   EXPECT_EQ(1, d2.GetCancelCountAndReset());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/overview/cleanup_animation_observer_unittest.cc b/ash/wm/overview/cleanup_animation_observer_unittest.cc
index b0542b5c..e74e1bba 100644
--- a/ash/wm/overview/cleanup_animation_observer_unittest.cc
+++ b/ash/wm/overview/cleanup_animation_observer_unittest.cc
@@ -63,7 +63,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestWindowSelectorDelegate);
 };
 
-class CleanupAnimationObserverTest : public test::AshTestBase,
+class CleanupAnimationObserverTest : public AshTestBase,
                                      public views::WidgetObserver {
  public:
   CleanupAnimationObserverTest() = default;
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc
index 0e62795..e40d566 100644
--- a/ash/wm/overview/window_selector_unittest.cc
+++ b/ash/wm/overview/window_selector_unittest.cc
@@ -87,16 +87,16 @@
 
 // TODO(bruthig): Move all non-simple method definitions out of class
 // declaration.
-class WindowSelectorTest : public test::AshTestBase {
+class WindowSelectorTest : public AshTestBase {
  public:
   WindowSelectorTest() {}
   ~WindowSelectorTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
-    shelf_view_test_.reset(new test::ShelfViewTestAPI(
-        GetPrimaryShelf()->GetShelfViewForTesting()));
+    shelf_view_test_.reset(
+        new ShelfViewTestAPI(GetPrimaryShelf()->GetShelfViewForTesting()));
     shelf_view_test_->SetAnimationDuration(1);
     ScopedTransformOverviewWindow::SetImmediateCloseForTests();
   }
@@ -319,7 +319,7 @@
     window_selector()->ContentsChanged(nullptr, base::UTF8ToUTF16(pattern));
   }
 
-  test::ShelfViewTestAPI* shelf_view_test() { return shelf_view_test_.get(); }
+  ShelfViewTestAPI* shelf_view_test() { return shelf_view_test_.get(); }
 
   views::Widget* text_filter_widget() {
     return window_selector()->text_filter_widget_.get();
@@ -328,7 +328,7 @@
  private:
   aura::test::TestWindowDelegate delegate_;
   NonActivatableActivationDelegate non_activatable_activation_delegate_;
-  std::unique_ptr<test::ShelfViewTestAPI> shelf_view_test_;
+  std::unique_ptr<ShelfViewTestAPI> shelf_view_test_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowSelectorTest);
 };
@@ -934,7 +934,7 @@
   std::unique_ptr<aura::Window> window2(CreateWindow(bounds));
 
   // The tested behavior relies on the app list presenter delegate.
-  test::TestAppListViewPresenterImpl app_list_presenter_impl;
+  TestAppListViewPresenterImpl app_list_presenter_impl;
 
   app_list_presenter_impl.Show(
       display::Screen::GetScreen()->GetPrimaryDisplay().id());
@@ -1293,7 +1293,7 @@
   bool drag_canceled_by_test = false;
   gfx::Rect bounds(0, 0, 400, 400);
   std::unique_ptr<aura::Window> window(CreateWindow(bounds));
-  test::ShellTestApi shell_test_api(Shell::Get());
+  ShellTestApi shell_test_api(Shell::Get());
   DragDropController* drag_drop_controller =
       shell_test_api.drag_drop_controller();
   ui::OSExchangeData data;
diff --git a/ash/wm/panels/panel_layout_manager_unittest.cc b/ash/wm/panels/panel_layout_manager_unittest.cc
index 5bb9bcb..7f088e4e 100644
--- a/ash/wm/panels/panel_layout_manager_unittest.cc
+++ b/ash/wm/panels/panel_layout_manager_unittest.cc
@@ -58,23 +58,23 @@
 
 using aura::test::WindowIsAbove;
 
-class PanelLayoutManagerTest : public test::AshTestBase {
+class PanelLayoutManagerTest : public AshTestBase {
  public:
   PanelLayoutManagerTest() {}
   ~PanelLayoutManagerTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
-    shelf_view_test_.reset(new test::ShelfViewTestAPI(
-        GetPrimaryShelf()->GetShelfViewForTesting()));
+    shelf_view_test_.reset(
+        new ShelfViewTestAPI(GetPrimaryShelf()->GetShelfViewForTesting()));
     shelf_view_test_->SetAnimationDuration(1);
 
     WebNotificationTray::DisableAnimationsForTest(true);
   }
 
   void TearDown() override {
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
 
     WebNotificationTray::DisableAnimationsForTest(false);  // Reenable animation
   }
@@ -208,11 +208,11 @@
     return widget->IsVisible();
   }
 
-  test::ShelfViewTestAPI* shelf_view_test() { return shelf_view_test_.get(); }
+  ShelfViewTestAPI* shelf_view_test() { return shelf_view_test_.get(); }
 
   // Clicks the shelf item on |shelf_view| associated with the given |window|.
   void ClickShelfItemForWindow(ShelfView* shelf_view, aura::Window* window) {
-    test::ShelfViewTestAPI test_api(shelf_view);
+    ShelfViewTestAPI test_api(shelf_view);
     test_api.SetAnimationDuration(1);
     test_api.RunMessageLoopUntilAnimationsDone();
     ShelfID shelf_id = ShelfID::Deserialize(window->GetProperty(kShelfIDKey));
@@ -240,7 +240,7 @@
                                 ShelfAutoHideBehavior behavior) {
     Shelf* shelf = GetShelfForWindow(window);
     shelf->SetAutoHideBehavior(behavior);
-    test::ShelfViewTestAPI test_api(shelf->GetShelfViewForTesting());
+    ShelfViewTestAPI test_api(shelf->GetShelfViewForTesting());
     test_api.RunMessageLoopUntilAnimationsDone();
   }
 
@@ -251,7 +251,7 @@
   }
 
  private:
-  std::unique_ptr<test::ShelfViewTestAPI> shelf_view_test_;
+  std::unique_ptr<ShelfViewTestAPI> shelf_view_test_;
 
   bool IsHorizontal(ShelfAlignment alignment) {
     return alignment == SHELF_ALIGNMENT_BOTTOM;
diff --git a/ash/wm/panels/panel_window_resizer_unittest.cc b/ash/wm/panels/panel_window_resizer_unittest.cc
index 98939530..ddd413d 100644
--- a/ash/wm/panels/panel_window_resizer_unittest.cc
+++ b/ash/wm/panels/panel_window_resizer_unittest.cc
@@ -31,7 +31,7 @@
 
 namespace ash {
 
-class PanelWindowResizerTest : public test::AshTestBase {
+class PanelWindowResizerTest : public AshTestBase {
  public:
   PanelWindowResizerTest() {}
   ~PanelWindowResizerTest() override {}
@@ -39,8 +39,8 @@
   void SetUp() override {
     AshTestBase::SetUp();
     UpdateDisplay("600x400");
-    shelf_view_test_.reset(new test::ShelfViewTestAPI(
-        GetPrimaryShelf()->GetShelfViewForTesting()));
+    shelf_view_test_.reset(
+        new ShelfViewTestAPI(GetPrimaryShelf()->GetShelfViewForTesting()));
     shelf_view_test_->SetAnimationDuration(1);
   }
 
@@ -170,7 +170,7 @@
 
  private:
   std::unique_ptr<WindowResizer> resizer_;
-  std::unique_ptr<test::ShelfViewTestAPI> shelf_view_test_;
+  std::unique_ptr<ShelfViewTestAPI> shelf_view_test_;
 
   DISALLOW_COPY_AND_ASSIGN(PanelWindowResizerTest);
 };
diff --git a/ash/wm/resize_shadow_and_cursor_unittest.cc b/ash/wm/resize_shadow_and_cursor_unittest.cc
index b4410e4..c829580 100644
--- a/ash/wm/resize_shadow_and_cursor_unittest.cc
+++ b/ash/wm/resize_shadow_and_cursor_unittest.cc
@@ -19,7 +19,6 @@
 #include "ui/views/widget/widget_delegate.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -99,7 +98,7 @@
 
   // Returns the current cursor type.
   ui::CursorType GetCurrentCursorType() const {
-    CursorManagerTestApi test_api(ash::Shell::Get()->cursor_manager());
+    CursorManagerTestApi test_api(Shell::Get()->cursor_manager());
     return test_api.GetCurrentCursor().native_type();
   }
 
@@ -243,5 +242,4 @@
   EXPECT_EQ(ui::CursorType::kEastResize, GetCurrentCursorType());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/root_window_layout_manager_unittest.cc b/ash/wm/root_window_layout_manager_unittest.cc
index 8bd7721..a8e7da74 100644
--- a/ash/wm/root_window_layout_manager_unittest.cc
+++ b/ash/wm/root_window_layout_manager_unittest.cc
@@ -30,7 +30,7 @@
 
 }  // namespace
 
-using RootWindowLayoutManagerTest = test::AshTestBase;
+using RootWindowLayoutManagerTest = AshTestBase;
 
 TEST_F(RootWindowLayoutManagerTest, DeleteChildDuringResize) {
   aura::Window* parent = Shell::GetPrimaryRootWindow()->GetChildById(
diff --git a/ash/wm/screen_dimmer.h b/ash/wm/screen_dimmer.h
index 70bbacc..1be2dd3 100644
--- a/ash/wm/screen_dimmer.h
+++ b/ash/wm/screen_dimmer.h
@@ -14,15 +14,12 @@
 
 namespace ash {
 
+class ScreenDimmerTest;
 class WindowDimmer;
 
 template <typename UserData>
 class WindowUserData;
 
-namespace test {
-class ScreenDimmerTest;
-}
-
 // ScreenDimmer displays a partially-opaque layer above everything
 // else in the given container window to darken the display.  It shouldn't be
 // used for long-term brightness adjustments due to performance
@@ -52,7 +49,7 @@
   static ScreenDimmer* FindForTest(int container_id);
 
  private:
-  friend class test::ScreenDimmerTest;
+  friend class ScreenDimmerTest;
 
   // Returns the aura::Windows (one per display) that correspond to
   // |container_|.
diff --git a/ash/wm/screen_dimmer_unittest.cc b/ash/wm/screen_dimmer_unittest.cc
index b0058cca..4b84a58 100644
--- a/ash/wm/screen_dimmer_unittest.cc
+++ b/ash/wm/screen_dimmer_unittest.cc
@@ -16,7 +16,6 @@
 #include "ui/compositor/layer.h"
 
 namespace ash {
-namespace test {
 
 class ScreenDimmerTest : public AshTestBase {
  public:
@@ -133,5 +132,4 @@
 TEST_F(ScreenDimmerShellDestructionTest, DontCrashIfScreenDimmerOutlivesShell) {
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/screen_pinning_controller_unittest.cc b/ash/wm/screen_pinning_controller_unittest.cc
index ccc12a3..e8ed686f 100644
--- a/ash/wm/screen_pinning_controller_unittest.cc
+++ b/ash/wm/screen_pinning_controller_unittest.cc
@@ -27,7 +27,7 @@
 
 }  // namespace
 
-using ScreenPinningControllerTest = test::AshTestBase;
+using ScreenPinningControllerTest = AshTestBase;
 
 TEST_F(ScreenPinningControllerTest, IsPinned) {
   aura::Window* w1 = CreateTestWindowInShellWithId(0);
diff --git a/ash/wm/session_state_animator_impl_unittest.cc b/ash/wm/session_state_animator_impl_unittest.cc
index abcbaa4..49c3535 100644
--- a/ash/wm/session_state_animator_impl_unittest.cc
+++ b/ash/wm/session_state_animator_impl_unittest.cc
@@ -12,8 +12,6 @@
 #include "base/run_loop.h"
 #include "ui/aura/client/aura_constants.h"
 
-typedef ash::test::AshTestBase SessionStateAnimatiorImplContainersTest;
-
 namespace ash {
 namespace {
 
@@ -31,6 +29,8 @@
 
 }  // namespace
 
+using SessionStateAnimatiorImplContainersTest = AshTestBase;
+
 TEST_F(SessionStateAnimatiorImplContainersTest, ContainersHaveIdTest) {
   aura::Window::Windows containers;
 
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc
index d8f2570..2f1a196e 100644
--- a/ash/wm/splitview/split_view_controller_unittest.cc
+++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -13,7 +13,7 @@
 
 namespace ash {
 
-class SplitViewControllerTest : public test::AshTestBase {
+class SplitViewControllerTest : public AshTestBase {
  public:
   SplitViewControllerTest() {}
   ~SplitViewControllerTest() override {}
diff --git a/ash/wm/stacking_controller_unittest.cc b/ash/wm/stacking_controller_unittest.cc
index 32c9d61..28717318 100644
--- a/ash/wm/stacking_controller_unittest.cc
+++ b/ash/wm/stacking_controller_unittest.cc
@@ -16,7 +16,7 @@
 
 namespace ash {
 
-class StackingControllerTest : public test::AshTestBase {
+class StackingControllerTest : public AshTestBase {
  public:
   StackingControllerTest() {}
   ~StackingControllerTest() override {}
diff --git a/ash/wm/system_gesture_event_filter.h b/ash/wm/system_gesture_event_filter.h
index d45c2a7..bf33c0ae 100644
--- a/ash/wm/system_gesture_event_filter.h
+++ b/ash/wm/system_gesture_event_filter.h
@@ -13,10 +13,6 @@
 namespace ash {
 class OverviewGestureHandler;
 
-namespace test {
-class SystemGestureEventFilterTest;
-}
-
 // An event filter which handles system level gesture events.
 class SystemGestureEventFilter : public ui::EventHandler {
  public:
@@ -30,7 +26,7 @@
   void OnGestureEvent(ui::GestureEvent* event) override;
 
  private:
-  friend class ash::test::SystemGestureEventFilterTest;
+  friend class SystemGestureEventFilterTest;
 
   std::unique_ptr<OverviewGestureHandler> overview_gesture_handler_;
 
diff --git a/ash/wm/system_gesture_event_filter_unittest.cc b/ash/wm/system_gesture_event_filter_unittest.cc
index a77ff4af..f56d4be 100644
--- a/ash/wm/system_gesture_event_filter_unittest.cc
+++ b/ash/wm/system_gesture_event_filter_unittest.cc
@@ -36,7 +36,6 @@
 #include "ui/views/window/window_button_order_provider.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -123,7 +122,7 @@
     views::WindowButtonOrderProvider::GetInstance()->SetWindowButtonOrder(
         leading, trailing);
 
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     // Enable brightness key.
     display::test::DisplayManagerTestApi(Shell::Get()->display_manager())
         .SetFirstDisplayAsInternalDisplay();
@@ -479,5 +478,4 @@
   aura::Env::GetInstance()->RemovePreTargetHandler(&event_handler);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/system_modal_container_layout_manager_unittest.cc b/ash/wm/system_modal_container_layout_manager_unittest.cc
index c8cc403..aad25254 100644
--- a/ash/wm/system_modal_container_layout_manager_unittest.cc
+++ b/ash/wm/system_modal_container_layout_manager_unittest.cc
@@ -37,7 +37,6 @@
 #include "ui/wm/core/window_util.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -838,7 +837,7 @@
   InputTestDelegate() {}
   ~InputTestDelegate() override {}
 
-  void RunTest(test::AshTestBase* test_base) {
+  void RunTest(AshTestBase* test_base) {
     std::unique_ptr<aura::Window> window(
         test_base->CreateTestWindowInShellWithDelegate(
             this, 0, gfx::Rect(0, 0, 100, 100)));
@@ -927,5 +926,4 @@
   delegate.RunTest(this);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc
index 2b7be1f..7dd57eb 100644
--- a/ash/wm/toplevel_window_event_handler_unittest.cc
+++ b/ash/wm/toplevel_window_event_handler_unittest.cc
@@ -34,7 +34,6 @@
 #include "ui/wm/public/window_move_client.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -997,5 +996,4 @@
 // Showing the resize shadows when the mouse is over the window edges is
 // tested in resize_shadow_and_cursor_test.cc
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/video_detector_unittest.cc b/ash/wm/video_detector_unittest.cc
index c9db96e1..825d46e 100644
--- a/ash/wm/video_detector_unittest.cc
+++ b/ash/wm/video_detector_unittest.cc
@@ -23,7 +23,6 @@
 #include "ui/gfx/geometry/rect.h"
 
 namespace ash {
-namespace test {
 
 // Implementation that just records video state changes.
 class TestObserver : public VideoDetector::Observer {
@@ -294,5 +293,4 @@
   EXPECT_TRUE(observer_->empty());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/ash/wm/window_animations_unittest.cc b/ash/wm/window_animations_unittest.cc
index dc58b0e..24d70e3 100644
--- a/ash/wm/window_animations_unittest.cc
+++ b/ash/wm/window_animations_unittest.cc
@@ -22,7 +22,8 @@
 using ui::Layer;
 
 namespace ash {
-class WindowAnimationsTest : public ash::test::AshTestBase {
+
+class WindowAnimationsTest : public AshTestBase {
  public:
   WindowAnimationsTest() {}
 
diff --git a/ash/wm/window_cycle_controller_unittest.cc b/ash/wm/window_cycle_controller_unittest.cc
index 5307841..136c4d2 100644
--- a/ash/wm/window_cycle_controller_unittest.cc
+++ b/ash/wm/window_cycle_controller_unittest.cc
@@ -80,18 +80,18 @@
 using aura::test::TestWindowDelegate;
 using aura::Window;
 
-class WindowCycleControllerTest : public test::AshTestBase {
+class WindowCycleControllerTest : public AshTestBase {
  public:
   WindowCycleControllerTest() {}
   ~WindowCycleControllerTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
 
     WindowCycleList::DisableInitialDelayForTesting();
 
-    shelf_view_test_.reset(new test::ShelfViewTestAPI(
-        GetPrimaryShelf()->GetShelfViewForTesting()));
+    shelf_view_test_.reset(
+        new ShelfViewTestAPI(GetPrimaryShelf()->GetShelfViewForTesting()));
     shelf_view_test_->SetAnimationDuration(1);
   }
 
@@ -115,7 +115,7 @@
   }
 
  private:
-  std::unique_ptr<test::ShelfViewTestAPI> shelf_view_test_;
+  std::unique_ptr<ShelfViewTestAPI> shelf_view_test_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowCycleControllerTest);
 };
@@ -481,7 +481,7 @@
     return;
 
   // The tested behavior relies on the app list presenter implementation.
-  test::TestAppListViewPresenterImpl app_list_presenter_impl;
+  TestAppListViewPresenterImpl app_list_presenter_impl;
 
   WindowCycleController* controller = Shell::Get()->window_cycle_controller();
 
diff --git a/ash/wm/window_manager_unittest.cc b/ash/wm/window_manager_unittest.cc
index 59ee4f5..4fc16af1e 100644
--- a/ash/wm/window_manager_unittest.cc
+++ b/ash/wm/window_manager_unittest.cc
@@ -79,7 +79,7 @@
 
 namespace ash {
 
-typedef test::AshTestBase WindowManagerTest;
+using WindowManagerTest = AshTestBase;
 
 class NonFocusableDelegate : public aura::test::TestWindowDelegate {
  public:
@@ -199,7 +199,7 @@
             aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
 
   // Set the focus to w123, but make the w1 not activatable.
-  test::TestActivationDelegate activation_delegate(false);
+  TestActivationDelegate activation_delegate(false);
   w123->Focus();
   EXPECT_EQ(w123.get(),
             aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
@@ -240,12 +240,12 @@
 TEST_F(WindowManagerTest, ActivateOnMouse) {
   aura::Window* root_window = Shell::GetPrimaryRootWindow();
 
-  test::TestActivationDelegate d1;
+  TestActivationDelegate d1;
   aura::test::TestWindowDelegate wd;
   std::unique_ptr<aura::Window> w1(
       CreateTestWindowInShellWithDelegate(&wd, -1, gfx::Rect(10, 10, 50, 50)));
   d1.SetWindow(w1.get());
-  test::TestActivationDelegate d2;
+  TestActivationDelegate d2;
   std::unique_ptr<aura::Window> w2(
       CreateTestWindowInShellWithDelegate(&wd, -2, gfx::Rect(70, 70, 50, 50)));
   d2.SetWindow(w2.get());
@@ -431,12 +431,12 @@
 TEST_F(WindowManagerTest, ActivateOnTouch) {
   aura::Window* root_window = Shell::GetPrimaryRootWindow();
 
-  test::TestActivationDelegate d1;
+  TestActivationDelegate d1;
   aura::test::TestWindowDelegate wd;
   std::unique_ptr<aura::Window> w1(
       CreateTestWindowInShellWithDelegate(&wd, -1, gfx::Rect(10, 10, 50, 50)));
   d1.SetWindow(w1.get());
-  test::TestActivationDelegate d2;
+  TestActivationDelegate d2;
   std::unique_ptr<aura::Window> w2(
       CreateTestWindowInShellWithDelegate(&wd, -2, gfx::Rect(70, 70, 50, 50)));
   d2.SetWindow(w2.get());
@@ -637,7 +637,7 @@
   transform.Rotate(90.0f);
   root_window->GetHost()->SetRootTransform(transform);
 
-  test::TestActivationDelegate d1;
+  TestActivationDelegate d1;
   aura::test::TestWindowDelegate wd;
   std::unique_ptr<aura::Window> w1(
       CreateTestWindowInShellWithDelegate(&wd, 1, gfx::Rect(0, 15, 50, 50)));
diff --git a/ash/wm/window_modality_controller_unittest.cc b/ash/wm/window_modality_controller_unittest.cc
index 0273a68..df73480 100644
--- a/ash/wm/window_modality_controller_unittest.cc
+++ b/ash/wm/window_modality_controller_unittest.cc
@@ -23,7 +23,7 @@
 
 namespace ash {
 
-typedef test::AshTestBase WindowModalityControllerTest;
+using WindowModalityControllerTest = AshTestBase;
 
 namespace {
 
diff --git a/ash/wm/window_positioner.h b/ash/wm/window_positioner.h
index d4957ecd..10006b3 100644
--- a/ash/wm/window_positioner.h
+++ b/ash/wm/window_positioner.h
@@ -23,10 +23,6 @@
 
 namespace ash {
 
-namespace test {
-class WindowPositionerTest;
-}
-
 // WindowPositioner is used by the browser to move new popups automatically to
 // a usable position on the closest work area (of the active window).
 class ASH_EXPORT WindowPositioner {
@@ -89,7 +85,7 @@
   static void SetMaximizeFirstWindow(bool maximize);
 
  protected:
-  friend class test::WindowPositionerTest;
+  friend class WindowPositionerTest;
 
   // Find a smart way to position the popup window. If there is no space this
   // function will return an empty rectangle.
diff --git a/ash/wm/window_positioner_unittest.cc b/ash/wm/window_positioner_unittest.cc
index fd951b9..c40b5ec 100644
--- a/ash/wm/window_positioner_unittest.cc
+++ b/ash/wm/window_positioner_unittest.cc
@@ -20,7 +20,14 @@
 
 namespace ash {
 
-using WindowPositionerTest = test::AshTestBase;
+class WindowPositionerTest : public AshTestBase {
+ public:
+  WindowPositionerTest() = default;
+  ~WindowPositionerTest() override = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WindowPositionerTest);
+};
 
 TEST_F(WindowPositionerTest, OpenMaximizedWindowOnSecondDisplay) {
   // Tests that for a screen that is narrower than kForceMaximizeWidthLimit
@@ -145,8 +152,8 @@
   gfx::Rect bounds_in_out(0, 0, 320, 240);  // Random bounds.
   ui::WindowShowState show_state_out = ui::SHOW_STATE_DEFAULT;
 
-  test::TestShellDelegate* const delegate =
-      static_cast<test::TestShellDelegate*>(Shell::Get()->shell_delegate());
+  TestShellDelegate* const delegate =
+      static_cast<TestShellDelegate*>(Shell::Get()->shell_delegate());
   delegate->SetForceMaximizeOnFirstRun(true);
 
   WindowPositioner::GetBoundsAndShowStateForNewWindow(
@@ -164,8 +171,8 @@
   gfx::Rect bounds_in_out(0, 0, 320, 240);  // Random bounds.
   ui::WindowShowState show_state_out = ui::SHOW_STATE_DEFAULT;
 
-  test::TestShellDelegate* const delegate =
-      static_cast<test::TestShellDelegate*>(Shell::Get()->shell_delegate());
+  TestShellDelegate* const delegate =
+      static_cast<TestShellDelegate*>(Shell::Get()->shell_delegate());
   delegate->SetForceMaximizeOnFirstRun(true);
 
   WindowPositioner::GetBoundsAndShowStateForNewWindow(
diff --git a/ash/wm/window_state_unittest.cc b/ash/wm/window_state_unittest.cc
index 9e5cb692..57e4928 100644
--- a/ash/wm/window_state_unittest.cc
+++ b/ash/wm/window_state_unittest.cc
@@ -50,7 +50,7 @@
 
 }  // namespace
 
-using WindowStateTest = test::AshTestBase;
+using WindowStateTest = AshTestBase;
 
 // Test that a window gets properly snapped to the display's edges in a
 // multi monitor environment.
diff --git a/ash/wm/window_util_unittest.cc b/ash/wm/window_util_unittest.cc
index d289412..7e4fe791 100644
--- a/ash/wm/window_util_unittest.cc
+++ b/ash/wm/window_util_unittest.cc
@@ -23,7 +23,7 @@
 
 }  // namespace
 
-typedef test::AshTestBase WindowUtilTest;
+using WindowUtilTest = AshTestBase;
 
 TEST_F(WindowUtilTest, CenterWindow) {
   UpdateDisplay("500x400, 600x400");
diff --git a/ash/wm/workspace/backdrop_controller.h b/ash/wm/workspace/backdrop_controller.h
index dc28f198..04313126 100644
--- a/ash/wm/workspace/backdrop_controller.h
+++ b/ash/wm/workspace/backdrop_controller.h
@@ -25,9 +25,6 @@
 }
 
 namespace ash {
-namespace test {
-class WorkspaceControllerTestApi;
-}
 
 namespace wm {
 class WindowState;
@@ -71,7 +68,7 @@
       AccessibilityNotificationVisibility notify) override;
 
  private:
-  friend class test::WorkspaceControllerTestApi;
+  friend class WorkspaceControllerTestApi;
 
   void EnsureBackdropWidget();
 
diff --git a/ash/wm/workspace/multi_window_resize_controller_unittest.cc b/ash/wm/workspace/multi_window_resize_controller_unittest.cc
index c79504c..716e20b 100644
--- a/ash/wm/workspace/multi_window_resize_controller_unittest.cc
+++ b/ash/wm/workspace/multi_window_resize_controller_unittest.cc
@@ -46,17 +46,16 @@
 
 }  // namespace
 
-class MultiWindowResizeControllerTest : public test::AshTestBase {
+class MultiWindowResizeControllerTest : public AshTestBase {
  public:
   MultiWindowResizeControllerTest() : resize_controller_(NULL) {}
   ~MultiWindowResizeControllerTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
-    WorkspaceController* wc =
-        test::ShellTestApi(Shell::Get()).workspace_controller();
+    AshTestBase::SetUp();
+    WorkspaceController* wc = ShellTestApi(Shell::Get()).workspace_controller();
     WorkspaceEventHandler* event_handler =
-        test::WorkspaceControllerTestApi(wc).GetEventHandler();
+        WorkspaceControllerTestApi(wc).GetEventHandler();
     resize_controller_ =
         WorkspaceEventHandlerTestHelper(event_handler).resize_controller();
   }
diff --git a/ash/wm/workspace/workspace_event_handler_unittest.cc b/ash/wm/workspace/workspace_event_handler_unittest.cc
index c9238312..779634d3 100644
--- a/ash/wm/workspace/workspace_event_handler_unittest.cc
+++ b/ash/wm/workspace/workspace_event_handler_unittest.cc
@@ -46,7 +46,7 @@
 
 }  // namespace
 
-class WorkspaceEventHandlerTest : public test::AshTestBase {
+class WorkspaceEventHandlerTest : public AshTestBase {
  public:
   WorkspaceEventHandlerTest() {}
   ~WorkspaceEventHandlerTest() override {}
diff --git a/ash/wm/workspace/workspace_layout_manager.h b/ash/wm/workspace/workspace_layout_manager.h
index 3941f95..cd9dc6c2 100644
--- a/ash/wm/workspace/workspace_layout_manager.h
+++ b/ash/wm/workspace/workspace_layout_manager.h
@@ -31,10 +31,6 @@
 class BackdropDelegate;
 class BackdropController;
 
-namespace test {
-class WorkspaceControllerTestApi;
-}
-
 namespace wm {
 class WMEvent;
 }
@@ -105,7 +101,7 @@
                                      aura::Window* root_window) override;
 
  private:
-  friend class test::WorkspaceControllerTestApi;
+  friend class WorkspaceControllerTestApi;
   typedef std::set<aura::Window*> WindowSet;
 
   // Adjusts the bounds of all managed windows when the display area changes.
diff --git a/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc b/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
index 2be47b5..d3ccdd7 100644
--- a/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
@@ -43,13 +43,13 @@
 
 }  // namespace
 
-class WorkspaceLayoutManagerKeyboardTest2 : public test::AshTestBase {
+class WorkspaceLayoutManagerKeyboardTest2 : public AshTestBase {
  public:
   WorkspaceLayoutManagerKeyboardTest2() : layout_manager_(nullptr) {}
   ~WorkspaceLayoutManagerKeyboardTest2() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     UpdateDisplay("800x600");
     aura::Window* default_container =
         Shell::GetPrimaryRootWindowController()->GetContainer(
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index 95274c3..be8d0c7 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -133,7 +133,7 @@
   DISALLOW_COPY_AND_ASSIGN(CustomFrameViewAshSizeLock);
 };
 
-using WorkspaceLayoutManagerTest = test::AshTestBase;
+using WorkspaceLayoutManagerTest = AshTestBase;
 
 // Verifies that a window containing a restore coordinate will be restored to
 // to the size prior to minimize, keeping the restore rectangle in tact (if
@@ -360,8 +360,7 @@
       aura::Window* w = window_;
       window_ = nullptr;
 
-      gfx::Rect shelf_bounds(
-          test::AshTestBase::GetPrimaryShelf()->GetIdealBounds());
+      gfx::Rect shelf_bounds(AshTestBase::GetPrimaryShelf()->GetIdealBounds());
       const gfx::Rect& window_bounds(w->bounds());
       w->SetBounds(gfx::Rect(window_bounds.x(), shelf_bounds.y() - 1,
                              window_bounds.width(), window_bounds.height()));
@@ -624,7 +623,7 @@
 }
 
 // Following "Solo" tests were originally written for BaseLayoutManager.
-using WorkspaceLayoutManagerSoloTest = test::AshTestBase;
+using WorkspaceLayoutManagerSoloTest = AshTestBase;
 
 // Tests normal->maximize->normal.
 TEST_F(WorkspaceLayoutManagerSoloTest, Maximize) {
@@ -963,7 +962,7 @@
   return static_cast<WorkspaceLayoutManager*>(container->layout_manager());
 }
 
-class WorkspaceLayoutManagerBackdropTest : public test::AshTestBase {
+class WorkspaceLayoutManagerBackdropTest : public AshTestBase {
  public:
   WorkspaceLayoutManagerBackdropTest() : default_container_(nullptr) {}
   ~WorkspaceLayoutManagerBackdropTest() override {}
@@ -1149,9 +1148,8 @@
 }
 
 TEST_F(WorkspaceLayoutManagerBackdropTest, BackdropTest) {
-  WorkspaceController* wc =
-      test::ShellTestApi(Shell::Get()).workspace_controller();
-  test::WorkspaceControllerTestApi test_helper(wc);
+  WorkspaceController* wc = ShellTestApi(Shell::Get()).workspace_controller();
+  WorkspaceControllerTestApi test_helper(wc);
 
   std::unique_ptr<aura::Window> window1(
       CreateTestWindow(gfx::Rect(0, 0, 100, 100)));
@@ -1274,11 +1272,10 @@
 }
 
 TEST_F(WorkspaceLayoutManagerBackdropTest, SpokenFeedbackFullscreenBackground) {
-  WorkspaceController* wc =
-      test::ShellTestApi(Shell::Get()).workspace_controller();
-  test::WorkspaceControllerTestApi test_helper(wc);
-  test::TestAccessibilityDelegate* accessibility_delegate =
-      static_cast<test::TestAccessibilityDelegate*>(
+  WorkspaceController* wc = ShellTestApi(Shell::Get()).workspace_controller();
+  WorkspaceControllerTestApi test_helper(wc);
+  TestAccessibilityDelegate* accessibility_delegate =
+      static_cast<TestAccessibilityDelegate*>(
           Shell::Get()->accessibility_delegate());
 
   aura::test::TestWindowDelegate delegate;
@@ -1334,11 +1331,10 @@
 }
 
 TEST_F(WorkspaceLayoutManagerBackdropTest, SpokenFeedbackForArc) {
-  WorkspaceController* wc =
-      test::ShellTestApi(Shell::Get()).workspace_controller();
-  test::WorkspaceControllerTestApi test_helper(wc);
-  test::TestAccessibilityDelegate* accessibility_delegate =
-      static_cast<test::TestAccessibilityDelegate*>(
+  WorkspaceController* wc = ShellTestApi(Shell::Get()).workspace_controller();
+  WorkspaceControllerTestApi test_helper(wc);
+  TestAccessibilityDelegate* accessibility_delegate =
+      static_cast<TestAccessibilityDelegate*>(
           Shell::Get()->accessibility_delegate());
 
   accessibility_delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
@@ -1381,7 +1377,7 @@
   EXPECT_EQ(kNoSoundKey, accessibility_delegate->GetPlayedEarconAndReset());
 }
 
-class WorkspaceLayoutManagerKeyboardTest : public test::AshTestBase {
+class WorkspaceLayoutManagerKeyboardTest : public AshTestBase {
  public:
   WorkspaceLayoutManagerKeyboardTest() : layout_manager_(nullptr) {}
   ~WorkspaceLayoutManagerKeyboardTest() override {}
diff --git a/ash/wm/workspace/workspace_window_resizer_unittest.cc b/ash/wm/workspace/workspace_window_resizer_unittest.cc
index 3b75840b..c3d44f1 100644
--- a/ash/wm/workspace/workspace_window_resizer_unittest.cc
+++ b/ash/wm/workspace/workspace_window_resizer_unittest.cc
@@ -63,7 +63,7 @@
 
 }  // namespace
 
-class WorkspaceWindowResizerTest : public test::AshTestBase {
+class WorkspaceWindowResizerTest : public AshTestBase {
  public:
   WorkspaceWindowResizerTest() : workspace_resizer_(nullptr) {}
   ~WorkspaceWindowResizerTest() override {}
diff --git a/ash/wm/workspace_controller.h b/ash/wm/workspace_controller.h
index d55c8b9..2acf99d3 100644
--- a/ash/wm/workspace_controller.h
+++ b/ash/wm/workspace_controller.h
@@ -13,13 +13,10 @@
 #include "ui/aura/window_observer.h"
 
 namespace ash {
+
+class BackdropDelegate;
 class WorkspaceEventHandler;
 class WorkspaceLayoutManager;
-class BackdropDelegate;
-
-namespace test {
-class WorkspaceControllerTestApi;
-}
 
 // WorkspaceController acts as a central place that ties together all the
 // various workspace pieces.
@@ -42,7 +39,7 @@
   WorkspaceLayoutManager* layout_manager() { return layout_manager_; }
 
  private:
-  friend class test::WorkspaceControllerTestApi;
+  friend class WorkspaceControllerTestApi;
 
   // aura::WindowObserver:
   void OnWindowDestroying(aura::Window* window) override;
diff --git a/ash/wm/workspace_controller_unittest.cc b/ash/wm/workspace_controller_unittest.cc
index 6a89c13c..28dae6d 100644
--- a/ash/wm/workspace_controller_unittest.cc
+++ b/ash/wm/workspace_controller_unittest.cc
@@ -75,7 +75,7 @@
   return result;
 }
 
-class WorkspaceControllerTest : public test::AshTestBase {
+class WorkspaceControllerTest : public AshTestBase {
  public:
   WorkspaceControllerTest() {}
   ~WorkspaceControllerTest() override {}
diff --git a/base/BUILD.gn b/base/BUILD.gn
index f2cfde31..b50a8c05 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -2088,6 +2088,7 @@
     "memory/shared_memory_win_unittest.cc",
     "memory/singleton_unittest.cc",
     "memory/weak_ptr_unittest.cc",
+    "message_loop/message_loop_io_posix_unittest.cc",
     "message_loop/message_loop_task_runner_unittest.cc",
     "message_loop/message_loop_unittest.cc",
     "message_loop/message_pump_glib_unittest.cc",
diff --git a/base/message_loop/message_loop_io_posix_unittest.cc b/base/message_loop/message_loop_io_posix_unittest.cc
new file mode 100644
index 0000000..78a09bc
--- /dev/null
+++ b/base/message_loop/message_loop_io_posix_unittest.cc
@@ -0,0 +1,174 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/compiler_specific.h"
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/run_loop.h"
+#include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+#if !defined(OS_NACL)
+
+namespace {
+
+class MessageLoopForIoPosixTest : public testing::Test {
+ public:
+  MessageLoopForIoPosixTest() {}
+
+  // testing::Test interface.
+  void SetUp() override {
+    // Create a file descriptor.  Doesn't need to be readable or writable,
+    // as we don't need to actually get any notifications.
+    // pipe() is just the easiest way to do it.
+    int pipefds[2];
+    int err = pipe(pipefds);
+    ASSERT_EQ(0, err);
+    read_fd_ = base::File(pipefds[0]);
+    write_fd_ = base::File(pipefds[1]);
+  }
+
+  base::File read_fd_;
+  base::File write_fd_;
+
+  DISALLOW_COPY_AND_ASSIGN(MessageLoopForIoPosixTest);
+};
+
+class TestHandler : public MessageLoopForIO::Watcher {
+ public:
+  void OnFileCanReadWithoutBlocking(int fd) override {
+    watcher_to_delete_ = nullptr;
+    is_readable_ = true;
+    MessageLoop::current()->QuitWhenIdle();
+  }
+  void OnFileCanWriteWithoutBlocking(int fd) override {
+    watcher_to_delete_ = nullptr;
+    is_writable_ = true;
+    MessageLoop::current()->QuitWhenIdle();
+  }
+
+  bool is_readable_ = false;
+  bool is_writable_ = false;
+
+  // If set then the contained watcher will be deleted on notification.
+  std::unique_ptr<MessageLoopForIO::FileDescriptorWatcher> watcher_to_delete_;
+};
+
+TEST_F(MessageLoopForIoPosixTest, FileDescriptorWatcherOutlivesMessageLoop) {
+  // Simulate a MessageLoop that dies before an FileDescriptorWatcher.
+  // This could happen when people use the Singleton pattern or atexit.
+
+  // Arrange for watcher to live longer than message loop.
+  MessageLoopForIO::FileDescriptorWatcher watcher(FROM_HERE);
+  TestHandler handler;
+  {
+    MessageLoopForIO message_loop;
+
+    message_loop.WatchFileDescriptor(write_fd_.GetPlatformFile(), true,
+                                     MessageLoopForIO::WATCH_WRITE, &watcher,
+                                     &handler);
+    // Don't run the message loop, just destroy it.
+  }
+
+  ASSERT_FALSE(handler.is_readable_);
+  ASSERT_FALSE(handler.is_writable_);
+}
+
+TEST_F(MessageLoopForIoPosixTest, FileDescriptorWatcherDoubleStop) {
+  // Verify that it's ok to call StopWatchingFileDescriptor().
+  // (Errors only showed up in valgrind.)
+
+  // Arrange for message loop to live longer than watcher.
+  MessageLoopForIO message_loop;
+  {
+    MessageLoopForIO::FileDescriptorWatcher watcher(FROM_HERE);
+
+    TestHandler handler;
+    message_loop.WatchFileDescriptor(write_fd_.GetPlatformFile(), true,
+                                     MessageLoopForIO::WATCH_WRITE, &watcher,
+                                     &handler);
+    ASSERT_TRUE(watcher.StopWatchingFileDescriptor());
+    ASSERT_TRUE(watcher.StopWatchingFileDescriptor());
+  }
+}
+
+TEST_F(MessageLoopForIoPosixTest, FileDescriptorWatcherDeleteInCallback) {
+  // Verify that it is OK to delete the FileDescriptorWatcher from within a
+  // callback.
+  MessageLoopForIO message_loop;
+
+  TestHandler handler;
+  handler.watcher_to_delete_ =
+      base::MakeUnique<MessageLoopForIO::FileDescriptorWatcher>(FROM_HERE);
+
+  message_loop.WatchFileDescriptor(write_fd_.GetPlatformFile(), true,
+                                   MessageLoopForIO::WATCH_WRITE,
+                                   handler.watcher_to_delete_.get(), &handler);
+  RunLoop().Run();
+}
+
+// Verify that basic readable notification works.
+TEST_F(MessageLoopForIoPosixTest, WatchReadable) {
+  MessageLoopForIO message_loop;
+  MessageLoopForIO::FileDescriptorWatcher watcher(FROM_HERE);
+  TestHandler handler;
+
+  // Watch the pipe for readability.
+  ASSERT_TRUE(MessageLoopForIO::current()->WatchFileDescriptor(
+      read_fd_.GetPlatformFile(), /* persistent= */ false,
+      MessageLoopForIO::WATCH_READ, &watcher, &handler));
+
+  // The pipe should not be readable when first created.
+  base::RunLoop().RunUntilIdle();
+  ASSERT_FALSE(handler.is_readable_);
+  ASSERT_FALSE(handler.is_writable_);
+
+  // Write a byte to the other end, making it readable.
+  const char buf = 0;
+  ASSERT_TRUE(
+      WriteFileDescriptor(write_fd_.GetPlatformFile(), &buf, sizeof(buf)));
+
+  // We don't want to assume that the read fd becomes readable the
+  // instant a bytes is written, so Run until quit by an event.
+  RunLoop().Run();
+
+  ASSERT_TRUE(handler.is_readable_);
+  ASSERT_FALSE(handler.is_writable_);
+}
+
+// Verify that watching a file descriptor for writability succeeds.
+TEST_F(MessageLoopForIoPosixTest, WatchWritable) {
+  MessageLoopForIO message_loop;
+  MessageLoopForIO::FileDescriptorWatcher watcher(FROM_HERE);
+  TestHandler handler;
+
+  // Watch the pipe for writability.
+  ASSERT_TRUE(MessageLoopForIO::current()->WatchFileDescriptor(
+      write_fd_.GetPlatformFile(), /* persistent= */ false,
+      MessageLoopForIO::WATCH_WRITE, &watcher, &handler));
+
+  // We should not receive a writable notification until we process events.
+  ASSERT_FALSE(handler.is_readable_);
+  ASSERT_FALSE(handler.is_writable_);
+
+  // The pipe should be writable immediately, but wait for the quit closure
+  // anyway, to be sure.
+  RunLoop().Run();
+
+  ASSERT_FALSE(handler.is_readable_);
+  ASSERT_TRUE(handler.is_writable_);
+}
+
+}  // namespace
+
+#endif  // !defined(OS_NACL)
+
+}  // namespace base
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc
index dc92f3c..b9fce13 100644
--- a/base/message_loop/message_loop_unittest.cc
+++ b/base/message_loop/message_loop_unittest.cc
@@ -729,78 +729,6 @@
 
 #endif  // defined(OS_WIN)
 
-#if defined(OS_POSIX) && !defined(OS_NACL)
-
-namespace {
-
-class QuitDelegate : public MessageLoopForIO::Watcher {
- public:
-  void OnFileCanWriteWithoutBlocking(int fd) override {
-    MessageLoop::current()->QuitWhenIdle();
-  }
-  void OnFileCanReadWithoutBlocking(int fd) override {
-    MessageLoop::current()->QuitWhenIdle();
-  }
-};
-
-TEST(MessageLoopTest, FileDescriptorWatcherOutlivesMessageLoop) {
-  // Simulate a MessageLoop that dies before an FileDescriptorWatcher.
-  // This could happen when people use the Singleton pattern or atexit.
-
-  // Create a file descriptor.  Doesn't need to be readable or writable,
-  // as we don't need to actually get any notifications.
-  // pipe() is just the easiest way to do it.
-  int pipefds[2];
-  int err = pipe(pipefds);
-  ASSERT_EQ(0, err);
-  int fd = pipefds[1];
-  {
-    // Arrange for controller to live longer than message loop.
-    MessageLoopForIO::FileDescriptorWatcher controller(FROM_HERE);
-    {
-      MessageLoopForIO message_loop;
-
-      QuitDelegate delegate;
-      message_loop.WatchFileDescriptor(fd,
-          true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate);
-      // and don't run the message loop, just destroy it.
-    }
-  }
-  if (IGNORE_EINTR(close(pipefds[0])) < 0)
-    PLOG(ERROR) << "close";
-  if (IGNORE_EINTR(close(pipefds[1])) < 0)
-    PLOG(ERROR) << "close";
-}
-
-TEST(MessageLoopTest, FileDescriptorWatcherDoubleStop) {
-  // Verify that it's ok to call StopWatchingFileDescriptor().
-  // (Errors only showed up in valgrind.)
-  int pipefds[2];
-  int err = pipe(pipefds);
-  ASSERT_EQ(0, err);
-  int fd = pipefds[1];
-  {
-    // Arrange for message loop to live longer than controller.
-    MessageLoopForIO message_loop;
-    {
-      MessageLoopForIO::FileDescriptorWatcher controller(FROM_HERE);
-
-      QuitDelegate delegate;
-      message_loop.WatchFileDescriptor(fd,
-          true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate);
-      controller.StopWatchingFileDescriptor();
-    }
-  }
-  if (IGNORE_EINTR(close(pipefds[0])) < 0)
-    PLOG(ERROR) << "close";
-  if (IGNORE_EINTR(close(pipefds[1])) < 0)
-    PLOG(ERROR) << "close";
-}
-
-}  // namespace
-
-#endif  // defined(OS_POSIX) && !defined(OS_NACL)
-
 namespace {
 // Inject a test point for recording the destructor calls for Closure objects
 // send to MessageLoop::PostTask(). It is awkward usage since we are trying to
diff --git a/base/message_loop/message_pump_fuchsia.cc b/base/message_loop/message_pump_fuchsia.cc
index 110268f..f3ff253 100644
--- a/base/message_loop/message_pump_fuchsia.cc
+++ b/base/message_loop/message_pump_fuchsia.cc
@@ -42,9 +42,7 @@
 
 MessagePumpFuchsia::MessagePumpFuchsia()
     : keep_running_(true), weak_factory_(this) {
-  // TODO(wez): Remove MX_PORT_OPT_V2 once the SDK is rolled, or migrate
-  // this implementation use ulib/port helpers.
-  CHECK_EQ(0, mx_port_create(MX_PORT_OPT_V2, &port_));
+  CHECK_EQ(0, mx_port_create(0, &port_));
 }
 
 MessagePumpFuchsia::~MessagePumpFuchsia() {
diff --git a/base/message_loop/message_pump_libevent_unittest.cc b/base/message_loop/message_pump_libevent_unittest.cc
index 75cdca04..4d51bbf9 100644
--- a/base/message_loop/message_pump_libevent_unittest.cc
+++ b/base/message_loop/message_pump_libevent_unittest.cc
@@ -277,87 +277,6 @@
       BindOnce(&WaitableEventWatcher::StopWatching, Owned(watcher.release())));
 }
 
-class CaptureAndQuitWatcher : public BaseWatcher {
- public:
-  CaptureAndQuitWatcher(MessagePumpLibevent::FileDescriptorWatcher* controller,
-                        base::Closure quit_closure)
-      : BaseWatcher(controller), quit_closure_(std::move(quit_closure)) {}
-
-  void OnFileCanReadWithoutBlocking(int /* fd */) override {
-    is_readable_ = true;
-    quit_closure_.Run();
-  }
-  void OnFileCanWriteWithoutBlocking(int /* fd */) override {
-    is_writable_ = true;
-    quit_closure_.Run();
-  }
-
-  bool is_readable_ = false;
-  bool is_writable_ = false;
-
- private:
-  base::Closure quit_closure_;
-};
-
-// Verify that basic readable notification works.
-TEST_F(MessagePumpLibeventTest, WatchReadable) {
-  // Tear-down the old MessageLoop before creating the replacement.
-  ui_loop_.reset();
-
-  ui_loop_ = base::MakeUnique<MessageLoopForIO>();
-  MessagePumpLibevent::FileDescriptorWatcher watcher(FROM_HERE);
-  RunLoop run_loop;
-  CaptureAndQuitWatcher delegate(&watcher, run_loop.QuitClosure());
-
-  // Watch the pipe for readability.
-  ASSERT_TRUE(MessageLoopForIO::current()->WatchFileDescriptor(
-      pipefds_[0], /* persistent= */ false, MessageLoopForIO::WATCH_READ,
-      &watcher, &delegate));
-
-  // The pipe should not be readable when first created.
-  base::RunLoop().RunUntilIdle();
-  ASSERT_FALSE(delegate.is_readable_);
-  ASSERT_FALSE(delegate.is_writable_);
-
-  // Write a byte to the other end, making it readable.
-  const char buf = 0;
-  ASSERT_TRUE(WriteFileDescriptor(pipefds_[1], &buf, sizeof(buf)));
-
-  // We don't want to assume that the read fd becomes readable the
-  // instant a bytes is written, so Run until quit by an event.
-  run_loop.Run();
-
-  ASSERT_TRUE(delegate.is_readable_);
-  ASSERT_FALSE(delegate.is_writable_);
-}
-
-// Verify that watching a file descriptor for writability succeeds.
-TEST_F(MessagePumpLibeventTest, WatchWritable) {
-  // Tear-down the old MessageLoop before creating the replacement.
-  ui_loop_.reset();
-
-  ui_loop_ = base::MakeUnique<MessageLoopForIO>();
-  MessagePumpLibevent::FileDescriptorWatcher watcher(FROM_HERE);
-  RunLoop run_loop;
-  CaptureAndQuitWatcher delegate(&watcher, run_loop.QuitClosure());
-
-  // Watch the pipe for writability.
-  ASSERT_TRUE(MessageLoopForIO::current()->WatchFileDescriptor(
-      pipefds_[1], /* persistent= */ false, MessageLoopForIO::WATCH_WRITE,
-      &watcher, &delegate));
-
-  // We should not receive a writable notification until we process events.
-  ASSERT_FALSE(delegate.is_readable_);
-  ASSERT_FALSE(delegate.is_writable_);
-
-  // The pipe should be writable immediately, so no need to wait for
-  // the quit closure.
-  run_loop.RunUntilIdle();
-
-  ASSERT_FALSE(delegate.is_readable_);
-  ASSERT_TRUE(delegate.is_writable_);
-}
-
 }  // namespace
 
 }  // namespace base
diff --git a/base/task_scheduler/scheduler_worker.cc b/base/task_scheduler/scheduler_worker.cc
index 26033d1b..07353443 100644
--- a/base/task_scheduler/scheduler_worker.cc
+++ b/base/task_scheduler/scheduler_worker.cc
@@ -15,7 +15,6 @@
 #if defined(OS_MACOSX)
 #include "base/mac/scoped_nsautorelease_pool.h"
 #elif defined(OS_WIN)
-#include "base/win/com_init_check_hook.h"
 #include "base/win/scoped_com_initializer.h"
 #endif
 
@@ -44,10 +43,7 @@
     // A SchedulerWorker starts out waiting for work.
     outer_->delegate_->WaitForWork(&wake_up_event_);
 
-    // When defined(COM_INIT_CHECK_HOOK_ENABLED), ignore
-    // SchedulerBackwardCompatibility::INIT_COM_STA to find incorrect uses of
-    // COM that should be running in a COM STA Task Runner.
-#if defined(OS_WIN) && !defined(COM_INIT_CHECK_HOOK_ENABLED)
+#if defined(OS_WIN)
     std::unique_ptr<win::ScopedCOMInitializer> com_initializer;
     if (outer_->backward_compatibility_ ==
         SchedulerBackwardCompatibility::INIT_COM_STA) {
diff --git a/base/task_scheduler/scheduler_worker_unittest.cc b/base/task_scheduler/scheduler_worker_unittest.cc
index 4d22f59..ab5982fb2 100644
--- a/base/task_scheduler/scheduler_worker_unittest.cc
+++ b/base/task_scheduler/scheduler_worker_unittest.cc
@@ -30,8 +30,6 @@
 
 #if defined(OS_WIN)
 #include <objbase.h>
-
-#include "base/win/com_init_check_hook.h"
 #endif
 
 using testing::_;
@@ -933,13 +931,7 @@
 
   // The call to CoInitializeEx() should have returned S_FALSE to indicate that
   // the COM library was already initialized on the thread.
-  // See SchedulerWorker::Thread::ThreadMain for why we expect two different
-  // results here.
-#if defined(COM_INIT_CHECK_HOOK_ENABLED)
-  EXPECT_EQ(S_OK, delegate_raw->coinitialize_hresult());
-#else
   EXPECT_EQ(S_FALSE, delegate_raw->coinitialize_hresult());
-#endif
 
   worker->JoinForTesting();
 }
diff --git a/build/fuchsia/test_runner.py b/build/fuchsia/test_runner.py
index 5392f22..87e52b3 100755
--- a/build/fuchsia/test_runner.py
+++ b/build/fuchsia/test_runner.py
@@ -9,6 +9,7 @@
 it. Does not yet implement running on real hardware."""
 
 import argparse
+import multiprocessing
 import os
 import re
 import subprocess
@@ -190,6 +191,22 @@
   return bootfs_name
 
 
+def SymbolizeEntry(entry):
+  addr2line_output = subprocess.check_output(
+      ['addr2line', '-Cipf', '--exe=' + entry[1], entry[2]])
+  prefix = '#%s: ' % entry[0]
+  # addr2line outputs a second line for inlining information, offset
+  # that to align it properly after the frame index.
+  addr2line_filtered = addr2line_output.strip().replace(
+      '(inlined', ' ' * len(prefix) + '(inlined')
+  return '#%s: %s' % (prefix, addr2line_filtered)
+
+
+def ParallelSymbolizeBacktrace(backtrace):
+  p = multiprocessing.Pool(multiprocessing.cpu_count())
+  return p.imap(SymbolizeEntry, backtrace)
+
+
 def main():
   parser = argparse.ArgumentParser()
   parser.add_argument('--dry-run', '-n', action='store_true', default=False,
@@ -297,7 +314,12 @@
     qemu_popen = subprocess.Popen(
         qemu_command, stdout=subprocess.PIPE, stdin=open(os.devnull))
 
-    processed_lines = []
+    # A buffer of backtrace entries awaiting symbolization, stored as tuples.
+    # Element #0: backtrace frame number (starting at 0).
+    # Element #1: path to executable code corresponding to the current frame.
+    # Element #2: memory offset within the executable.
+    bt_entries = []
+
     success = False
     while True:
       line = qemu_popen.stdout.readline()
@@ -307,23 +329,16 @@
       if 'SUCCESS: all tests passed.' in line:
         success = True
       if bt_end_re.match(line.strip()):
-        if processed_lines:
+        if bt_entries:
           print '----- start symbolized stack'
-          for processed in processed_lines:
+          for processed in ParallelSymbolizeBacktrace(bt_entries):
             print processed
           print '----- end symbolized stack'
-        processed_lines = []
+        bt_entries = []
       else:
         m = bt_with_offset_re.match(line.strip())
         if m:
-          addr2line_output = subprocess.check_output(
-              ['addr2line', '-Cipf', '--exe=' + args.test_name, m.group(4)])
-          prefix = '#%s: ' % m.group(1)
-          # addr2line outputs a second line for inlining information, offset
-          # that to align it properly after the frame index.
-          addr2line_filtered = addr2line_output.strip().replace(
-              '(inlined', ' ' * len(prefix) + '(inlined')
-          processed_lines.append('%s%s' % (prefix, addr2line_filtered))
+          bt_entries.append((m.group(1), args.test_name, m.group(4)))
     qemu_popen.wait()
 
     return 0 if success else 1
diff --git a/chrome/VERSION b/chrome/VERSION
index 3e6b650..fa40055 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=61
 MINOR=0
-BUILD=3160
+BUILD=3161
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
index 4356348..c1c3564 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -127,6 +127,9 @@
     private int mOverlayContentWidthMeasureSpec = ContentView.DEFAULT_MEASURE_SPEC;
     private int mOverlayContentHeightMeasureSpec = ContentView.DEFAULT_MEASURE_SPEC;
 
+    // List of callbacks to be called on nearest frame swap.
+    private List<Runnable> mNextFrameSwapCallbacks;
+
     /**
      * This view is created on demand to display debugging information.
      */
@@ -598,6 +601,24 @@
 
         if (!mSkipInvalidation || pendingFrameCount == 0) flushInvalidation();
         mSkipInvalidation = !mSkipInvalidation;
+
+        runNextFrameSwapCallbacks();
+    }
+
+    /**
+     * @param nextFrameSwapCallback Callback to run on a nearest compositor frame swap.
+     */
+    public void addNextFrameSwapCallback(Runnable nextFrameSwapCallback) {
+        if (mNextFrameSwapCallbacks == null) mNextFrameSwapCallbacks = new ArrayList<>();
+        mNextFrameSwapCallbacks.add(nextFrameSwapCallback);
+    }
+
+    private void runNextFrameSwapCallbacks() {
+        if (mNextFrameSwapCallbacks == null) return;
+        for (Runnable r : mNextFrameSwapCallbacks) {
+            post(r);
+        }
+        mNextFrameSwapCallbacks = null;
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
index 52b2337..6b23f15 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
@@ -75,46 +75,37 @@
                         mActivity, menu.findItem(R.id.direct_share_menu_id));
             }
 
-            MenuItem iconRow = menu.findItem(R.id.icon_row_menu_id);
-            MenuItem openInChromeItem = menu.findItem(R.id.open_in_browser_id);
-            MenuItem bookmarkItem = menu.findItem(R.id.bookmark_this_page_id);
-            MenuItem downloadItem = menu.findItem(R.id.offline_page_id);
-
+            boolean openInChromeItemVisible = true;
+            boolean bookmarkItemVisible = mShowStar;
+            boolean downloadItemVisible = mShowDownload;
             boolean addToHomeScreenVisible = true;
-            updateRequestDesktopSiteMenuItem(menu, currentTab);
+            boolean requestDesktopSiteVisible = true;
 
             if (mUiType == CUSTOM_TABS_UI_TYPE_MEDIA_VIEWER) {
                 // Most of the menu items don't make sense when viewing media.
-                iconRow.setVisible(false);
-                openInChromeItem.setVisible(false);
+                menu.findItem(R.id.icon_row_menu_id).setVisible(false);
                 menu.findItem(R.id.find_in_page_id).setVisible(false);
-                menu.findItem(R.id.request_desktop_site_row_menu_id).setVisible(false);
+                bookmarkItemVisible = false; // Set to skip initialization.
+                downloadItemVisible = false; // Set to skip initialization.
+                openInChromeItemVisible = false;
+                requestDesktopSiteVisible = false;
                 addToHomeScreenVisible = false;
             } else if (mUiType == CUSTOM_TABS_UI_TYPE_PAYMENT_REQUEST) {
                 // Only the icon row and 'find in page' are shown for openning payment request UI
                 // from Chrome.
-                openInChromeItem.setVisible(false);
-                menu.findItem(R.id.request_desktop_site_id).setVisible(false);
+                openInChromeItemVisible = false;
+                requestDesktopSiteVisible = false;
                 addToHomeScreenVisible = false;
-                downloadItem.setVisible(false);
-                bookmarkItem.setVisible(false);
-            } else {
-                openInChromeItem.setTitle(
-                        DefaultBrowserInfo.getTitleOpenInDefaultBrowser(mIsOpenedByChrome));
-                updateBookmarkMenuItem(bookmarkItem, currentTab);
-            }
-            if (!mShowStar) {
-                bookmarkItem.setVisible(false);
-            }
-            downloadItem.setVisible(mShowDownload);
-            if (!FirstRunStatus.getFirstRunFlowComplete()) {
-                openInChromeItem.setVisible(false);
-                bookmarkItem.setVisible(false);
-                downloadItem.setVisible(false);
-                addToHomeScreenVisible = false;
+                downloadItemVisible = false;
+                bookmarkItemVisible = false;
             }
 
-            downloadItem.setEnabled(DownloadUtils.isAllowedToDownloadPage(currentTab));
+            if (!FirstRunStatus.getFirstRunFlowComplete()) {
+                openInChromeItemVisible = false;
+                bookmarkItemVisible = false;
+                downloadItemVisible = false;
+                addToHomeScreenVisible = false;
+            }
 
             String url = currentTab.getUrl();
             boolean isChromeScheme = url.startsWith(UrlConstants.CHROME_URL_PREFIX)
@@ -123,6 +114,34 @@
                 addToHomeScreenVisible = false;
             }
 
+            MenuItem downloadItem = menu.findItem(R.id.offline_page_id);
+            if (downloadItemVisible) {
+                downloadItem.setEnabled(DownloadUtils.isAllowedToDownloadPage(currentTab));
+            } else {
+                downloadItem.setVisible(false);
+            }
+
+            MenuItem bookmarkItem = menu.findItem(R.id.bookmark_this_page_id);
+            if (bookmarkItemVisible) {
+                updateBookmarkMenuItem(bookmarkItem, currentTab);
+            } else {
+                bookmarkItem.setVisible(false);
+            }
+
+            MenuItem openInChromeItem = menu.findItem(R.id.open_in_browser_id);
+            if (openInChromeItemVisible) {
+                openInChromeItem.setTitle(
+                        DefaultBrowserInfo.getTitleOpenInDefaultBrowser(mIsOpenedByChrome));
+            } else {
+                openInChromeItem.setVisible(false);
+            }
+
+            if (requestDesktopSiteVisible) {
+                updateRequestDesktopSiteMenuItem(menu, currentTab);
+            } else {
+                menu.findItem(R.id.request_desktop_site_row_menu_id).setVisible(false);
+            }
+
             // Add custom menu items. Make sure they are only added once.
             if (!mIsCustomEntryAdded) {
                 mIsCustomEntryAdded = true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
index 576fb43e..66834f2f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -480,7 +480,7 @@
         int surfaceHeight = (int) Math.ceil(height * dpr);
 
         Point size = new Point(surfaceWidth, surfaceHeight);
-        mContentVirtualDisplay.update(size, dpr, null, null, null);
+        mContentVirtualDisplay.update(size, dpr, null, null, null, null, null);
         if (mTab != null && mTab.getContentViewCore() != null) {
             mTab.getContentViewCore().onSizeChanged(surfaceWidth, surfaceHeight, 0, 0);
             nativeOnPhysicalBackingSizeChanged(mNativeVrShell,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
index 9d77a15..cfc6022d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -179,7 +179,7 @@
                 controlContainer);
 
         if (getFullscreenManager() != null) getFullscreenManager().setTab(getActivityTab());
-        mSplashController.onFinishedNativeInit(getActivityTab());
+        mSplashController.onFinishedNativeInit(getActivityTab(), getCompositorViewHolder());
         super.finishNativeInitialization();
         mIsInitialized = true;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java
index 3ba88d1..727358b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java
@@ -17,6 +17,7 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.compositor.CompositorViewHolder;
 import org.chromium.chrome.browser.metrics.WebappUma;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
@@ -24,6 +25,9 @@
 
 /** Shows and hides splash screen. */
 class WebappSplashScreenController extends EmptyTabObserver {
+    /** Used to schedule splash screen hiding. */
+    private CompositorViewHolder mCompositorViewHolder;
+
     /** View to which the splash screen is added. */
     private ViewGroup mParentView;
 
@@ -76,8 +80,9 @@
     }
 
     /** Should be called once native has loaded. */
-    public void onFinishedNativeInit(Tab tab) {
+    public void onFinishedNativeInit(Tab tab, CompositorViewHolder compositorViewHolder) {
         mNativeLoaded = true;
+        mCompositorViewHolder = compositorViewHolder;
         tab.addObserver(this);
         if (mInitializedLayout) {
             mWebappUma.commitMetrics();
@@ -92,27 +97,27 @@
     @Override
     public void didFirstVisuallyNonEmptyPaint(Tab tab) {
         if (canHideSplashScreen()) {
-            hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_PAINT);
+            hideSplashScreenOnNextFrameSwap(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_PAINT);
         }
     }
 
     @Override
     public void onPageLoadFinished(Tab tab) {
         if (canHideSplashScreen()) {
-            hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FINISHED);
+            hideSplashScreenOnNextFrameSwap(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FINISHED);
         }
     }
 
     @Override
     public void onPageLoadFailed(Tab tab, int errorCode) {
         if (canHideSplashScreen()) {
-            hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FAILED);
+            hideSplashScreenOnNextFrameSwap(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FAILED);
         }
     }
 
     @Override
     public void onCrash(Tab tab, boolean sadTabShown) {
-        hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_CRASH);
+        hideSplashScreenOnNextFrameSwap(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_CRASH);
     }
 
     protected boolean canHideSplashScreen() {
@@ -181,8 +186,25 @@
         }
     }
 
-    /** Hides the splash screen. */
-    private void hideSplashScreen(final Tab tab, final int reason) {
+    /**
+     * Schedules the splash screen hiding animation once the compositor frame has been swapped.
+     *
+     * Without this callback we were seeing a short flash of white between the splash screen and
+     * the web content (crbug.com/734500).
+     * */
+    private void hideSplashScreenOnNextFrameSwap(final Tab tab, final int reason) {
+        if (mSplashScreen == null || mCompositorViewHolder == null) return;
+
+        mCompositorViewHolder.addNextFrameSwapCallback(new Runnable() {
+            @Override
+            public void run() {
+                animateHidingSplashScreen(tab, reason);
+            }
+        });
+    }
+
+    /** Performs the splash screen hiding animation. */
+    private void animateHidingSplashScreen(final Tab tab, final int reason) {
         if (mSplashScreen == null) return;
 
         mSplashScreen.animate().alpha(0f).withEndAction(new Runnable() {
@@ -192,6 +214,7 @@
                 mParentView.removeView(mSplashScreen);
                 tab.removeObserver(WebappSplashScreenController.this);
                 mSplashScreen = null;
+                mCompositorViewHolder = null;
                 mWebappUma.splashscreenHidden(reason);
             }
         });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java
index 4acf84d..e7fefad 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java
@@ -187,7 +187,7 @@
         Assert.assertFalse(menu.findItem(R.id.open_in_browser_id).isVisible());
         Assert.assertFalse(menu.findItem(R.id.bookmark_this_page_id).isVisible());
         Assert.assertFalse(menu.findItem(R.id.offline_page_id).isVisible());
-        Assert.assertFalse(menu.findItem(R.id.request_desktop_site_id).isVisible());
+        Assert.assertFalse(menu.findItem(R.id.request_desktop_site_row_menu_id).isVisible());
         Assert.assertFalse(menu.findItem(R.id.add_to_homescreen_id).isVisible());
         Assert.assertFalse(menu.findItem(R.id.open_webapk_id).isVisible());
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNativeUiTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNativeUiTest.java
index 835fc0f..8e11b7f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNativeUiTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNativeUiTest.java
@@ -8,7 +8,6 @@
 import static org.chromium.chrome.browser.UrlConstants.BOOKMARKS_UNCATEGORIZED_URL;
 import static org.chromium.chrome.browser.UrlConstants.BOOKMARKS_URL;
 import static org.chromium.chrome.browser.UrlConstants.DOWNLOADS_URL;
-import static org.chromium.chrome.browser.UrlConstants.INTERESTS_URL;
 import static org.chromium.chrome.browser.UrlConstants.NATIVE_HISTORY_URL;
 import static org.chromium.chrome.browser.UrlConstants.NTP_URL;
 import static org.chromium.chrome.browser.UrlConstants.RECENT_TABS_URL;
@@ -45,6 +44,9 @@
     @Rule
     public VrTestRule mVrTestRule = new VrTestRule();
 
+    private static final String TEST_PAGE_2D_URL =
+            VrTestRule.getHtmlTestFile("test_navigation_2d_page");
+
     @Before
     public void setUp() throws Exception {
         VrTransitionUtils.forceEnterVr();
@@ -52,28 +54,43 @@
     }
 
     /**
-     * Tests that URLs are shown for native UI.
-     * TODO(tiborg): Update this. crbug.com/738583
+     * Tests that URLs are not shown for native UI.
      */
     @Test
     @MediumTest
-    public void testURLOnNativeUi()
+    public void testUrlOnNativeUi()
             throws IllegalArgumentException, InterruptedException, TimeoutException {
         mVrTestRule.loadUrl(BOOKMARKS_URL, PAGE_LOAD_TIMEOUT_S);
-        Assert.assertTrue("Should be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
+        Assert.assertFalse(
+                "Should not be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
         mVrTestRule.loadUrl(BOOKMARKS_FOLDER_URL, PAGE_LOAD_TIMEOUT_S);
-        Assert.assertTrue("Should be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
+        Assert.assertFalse(
+                "Should not be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
         mVrTestRule.loadUrl(BOOKMARKS_UNCATEGORIZED_URL, PAGE_LOAD_TIMEOUT_S);
-        Assert.assertTrue("Should be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
+        Assert.assertFalse(
+                "Should not be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
         mVrTestRule.loadUrl(DOWNLOADS_URL, PAGE_LOAD_TIMEOUT_S);
-        Assert.assertTrue("Should be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
-        mVrTestRule.loadUrl(INTERESTS_URL, PAGE_LOAD_TIMEOUT_S);
-        Assert.assertTrue("Should be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
+        Assert.assertFalse(
+                "Should not be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
         mVrTestRule.loadUrl(NTP_URL, PAGE_LOAD_TIMEOUT_S);
-        Assert.assertTrue("Should be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
+        Assert.assertFalse(
+                "Should not be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
         mVrTestRule.loadUrl(NATIVE_HISTORY_URL, PAGE_LOAD_TIMEOUT_S);
-        Assert.assertTrue("Should be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
+        Assert.assertFalse(
+                "Should not be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
         mVrTestRule.loadUrl(RECENT_TABS_URL, PAGE_LOAD_TIMEOUT_S);
+        Assert.assertFalse(
+                "Should not be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
+    }
+
+    /**
+     * Tests that URLs are shown for non-native UI.
+     */
+    @Test
+    @MediumTest
+    public void testUrlOnNonNativeUi()
+            throws IllegalArgumentException, InterruptedException, TimeoutException {
+        mVrTestRule.loadUrl(TEST_PAGE_2D_URL, PAGE_LOAD_TIMEOUT_S);
         Assert.assertTrue("Should be showing URL", VrShellDelegate.isDisplayingUrlForTesting());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
index 99595a3..22a54c0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
@@ -117,7 +117,7 @@
     public void testLaunchAndNavigateOffOrigin() throws Exception {
         startWebApkActivity("org.chromium.webapk.test",
                 mTestServer.getURL("/chrome/test/data/android/test.html"));
-        waitUntilSplashscreenHides();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         // We navigate outside origin and expect Custom Tab to open on top of WebApkActivity.
         mActivityTestRule.runJavaScriptCodeInCurrentTab(
diff --git a/chrome/app/bookmarks_strings.grdp b/chrome/app/bookmarks_strings.grdp
index fbea426..31d520ee 100644
--- a/chrome/app/bookmarks_strings.grdp
+++ b/chrome/app/bookmarks_strings.grdp
@@ -425,23 +425,30 @@
   <message name="IDS_MD_BOOKMARK_MANAGER_ITEMS_SELECTED" desc="Label displayed in bookmark manager toolbar telling the user how many items they have selected.">
     <ph name="NUMBER_OF_ITEMS_SELECTED">$1</ph> selected
   </message>
+  <message name="IDS_MD_BOOKMARK_MANAGER_SEARCH_RESULTS" desc="Message announced by screenreaders when search results are found.">
+    Search results for '<ph name="SEARCH_STRING">$1<ex>reading</ex></ph>'
+  </message>
   <message name="IDS_MD_BOOKMARK_MANAGER_TITLE" desc="Title of the bookmark manager window.">
     Bookmarks
   </message>
   <message name="IDS_MD_BOOKMARK_MANAGER_TOAST_FOLDER_SORTED" desc="Label displayed in toast popup message when a folder's children are sorted.">
     Folder sorted
   </message>
-  <message name="IDS_MD_BOOKMARK_MANAGER_TOAST_ITEMS_DELETED" desc="Label displayed in toast popup message when several items are deleted.">
+  <message name="IDS_MD_BOOKMARK_MANAGER_TOAST_ITEM_DELETED" desc="Label displayed in toast popup message when a single item is deleted.">
+    '<ph name="DELETED_ITEM_NAME">$1<ex>Bookmark X</ex></ph>' has been deleted
+  </message>
+  <message name="IDS_MD_BOOKMARK_MANAGER_TOAST_ITEMS_DELETED" desc="Label displayed in toast popup message when two or more items are deleted.">
     {COUNT, plural,
-      =1 {'<ph name="DELETED_ITEM_NAME">$1</ph>' has been deleted}
       other {# bookmarks deleted}}
   </message>
   <message name="IDS_MD_BOOKMARK_MANAGER_TOAST_URL_COPIED" desc="Label displayed in toast popup message when a URL is copied.">
     URL copied
   </message>
-  <message name="IDS_MD_BOOKMARK_MANAGER_TOAST_ITEMS_COPIED" desc="Label displayed in a toast popup message when several bookmark items are copied">
+  <message name="IDS_MD_BOOKMARK_MANAGER_TOAST_ITEM_COPIED" desc="Label displayed in toast popup message when a single item is copied.">
+    '<ph name="COPIED_ITEM_NAME">$1<ex>Bookmark X</ex></ph>' copied
+  </message>
+  <message name="IDS_MD_BOOKMARK_MANAGER_TOAST_ITEMS_COPIED" desc="Label displayed in a toast popup message when two or more bookmark items are copied">
     {COUNT, plural,
-      =1 {'<ph name="COPIED_ITEM_NAME">$1</ph>' copied}
       other {# items copied}}
   </message>
   <!-- End of material design Bookmarks Manager strings. -->
diff --git a/chrome/app/theme/default_100_percent/common/ntp_welcome_thumb.png b/chrome/app/theme/default_100_percent/common/ntp_welcome_thumb.png
index c9ca730..6628ced3 100644
--- a/chrome/app/theme/default_100_percent/common/ntp_welcome_thumb.png
+++ b/chrome/app/theme/default_100_percent/common/ntp_welcome_thumb.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/ntp_webstore_thumb.png b/chrome/app/theme/default_100_percent/ntp_webstore_thumb.png
index ecd34b8..55bcd9f 100644
--- a/chrome/app/theme/default_100_percent/ntp_webstore_thumb.png
+++ b/chrome/app/theme/default_100_percent/ntp_webstore_thumb.png
Binary files differ
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc
index 651b368a..887bcfb9 100644
--- a/chrome/browser/android/vr_shell/vr_shell.cc
+++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -367,9 +367,7 @@
 bool VrShell::IsDisplayingUrlForTesting(
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& obj) {
-  // TODO(tiborg): this should return ShouldDisplayURL when it is available.
-  // crbug.com/738583
-  return true;
+  return ShouldDisplayURL();
 }
 
 void VrShell::OnLoadProgressChanged(JNIEnv* env,
@@ -738,6 +736,12 @@
   return web_contents_;
 }
 
+bool VrShell::ShouldDisplayURL() const {
+  // It's possible for there to be no web contents, e.g. on the new tab page.
+  return GetActiveWebContents() &&
+         ChromeToolbarModelDelegate::ShouldDisplayURL();
+}
+
 // ----------------------------------------------------------------------------
 // Native JNI methods
 // ----------------------------------------------------------------------------
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h
index d4f111e..a3a67b1d 100644
--- a/chrome/browser/android/vr_shell/vr_shell.h
+++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -186,6 +186,7 @@
 
   // ChromeToolbarModelDelegate implementation.
   content::WebContents* GetActiveWebContents() const override;
+  bool ShouldDisplayURL() const override;
 
  private:
   ~VrShell() override;
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc b/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc
index 2b15057..7bd33f6 100644
--- a/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc
+++ b/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc
@@ -35,13 +35,13 @@
 
 }  // namespace
 
-class MagnificationManagerTest : public ash::test::AshTestBase {
+class MagnificationManagerTest : public ash::AshTestBase {
  public:
   MagnificationManagerTest() {
   }
 
   void SetUp() override {
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
     MagnificationManager::Initialize();
     ASSERT_TRUE(MagnificationManager::Get());
     MagnificationManager::Get()->SetProfileForTest(&profile_);
@@ -49,7 +49,7 @@
 
   void TearDown() override {
     MagnificationManager::Shutdown();
-    ash::test::AshTestBase::TearDown();
+    ash::AshTestBase::TearDown();
   }
 
   TestingProfile profile_;
diff --git a/chrome/browser/chromeos/accessibility/select_to_speak_event_handler_unittest.cc b/chrome/browser/chromeos/accessibility/select_to_speak_event_handler_unittest.cc
index 79d31f9f..9b2a2fd 100644
--- a/chrome/browser/chromeos/accessibility/select_to_speak_event_handler_unittest.cc
+++ b/chrome/browser/chromeos/accessibility/select_to_speak_event_handler_unittest.cc
@@ -73,14 +73,14 @@
   DISALLOW_COPY_AND_ASSIGN(SelectToSpeakMouseEventDelegate);
 };
 
-class SelectToSpeakEventHandlerTest : public ash::test::AshTestBase {
+class SelectToSpeakEventHandlerTest : public ash::AshTestBase {
  public:
   SelectToSpeakEventHandlerTest()
       : generator_(nullptr),
         select_to_speak_event_handler_(new SelectToSpeakEventHandler()) {}
 
   void SetUp() override {
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
     mouse_event_delegate_.reset(new SelectToSpeakMouseEventDelegate());
     select_to_speak_event_handler_->CaptureForwardedEventsForTesting(
         mouse_event_delegate_.get());
@@ -95,7 +95,7 @@
         select_to_speak_event_handler_.get());
     CurrentContext()->RemovePreTargetHandler(&event_capturer_);
     generator_ = nullptr;
-    ash::test::AshTestBase::TearDown();
+    ash::AshTestBase::TearDown();
   }
 
  protected:
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc
index 2d471da..b7ea92c 100644
--- a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc
+++ b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc
@@ -71,7 +71,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestDelegate);
 };
 
-class SpokenFeedbackEventRewriterTest : public ash::test::AshTestBase {
+class SpokenFeedbackEventRewriterTest : public ash::AshTestBase {
  public:
   SpokenFeedbackEventRewriterTest()
       : generator_(nullptr),
@@ -82,7 +82,7 @@
   }
 
   void SetUp() override {
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
     generator_ = &AshTestBase::GetEventGenerator();
     CurrentContext()->AddPreTargetHandler(&event_capturer_);
     CurrentContext()->GetHost()->GetEventSource()->AddEventRewriter(
@@ -94,7 +94,7 @@
         spoken_feedback_event_rewriter_.get());
     CurrentContext()->RemovePreTargetHandler(&event_capturer_);
     generator_ = nullptr;
-    ash::test::AshTestBase::TearDown();
+    ash::AshTestBase::TearDown();
   }
 
  protected:
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc
index a81be99..0d4d1d0 100644
--- a/chrome/browser/chromeos/arc/arc_service_launcher.cc
+++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -36,7 +36,6 @@
 #include "chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
-#include "chromeos/chromeos_switches.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/arc_session.h"
 #include "components/arc/arc_session_runner.h"
@@ -96,24 +95,6 @@
   // List in lexicographical order.
   arc_service_manager_->AddService(
       base::MakeUnique<ArcIntentHelperBridge>(arc_bridge_service));
-  arc_service_manager_->AddService(
-      base::MakeUnique<ArcSettingsService>(arc_bridge_service));
-  arc_service_manager_->AddService(
-      base::MakeUnique<ArcUserSessionService>(arc_bridge_service));
-  if (chromeos::switches::IsVoiceInteractionEnabled()) {
-    arc_service_manager_->AddService(
-        base::MakeUnique<ArcVoiceInteractionFrameworkService>(
-            arc_bridge_service));
-    arc_service_manager_->AddService(
-        base::MakeUnique<ArcVoiceInteractionArcHomeService>(
-            arc_bridge_service));
-  }
-  arc_service_manager_->AddService(
-      base::MakeUnique<ArcVolumeMounterBridge>(arc_bridge_service));
-  arc_service_manager_->AddService(
-      base::MakeUnique<ArcWallpaperService>(arc_bridge_service));
-  arc_service_manager_->AddService(
-      base::MakeUnique<GpuArcVideoServiceHost>(arc_bridge_service));
 }
 
 void ArcServiceLauncher::MaybeSetProfile(Profile* profile) {
@@ -165,6 +146,7 @@
   ArcAuthService::GetForBrowserContext(profile);
   ArcBluetoothBridge::GetForBrowserContext(profile);
   ArcBootErrorNotification::GetForBrowserContext(profile);
+  ArcBootPhaseMonitorBridge::GetForBrowserContext(profile);
   ArcClipboardBridge::GetForBrowserContext(profile);
   ArcCrashCollectorBridge::GetForBrowserContext(profile);
   ArcDownloadsWatcherService::GetForBrowserContext(profile);
@@ -179,12 +161,16 @@
   ArcPrintService::GetForBrowserContext(profile);
   ArcProcessService::GetForBrowserContext(profile);
   ArcProvisionNotificationService::GetForBrowserContext(profile);
+  ArcSettingsService::GetForBrowserContext(profile);
   ArcTracingBridge::GetForBrowserContext(profile);
   ArcTtsService::GetForBrowserContext(profile);
+  ArcUserSessionService::GetForBrowserContext(profile);
+  ArcVoiceInteractionArcHomeService::GetForBrowserContext(profile);
+  ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile);
+  ArcVolumeMounterBridge::GetForBrowserContext(profile);
+  ArcWallpaperService::GetForBrowserContext(profile);
+  GpuArcVideoServiceHost::GetForBrowserContext(profile);
 
-  arc_service_manager_->AddService(base::MakeUnique<ArcBootPhaseMonitorBridge>(
-      arc_service_manager_->arc_bridge_service(),
-      multi_user_util::GetAccountIdFromProfile(profile)));
   arc_service_manager_->AddService(
       base::MakeUnique<ArcFileSystemOperationRunner>(
           arc_service_manager_->arc_bridge_service(), profile));
diff --git a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.cc b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.cc
index 6ec026b..ed93d8d 100644
--- a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.cc
+++ b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.cc
@@ -4,14 +4,19 @@
 
 #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h"
 
+#include <utility>
+
 #include "base/bind.h"
 #include "base/logging.h"
+#include "base/memory/singleton.h"
 #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
 #include "chromeos/cryptohome/cryptohome_parameters.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 
 namespace {
 
@@ -23,23 +28,60 @@
 }  // namespace
 
 namespace arc {
+namespace {
+
+// Singleton factory for ArcBootPhaseMonitorBridge.
+class ArcBootPhaseMonitorBridgeFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          ArcBootPhaseMonitorBridge,
+          ArcBootPhaseMonitorBridgeFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName = "ArcBootPhaseMonitorBridgeFactory";
+
+  static ArcBootPhaseMonitorBridgeFactory* GetInstance() {
+    return base::Singleton<ArcBootPhaseMonitorBridgeFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<ArcBootPhaseMonitorBridgeFactory>;
+  ArcBootPhaseMonitorBridgeFactory() = default;
+  ~ArcBootPhaseMonitorBridgeFactory() override = default;
+};
+
+}  // namespace
+
+// static
+ArcBootPhaseMonitorBridge* ArcBootPhaseMonitorBridge::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return ArcBootPhaseMonitorBridgeFactory::GetForBrowserContext(context);
+}
 
 ArcBootPhaseMonitorBridge::ArcBootPhaseMonitorBridge(
-    ArcBridgeService* bridge_service,
-    const AccountId& account_id)
-    : ArcService(bridge_service), account_id_(account_id), binding_(this) {
-  arc_bridge_service()->boot_phase_monitor()->AddObserver(this);
+    content::BrowserContext* context,
+    ArcBridgeService* bridge_service)
+    : arc_bridge_service_(bridge_service),
+      account_id_(multi_user_util::GetAccountIdFromProfile(
+          Profile::FromBrowserContext(context))),
+      binding_(this) {
+  arc_bridge_service_->boot_phase_monitor()->AddObserver(this);
 }
 
 ArcBootPhaseMonitorBridge::~ArcBootPhaseMonitorBridge() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  arc_bridge_service()->boot_phase_monitor()->RemoveObserver(this);
+
+  // TODO(hidehiko): Currently, the lifetime of ArcBridgeService and
+  // BrowserContextKeyedService is not nested.
+  // If ArcServiceManager::Get() returns nullptr, it is already destructed,
+  // so do not touch it.
+  if (ArcServiceManager::Get())
+    arc_bridge_service_->boot_phase_monitor()->RemoveObserver(this);
 }
 
 void ArcBootPhaseMonitorBridge::OnInstanceReady() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   auto* instance = ARC_GET_INSTANCE_FOR_METHOD(
-      arc_bridge_service()->boot_phase_monitor(), Init);
+      arc_bridge_service_->boot_phase_monitor(), Init);
   DCHECK(instance);
   mojom::BootPhaseMonitorHostPtr host_proxy;
   binding_.Bind(mojo::MakeRequest(&host_proxy));
diff --git a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h
index 3c88d07..750d4b2 100644
--- a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h
+++ b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h
@@ -9,12 +9,16 @@
 
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
-#include "components/arc/arc_service.h"
 #include "components/arc/common/boot_phase_monitor.mojom.h"
 #include "components/arc/instance_holder.h"
+#include "components/keyed_service/core/keyed_service.h"
 #include "components/signin/core/account_id/account_id.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
+namespace content {
+class BrowserContext;
+}  // namespace content
+
 namespace arc {
 
 class ArcBridgeService;
@@ -22,12 +26,17 @@
 
 // Receives boot phase notifications from ARC.
 class ArcBootPhaseMonitorBridge
-    : public ArcService,
+    : public KeyedService,
       public InstanceHolder<mojom::BootPhaseMonitorInstance>::Observer,
       public mojom::BootPhaseMonitorHost {
  public:
-  ArcBootPhaseMonitorBridge(ArcBridgeService* bridge_service,
-                            const AccountId& account_id);
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static ArcBootPhaseMonitorBridge* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  ArcBootPhaseMonitorBridge(content::BrowserContext* context,
+                            ArcBridgeService* bridge_service);
   ~ArcBootPhaseMonitorBridge() override;
 
   // InstanceHolder<mojom::BootPhaseMonitorInstance>::Observer
@@ -40,6 +49,7 @@
  private:
   THREAD_CHECKER(thread_checker_);
 
+  ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
   const AccountId account_id_;
   mojo::Binding<mojom::BootPhaseMonitorHost> binding_;
   std::unique_ptr<ArcInstanceThrottle> throttle_;
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc
index fc980864..f9d8626 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc
@@ -9,11 +9,12 @@
 #include "base/command_line.h"
 #include "base/gtest_prod_util.h"
 #include "base/json/json_writer.h"
+#include "base/memory/singleton.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/network/network_handler.h"
@@ -25,6 +26,7 @@
 #include "chromeos/settings/cros_settings_names.h"
 #include "chromeos/settings/timezone_settings.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/arc/intent_helper/font_size_util.h"
 #include "components/onc/onc_pref_names.h"
 #include "components/prefs/pref_change_registrar.h"
@@ -67,20 +69,31 @@
   return !host->empty() && *port;
 }
 
-PrefService* GetPrefs() {
-  return ProfileManager::GetActiveUserProfile()->GetPrefs();
-}
-
-// Returns whether kProxy pref proxy config is applied.
-bool IsPrefProxyConfigApplied() {
-  net::ProxyConfig config;
-  return PrefProxyConfigTrackerImpl::PrefPrecedes(
-      PrefProxyConfigTrackerImpl::ReadPrefConfig(GetPrefs(), &config));
-}
-
 }  // namespace
 
 namespace arc {
+namespace {
+
+// Singleton factory for ArcSettingsService.
+class ArcSettingsServiceFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          ArcSettingsService,
+          ArcSettingsServiceFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName = "ArcSettingsServiceFactory";
+
+  static ArcSettingsServiceFactory* GetInstance() {
+    return base::Singleton<ArcSettingsServiceFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<ArcSettingsServiceFactory>;
+  ArcSettingsServiceFactory() = default;
+  ~ArcSettingsServiceFactory() override = default;
+};
+
+}  // namespace
 
 // Listens to changes for select Chrome settings (prefs) that Android cares
 // about and sends the new values to Android to keep the state in sync.
@@ -90,7 +103,8 @@
       public ArcSessionManager::Observer,
       public chromeos::NetworkStateHandlerObserver {
  public:
-  explicit ArcSettingsServiceImpl(ArcBridgeService* arc_bridge_service);
+  ArcSettingsServiceImpl(content::BrowserContext* context,
+                         ArcBridgeService* arc_bridge_service);
   ~ArcSettingsServiceImpl() override;
 
   // Called when a Chrome pref we have registered an observer for has changed.
@@ -111,6 +125,13 @@
   void DefaultNetworkChanged(const chromeos::NetworkState* network) override;
 
  private:
+  PrefService* GetPrefs() const {
+    return Profile::FromBrowserContext(context_)->GetPrefs();
+  }
+
+  // Returns whether kProxy pref proxy config is applied.
+  bool IsPrefProxyConfigApplied() const;
+
   // Registers to observe changes for Chrome settings we care about.
   void StartObservingSettingsChanges();
 
@@ -168,12 +189,14 @@
   void SendSettingsBroadcast(const std::string& action,
                              const base::DictionaryValue& extras) const;
 
+  content::BrowserContext* const context_;
+  ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
+
   // Manages pref observation registration.
   PrefChangeRegistrar registrar_;
 
   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
       reporting_consent_subscription_;
-  ArcBridgeService* const arc_bridge_service_;
 
   scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
 
@@ -184,8 +207,11 @@
 };
 
 ArcSettingsServiceImpl::ArcSettingsServiceImpl(
+    content::BrowserContext* context,
     ArcBridgeService* arc_bridge_service)
-    : arc_bridge_service_(arc_bridge_service), weak_factory_(this) {
+    : context_(context),
+      arc_bridge_service_(arc_bridge_service),
+      weak_factory_(this) {
   StartObservingSettingsChanges();
   SyncRuntimeSettings();
   DCHECK(ArcSessionManager::Get());
@@ -270,6 +296,12 @@
     SyncProxySettings();
 }
 
+bool ArcSettingsServiceImpl::IsPrefProxyConfigApplied() const {
+  net::ProxyConfig config;
+  return PrefProxyConfigTrackerImpl::PrefPrecedes(
+      PrefProxyConfigTrackerImpl::ReadPrefConfig(GetPrefs(), &config));
+}
+
 void ArcSettingsServiceImpl::StartObservingSettingsChanges() {
   registrar_.Init(GetPrefs());
 
@@ -609,17 +641,30 @@
                           extras_json);
 }
 
-ArcSettingsService::ArcSettingsService(ArcBridgeService* bridge_service)
-    : ArcService(bridge_service) {
-  arc_bridge_service()->intent_helper()->AddObserver(this);
+// static
+ArcSettingsService* ArcSettingsService::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return ArcSettingsServiceFactory::GetForBrowserContext(context);
+}
+
+ArcSettingsService::ArcSettingsService(content::BrowserContext* context,
+                                       ArcBridgeService* bridge_service)
+    : context_(context), arc_bridge_service_(bridge_service) {
+  arc_bridge_service_->intent_helper()->AddObserver(this);
 }
 
 ArcSettingsService::~ArcSettingsService() {
-  arc_bridge_service()->intent_helper()->RemoveObserver(this);
+  // TODO(hidehiko): Currently, the lifetime of ArcBridgeService and
+  // BrowserContextKeyedService is not nested.
+  // If ArcServiceManager::Get() returns nullptr, it is already destructed,
+  // so do not touch it.
+  if (ArcServiceManager::Get())
+    arc_bridge_service_->intent_helper()->RemoveObserver(this);
 }
 
 void ArcSettingsService::OnInstanceReady() {
-  impl_.reset(new ArcSettingsServiceImpl(arc_bridge_service()));
+  impl_ =
+      base::MakeUnique<ArcSettingsServiceImpl>(context_, arc_bridge_service_);
 }
 
 void ArcSettingsService::OnInstanceClosed() {
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.h b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.h
index 2fdaeb6..d686246 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.h
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.h
@@ -8,9 +8,13 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "components/arc/arc_service.h"
 #include "components/arc/common/intent_helper.mojom.h"
 #include "components/arc/instance_holder.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace content {
+class BrowserContext;
+}  // namespace content
 
 namespace arc {
 
@@ -18,10 +22,16 @@
 class ArcSettingsServiceImpl;
 
 class ArcSettingsService
-    : public ArcService,
+    : public KeyedService,
       public InstanceHolder<mojom::IntentHelperInstance>::Observer {
  public:
-  explicit ArcSettingsService(ArcBridgeService* bridge_service);
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static ArcSettingsService* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  ArcSettingsService(content::BrowserContext* context,
+                     ArcBridgeService* bridge_service);
   ~ArcSettingsService() override;
 
   // InstanceHolder<mojom::IntentHelperInstance>::Observer
@@ -29,6 +39,8 @@
   void OnInstanceClosed() override;
 
  private:
+  content::BrowserContext* const context_;
+  ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
   std::unique_ptr<ArcSettingsServiceImpl> impl_;
 
   DISALLOW_COPY_AND_ASSIGN(ArcSettingsService);
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
index ff038640..5c075af 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
@@ -28,6 +28,7 @@
 #include "chromeos/network/proxy/proxy_config_handler.h"
 #include "components/arc/arc_bridge_service.h"
 #include "components/arc/arc_service_manager.h"
+#include "components/arc/arc_util.h"
 #include "components/arc/test/fake_intent_helper_instance.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
@@ -223,6 +224,10 @@
   // InProcessBrowserTest:
   ~ArcSettingsServiceTest() override = default;
 
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    arc::SetArcAvailableCommandLineForTesting(command_line);
+  }
+
   void SetUpInProcessBrowserTestFixture() override {
     EXPECT_CALL(provider_, IsInitializationComplete(_))
         .WillRepeatedly(Return(true));
diff --git a/chrome/browser/chromeos/arc/user_session/arc_user_session_service.cc b/chrome/browser/chromeos/arc/user_session/arc_user_session_service.cc
index 49a5879..6b412bb 100644
--- a/chrome/browser/chromeos/arc/user_session/arc_user_session_service.cc
+++ b/chrome/browser/chromeos/arc/user_session/arc_user_session_service.cc
@@ -4,18 +4,53 @@
 
 #include "chrome/browser/chromeos/arc/user_session/arc_user_session_service.h"
 
+#include "base/memory/singleton.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/session_manager/core/session_manager.h"
 
 namespace arc {
+namespace {
 
-ArcUserSessionService::ArcUserSessionService(ArcBridgeService* bridge_service)
-    : ArcService(bridge_service) {
-  arc_bridge_service()->intent_helper()->AddObserver(this);
+// Singleton factory for ArcUserSessionService.
+class ArcUserSessionServiceFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          ArcUserSessionService,
+          ArcUserSessionServiceFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName = "ArcUserSessionServiceFactory";
+
+  static ArcUserSessionServiceFactory* GetInstance() {
+    return base::Singleton<ArcUserSessionServiceFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<ArcUserSessionServiceFactory>;
+  ArcUserSessionServiceFactory() = default;
+  ~ArcUserSessionServiceFactory() override = default;
+};
+
+}  // namespace
+
+ArcUserSessionService* ArcUserSessionService::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return ArcUserSessionServiceFactory::GetForBrowserContext(context);
+}
+
+ArcUserSessionService::ArcUserSessionService(content::BrowserContext* context,
+                                             ArcBridgeService* bridge_service)
+    : arc_bridge_service_(bridge_service) {
+  arc_bridge_service_->intent_helper()->AddObserver(this);
 }
 
 ArcUserSessionService::~ArcUserSessionService() {
-  arc_bridge_service()->intent_helper()->RemoveObserver(this);
+  // TODO(hidehiko): Currently, the lifetime of ArcBridgeService and
+  // BrowserContextKeyedService is not nested.
+  // If ArcServiceManager::Get() returns nullptr, it is already destructed,
+  // so do not touch it.
+  if (ArcServiceManager::Get())
+    arc_bridge_service_->intent_helper()->RemoveObserver(this);
 }
 
 void ArcUserSessionService::OnSessionStateChanged() {
@@ -25,7 +60,7 @@
     return;
 
   auto* instance = ARC_GET_INSTANCE_FOR_METHOD(
-      arc_bridge_service()->intent_helper(), SendBroadcast);
+      arc_bridge_service_->intent_helper(), SendBroadcast);
   if (!instance)
     return;
 
diff --git a/chrome/browser/chromeos/arc/user_session/arc_user_session_service.h b/chrome/browser/chromeos/arc/user_session/arc_user_session_service.h
index d8d006fc..0a59166 100644
--- a/chrome/browser/chromeos/arc/user_session/arc_user_session_service.h
+++ b/chrome/browser/chromeos/arc/user_session/arc_user_session_service.h
@@ -6,21 +6,31 @@
 #define CHROME_BROWSER_CHROMEOS_ARC_USER_SESSION_ARC_USER_SESSION_SERVICE_H_
 
 #include "base/macros.h"
-#include "components/arc/arc_service.h"
 #include "components/arc/common/intent_helper.mojom.h"
 #include "components/arc/instance_holder.h"
+#include "components/keyed_service/core/keyed_service.h"
 #include "components/session_manager/core/session_manager_observer.h"
 
+namespace content {
+class BrowserContext;
+}  // namespace content
+
 namespace arc {
 
 class ArcBridgeService;
 
 class ArcUserSessionService
-    : public ArcService,
+    : public KeyedService,
       public InstanceHolder<mojom::IntentHelperInstance>::Observer,
       public session_manager::SessionManagerObserver {
  public:
-  explicit ArcUserSessionService(ArcBridgeService* bridge_service);
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static ArcUserSessionService* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  ArcUserSessionService(content::BrowserContext* context,
+                        ArcBridgeService* bridge_service);
   ~ArcUserSessionService() override;
 
   // InstanceHolder<mojom::IntentHelperInstance>::Observer
@@ -31,6 +41,8 @@
   void OnSessionStateChanged() override;
 
  private:
+  ArcBridgeService* const arc_bridge_service_;
+
   DISALLOW_COPY_AND_ASSIGN(ArcUserSessionService);
 };
 
diff --git a/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc b/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc
index a86259c9..2a955fa 100644
--- a/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc
+++ b/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc
@@ -7,6 +7,7 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/arc/arc_bridge_service.h"
 #include "components/arc/arc_service_manager.h"
+#include "components/arc/arc_util.h"
 #include "components/arc/test/fake_intent_helper_instance.h"
 #include "components/session_manager/core/session_manager.h"
 
@@ -43,6 +44,10 @@
   // InProcessBrowserTest:
   ~ArcUserSessionServiceTest() override = default;
 
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    arc::SetArcAvailableCommandLineForTesting(command_line);
+  }
+
   void SetUpInProcessBrowserTestFixture() override {
     fake_intent_helper_instance_.reset(new FakeIntentHelperInstance());
   }
diff --git a/chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.cc b/chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.cc
index 70b43767..c2dfac9 100644
--- a/chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.cc
+++ b/chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.cc
@@ -10,9 +10,11 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/singleton.h"
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/arc/common/video_decode_accelerator.mojom.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/gpu_service_registry.h"
@@ -36,6 +38,25 @@
   content::BindInterfaceInGpuProcess(std::move(request));
 }
 
+// Singleton factory for GpuArcVideoServiceHost.
+class GpuArcVideoServiceHostFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          GpuArcVideoServiceHost,
+          GpuArcVideoServiceHostFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName = "GpuArcVideoServiceHostFactory";
+
+  static GpuArcVideoServiceHostFactory* GetInstance() {
+    return base::Singleton<GpuArcVideoServiceHostFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<GpuArcVideoServiceHostFactory>;
+  GpuArcVideoServiceHostFactory() = default;
+  ~GpuArcVideoServiceHostFactory() override = default;
+};
+
 }  // namespace
 
 class VideoAcceleratorFactoryService : public mojom::VideoAcceleratorFactory {
@@ -62,21 +83,33 @@
   DISALLOW_COPY_AND_ASSIGN(VideoAcceleratorFactoryService);
 };
 
-GpuArcVideoServiceHost::GpuArcVideoServiceHost(ArcBridgeService* bridge_service)
-    : ArcService(bridge_service), binding_(this) {
+// static
+GpuArcVideoServiceHost* GpuArcVideoServiceHost::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return GpuArcVideoServiceHostFactory::GetForBrowserContext(context);
+}
+
+GpuArcVideoServiceHost::GpuArcVideoServiceHost(content::BrowserContext* context,
+                                               ArcBridgeService* bridge_service)
+    : arc_bridge_service_(bridge_service), binding_(this) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  arc_bridge_service()->video()->AddObserver(this);
+  arc_bridge_service_->video()->AddObserver(this);
 }
 
 GpuArcVideoServiceHost::~GpuArcVideoServiceHost() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  arc_bridge_service()->video()->RemoveObserver(this);
+  // TODO(hidehiko): Currently, the lifetime of ArcBridgeService and
+  // BrowserContextKeyedService is not nested.
+  // If ArcServiceManager::Get() returns nullptr, it is already destructed,
+  // so do not touch it.
+  if (ArcServiceManager::Get())
+    arc_bridge_service_->video()->RemoveObserver(this);
 }
 
 void GpuArcVideoServiceHost::OnInstanceReady() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   auto* video_instance =
-      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service()->video(), Init);
+      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->video(), Init);
   DCHECK(video_instance);
   mojom::VideoHostPtr host_proxy;
   binding_.Bind(mojo::MakeRequest(&host_proxy));
diff --git a/chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.h b/chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.h
index 7ea0afd..9faa7278 100644
--- a/chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.h
+++ b/chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.h
@@ -6,11 +6,15 @@
 #define CHROME_BROWSER_CHROMEOS_ARC_VIDEO_GPU_ARC_VIDEO_SERVICE_HOST_H_
 
 #include "base/macros.h"
-#include "components/arc/arc_service.h"
 #include "components/arc/common/video.mojom.h"
 #include "components/arc/instance_holder.h"
+#include "components/keyed_service/core/keyed_service.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
+namespace content {
+class BrowserContext;
+}  // namespace content
+
 namespace arc {
 
 class ArcBridgeService;
@@ -23,11 +27,17 @@
 //
 // Lives on the UI thread.
 class GpuArcVideoServiceHost
-    : public ArcService,
+    : public KeyedService,
       public InstanceHolder<mojom::VideoInstance>::Observer,
       public mojom::VideoHost {
  public:
-  explicit GpuArcVideoServiceHost(ArcBridgeService* bridge_service);
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static GpuArcVideoServiceHost* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  GpuArcVideoServiceHost(content::BrowserContext* context,
+                         ArcBridgeService* bridge_service);
   ~GpuArcVideoServiceHost() override;
 
   // arc::InstanceHolder<mojom::VideoInstance>::Observer implementation.
@@ -38,6 +48,7 @@
       const OnBootstrapVideoAcceleratorFactoryCallback& callback) override;
 
  private:
+  ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
   mojo::Binding<mojom::VideoHost> binding_;
 
   DISALLOW_COPY_AND_ASSIGN(GpuArcVideoServiceHost);
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.cc
index 9bf01d2..c065a9ab 100644
--- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.cc
+++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.cc
@@ -10,6 +10,7 @@
 #include "ash/shell.h"
 #include "base/bind.h"
 #include "base/logging.h"
+#include "base/memory/singleton.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
@@ -21,7 +22,9 @@
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chromeos/chromeos_switches.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/instance_holder.h"
 #include "content/public/browser/browser_thread.h"
@@ -80,23 +83,69 @@
   callback.Run(std::move(root));
 }
 
+// Singleton factory for ArcVoiceInteractionArcHomeService.
+class ArcVoiceInteractionArcHomeServiceFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          ArcVoiceInteractionArcHomeService,
+          ArcVoiceInteractionArcHomeServiceFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName =
+      "ArcVoiceInteractionArcHomeServiceFactory";
+
+  static ArcVoiceInteractionArcHomeServiceFactory* GetInstance() {
+    return base::Singleton<ArcVoiceInteractionArcHomeServiceFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<ArcVoiceInteractionArcHomeServiceFactory>;
+
+  ArcVoiceInteractionArcHomeServiceFactory() {
+    DependsOn(ArcVoiceInteractionFrameworkService::GetFactory());
+  }
+  ~ArcVoiceInteractionArcHomeServiceFactory() override = default;
+
+  // BrowserContextKeyedServiceFactory override:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override {
+    if (!chromeos::switches::IsVoiceInteractionEnabled())
+      return nullptr;
+    return ArcBrowserContextKeyedServiceFactoryBase::BuildServiceInstanceFor(
+        context);
+  }
+};
+
 }  // namespace
 
+// static
+ArcVoiceInteractionArcHomeService*
+ArcVoiceInteractionArcHomeService::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return ArcVoiceInteractionArcHomeServiceFactory::GetForBrowserContext(
+      context);
+}
+
 ArcVoiceInteractionArcHomeService::ArcVoiceInteractionArcHomeService(
+    content::BrowserContext* context,
     ArcBridgeService* bridge_service)
-    : ArcService(bridge_service), binding_(this) {
-  arc_bridge_service()->voice_interaction_arc_home()->AddObserver(this);
+    : context_(context), arc_bridge_service_(bridge_service), binding_(this) {
+  arc_bridge_service_->voice_interaction_arc_home()->AddObserver(this);
 }
 
 ArcVoiceInteractionArcHomeService::~ArcVoiceInteractionArcHomeService() {
-  arc_bridge_service()->voice_interaction_arc_home()->RemoveObserver(this);
+  // TODO(hidehiko): Currently, the lifetime of ArcBridgeService and
+  // BrowserContextKeyedService is not nested.
+  // If ArcServiceManager::Get() returns nullptr, it is already destructed,
+  // so do not touch it.
+  if (ArcServiceManager::Get())
+    arc_bridge_service_->voice_interaction_arc_home()->RemoveObserver(this);
 }
 
 void ArcVoiceInteractionArcHomeService::OnInstanceReady() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   mojom::VoiceInteractionArcHomeInstance* home_instance =
       ARC_GET_INSTANCE_FOR_METHOD(
-          arc_bridge_service()->voice_interaction_arc_home(), Init);
+          arc_bridge_service_->voice_interaction_arc_home(), Init);
   DCHECK(home_instance);
   mojom::VoiceInteractionArcHomeHostPtr host_proxy;
   binding_.Bind(mojo::MakeRequest(&host_proxy));
@@ -108,8 +157,7 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   auto* framework_service =
-      ArcServiceManager::Get()
-          ->GetService<ArcVoiceInteractionFrameworkService>();
+      ArcVoiceInteractionFrameworkService::GetForBrowserContext(context_);
   if (!framework_service->ValidateTimeSinceUserInteraction()) {
     callback.Run(mojom::VoiceInteractionStructure::New());
     return;
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h
index faf2d48..dc64a66 100644
--- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h
+++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h
@@ -6,26 +6,38 @@
 #define CHROME_BROWSER_CHROMEOS_ARC_VOICE_INTERACTION_ARC_VOICE_INTERACTION_ARC_HOME_SERVICE_H_
 
 #include "base/macros.h"
-#include "components/arc/arc_service.h"
 #include "components/arc/common/voice_interaction_arc_home.mojom.h"
 #include "components/arc/instance_holder.h"
+#include "components/keyed_service/core/keyed_service.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "ui/accessibility/ax_tree_update.h"
 
+namespace content {
+class BrowserContext;
+}  // namespace content
+
 namespace ui {
 struct AXSnapshotNodeAndroid;
 }  // ui
 
 namespace arc {
 
+class ArcBridgeService;
+
 // ArcVoiceInteractionArcHomeService provides view hierarchy to to ARC to be
 // used by VoiceInteractionSession. This class lives on the UI thread.
 class ArcVoiceInteractionArcHomeService
-    : public ArcService,
+    : public KeyedService,
       public mojom::VoiceInteractionArcHomeHost,
       public InstanceHolder<mojom::VoiceInteractionArcHomeInstance>::Observer {
  public:
-  explicit ArcVoiceInteractionArcHomeService(ArcBridgeService* bridge_service);
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static ArcVoiceInteractionArcHomeService* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  ArcVoiceInteractionArcHomeService(content::BrowserContext* context,
+                                    ArcBridgeService* bridge_service);
   ~ArcVoiceInteractionArcHomeService() override;
 
   // InstanceHolder<mojom::VoiceInteractionArcHomeInstance> overrides;
@@ -41,6 +53,9 @@
       const ui::AXSnapshotNodeAndroid& view_structure);
 
  private:
+  content::BrowserContext* const context_;
+  ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
+
   mojo::Binding<mojom::VoiceInteractionArcHomeHost> binding_;
 
   DISALLOW_COPY_AND_ASSIGN(ArcVoiceInteractionArcHomeService);
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc
index 7d2d7cd4..0547573 100644
--- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc
+++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc
@@ -16,13 +16,14 @@
 #include "base/containers/flat_set.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/singleton.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
 #include "base/task_scheduler/post_task.h"
 #include "chrome/browser/chromeos/login/helper.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
-#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
@@ -30,6 +31,7 @@
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_switches.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/arc/arc_util.h"
 #include "components/arc/instance_holder.h"
 #include "components/exo/surface.h"
@@ -158,27 +160,71 @@
       callback);
 }
 
+// Singleton factory for ArcVoiceInteractionFrameworkService.
+class ArcVoiceInteractionFrameworkServiceFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          ArcVoiceInteractionFrameworkService,
+          ArcVoiceInteractionFrameworkServiceFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName =
+      "ArcVoiceInteractionFrameworkServiceFactory";
+
+  static ArcVoiceInteractionFrameworkServiceFactory* GetInstance() {
+    return base::Singleton<ArcVoiceInteractionFrameworkServiceFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<
+      ArcVoiceInteractionFrameworkServiceFactory>;
+  ArcVoiceInteractionFrameworkServiceFactory() = default;
+  ~ArcVoiceInteractionFrameworkServiceFactory() override = default;
+
+  // BrowserContextKeyedServiceFactory override:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override {
+    if (!chromeos::switches::IsVoiceInteractionEnabled())
+      return nullptr;
+    return ArcBrowserContextKeyedServiceFactoryBase::BuildServiceInstanceFor(
+        context);
+  }
+};
+
 }  // namespace
 
 // static
-const char ArcVoiceInteractionFrameworkService::kArcServiceName[] =
-    "arc::ArcVoiceInteractionFrameworkService";
+ArcVoiceInteractionFrameworkService*
+ArcVoiceInteractionFrameworkService::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return ArcVoiceInteractionFrameworkServiceFactory::GetForBrowserContext(
+      context);
+}
+
+KeyedServiceBaseFactory* ArcVoiceInteractionFrameworkService::GetFactory() {
+  return ArcVoiceInteractionFrameworkServiceFactory::GetInstance();
+}
 
 ArcVoiceInteractionFrameworkService::ArcVoiceInteractionFrameworkService(
+    content::BrowserContext* context,
     ArcBridgeService* bridge_service)
-    : ArcService(bridge_service), binding_(this) {
-  arc_bridge_service()->voice_interaction_framework()->AddObserver(this);
+    : context_(context), arc_bridge_service_(bridge_service), binding_(this) {
+  arc_bridge_service_->voice_interaction_framework()->AddObserver(this);
 }
 
 ArcVoiceInteractionFrameworkService::~ArcVoiceInteractionFrameworkService() {
-  arc_bridge_service()->voice_interaction_framework()->RemoveObserver(this);
+  // TODO(hidehiko): Currently, the lifetime of ArcBridgeService and
+  // BrowserContextKeyedService is not nested.
+  // If ArcServiceManager::Get() returns nullptr, it is already destructed,
+  // so do not touch it.
+  if (ArcServiceManager::Get())
+    arc_bridge_service_->voice_interaction_framework()->RemoveObserver(this);
 }
 
 void ArcVoiceInteractionFrameworkService::OnInstanceReady() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   mojom::VoiceInteractionFrameworkInstance* framework_instance =
       ARC_GET_INSTANCE_FOR_METHOD(
-          arc_bridge_service()->voice_interaction_framework(), Init);
+          arc_bridge_service_->voice_interaction_framework(), Init);
   DCHECK(framework_instance);
   mojom::VoiceInteractionFrameworkHostPtr host_proxy;
   binding_.Bind(mojo::MakeRequest(&host_proxy));
@@ -323,7 +369,7 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   arc::mojom::VoiceInteractionFrameworkInstance* framework_instance =
       ARC_GET_INSTANCE_FOR_METHOD(
-          arc_bridge_service()->voice_interaction_framework(),
+          arc_bridge_service_->voice_interaction_framework(),
           StartVoiceInteractionSetupWizard);
   if (!framework_instance)
     return;
@@ -334,7 +380,7 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   mojom::VoiceInteractionFrameworkInstance* framework_instance =
       ARC_GET_INSTANCE_FOR_METHOD(
-          arc_bridge_service()->voice_interaction_framework(),
+          arc_bridge_service_->voice_interaction_framework(),
           SetMetalayerVisibility);
   if (!framework_instance) {
     CallAndResetMetalayerCallback();
@@ -357,7 +403,7 @@
 
   mojom::VoiceInteractionFrameworkInstance* framework_instance =
       ARC_GET_INSTANCE_FOR_METHOD(
-          arc_bridge_service()->voice_interaction_framework(),
+          arc_bridge_service_->voice_interaction_framework(),
           SetVoiceInteractionEnabled);
   if (!framework_instance)
     return;
@@ -370,7 +416,7 @@
 
   mojom::VoiceInteractionFrameworkInstance* framework_instance =
       ARC_GET_INSTANCE_FOR_METHOD(
-          arc_bridge_service()->voice_interaction_framework(),
+          arc_bridge_service_->voice_interaction_framework(),
           SetVoiceInteractionContextEnabled);
   if (!framework_instance)
     return;
@@ -381,7 +427,7 @@
     const gfx::Rect& rect) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (!ProfileManager::GetActiveUserProfile()->GetPrefs()->GetBoolean(
+  if (!Profile::FromBrowserContext(context_)->GetPrefs()->GetBoolean(
           prefs::kArcVoiceInteractionValuePropAccepted)) {
     // If voice interaction value prop already showing, return.
     if (chromeos::LoginDisplayHost::default_host())
@@ -396,7 +442,7 @@
     return;
   }
 
-  if (!arc_bridge_service()->voice_interaction_framework()->has_instance()) {
+  if (!arc_bridge_service_->voice_interaction_framework()->has_instance()) {
     SetArcCpuRestriction(false);
     return;
   }
@@ -407,14 +453,14 @@
   if (rect.IsEmpty()) {
     mojom::VoiceInteractionFrameworkInstance* framework_instance =
         ARC_GET_INSTANCE_FOR_METHOD(
-            arc_bridge_service()->voice_interaction_framework(),
+            arc_bridge_service_->voice_interaction_framework(),
             StartVoiceInteractionSession);
     DCHECK(framework_instance);
     framework_instance->StartVoiceInteractionSession();
   } else {
     mojom::VoiceInteractionFrameworkInstance* framework_instance =
         ARC_GET_INSTANCE_FOR_METHOD(
-            arc_bridge_service()->voice_interaction_framework(),
+            arc_bridge_service_->voice_interaction_framework(),
             StartVoiceInteractionSessionForRegion);
     DCHECK(framework_instance);
     framework_instance->StartVoiceInteractionSessionForRegion(rect);
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h
index 79658292..eba6931 100644
--- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h
+++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h
@@ -9,32 +9,48 @@
 
 #include "base/macros.h"
 #include "base/time/time.h"
-#include "components/arc/arc_service.h"
 #include "components/arc/common/voice_interaction_framework.mojom.h"
 #include "components/arc/instance_holder.h"
+#include "components/keyed_service/core/keyed_service.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/events/event_handler.h"
 
+class KeyedServiceBaseFactory;
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
 namespace gfx {
 class Rect;
 }  // namespace gfx
 
 namespace arc {
 
+class ArcBridgeService;
+
 // This provides voice interaction context (currently screenshots)
 // to ARC to be used by VoiceInteractionSession. This class lives on the UI
 // thread.
 class ArcVoiceInteractionFrameworkService
-    : public ArcService,
+    : public KeyedService,
       public mojom::VoiceInteractionFrameworkHost,
       public ui::AcceleratorTarget,
       public ui::EventHandler,
       public InstanceHolder<
           mojom::VoiceInteractionFrameworkInstance>::Observer {
  public:
-  explicit ArcVoiceInteractionFrameworkService(
-      ArcBridgeService* bridge_service);
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static ArcVoiceInteractionFrameworkService* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  // Returns factory for ArcVoiceInteractionFrameworkService.
+  static KeyedServiceBaseFactory* GetFactory();
+
+  ArcVoiceInteractionFrameworkService(content::BrowserContext* context,
+                                      ArcBridgeService* bridge_service);
   ~ArcVoiceInteractionFrameworkService() override;
 
   // InstanceHolder<mojom::VoiceInteractionFrameworkInstance> overrides.
@@ -86,9 +102,6 @@
   // Start the voice interaction setup wizard in container.
   void StartVoiceInteractionSetupWizard();
 
-  // For supporting ArcServiceManager::GetService<T>().
-  static const char kArcServiceName[];
-
  private:
   void SetMetalayerVisibility(bool visible);
 
@@ -96,6 +109,8 @@
 
   bool InitiateUserInteraction();
 
+  content::BrowserContext* context_;
+  ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager
   mojo::Binding<mojom::VoiceInteractionFrameworkHost> binding_;
   base::Closure metalayer_closed_callback_;
   bool metalayer_enabled_ = false;
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
index 5655d61a..bdef8ff 100644
--- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
+++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
@@ -7,15 +7,18 @@
 #include <stdlib.h>
 
 #include <deque>
+#include <utility>
 
 #include "ash/shell.h"
 #include "ash/wallpaper/wallpaper_controller.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/singleton.h"
 #include "base/task_scheduler/post_task.h"
 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
 #include "chrome/browser/image_decoder.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_manager.h"
 #include "components/wallpaper/wallpaper_files_id.h"
@@ -61,6 +64,25 @@
   return ash::Shell::Get()->wallpaper_controller();
 }
 
+// Singleton factory for ArcWallpaperService.
+class ArcWallpaperServiceFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          ArcWallpaperService,
+          ArcWallpaperServiceFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName = "ArcWallpaperServiceFactory";
+
+  static ArcWallpaperServiceFactory* GetInstance() {
+    return base::Singleton<ArcWallpaperServiceFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<ArcWallpaperServiceFactory>;
+  ArcWallpaperServiceFactory() = default;
+  ~ArcWallpaperServiceFactory() override = default;
+};
+
 }  // namespace
 
 struct ArcWallpaperService::WallpaperIdPair {
@@ -133,9 +155,16 @@
   DISALLOW_COPY_AND_ASSIGN(DecodeRequest);
 };
 
-ArcWallpaperService::ArcWallpaperService(ArcBridgeService* bridge_service)
-    : ArcService(bridge_service), binding_(this) {
-  arc_bridge_service()->wallpaper()->AddObserver(this);
+// static
+ArcWallpaperService* ArcWallpaperService::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return ArcWallpaperServiceFactory::GetForBrowserContext(context);
+}
+
+ArcWallpaperService::ArcWallpaperService(content::BrowserContext* context,
+                                         ArcBridgeService* bridge_service)
+    : arc_bridge_service_(bridge_service), binding_(this) {
+  arc_bridge_service_->wallpaper()->AddObserver(this);
 }
 
 ArcWallpaperService::~ArcWallpaperService() {
@@ -143,13 +172,19 @@
   ash::WallpaperController* wc = GetWallpaperController();
   if (wc)
     wc->RemoveObserver(this);
-  arc_bridge_service()->wallpaper()->RemoveObserver(this);
+
+  // TODO(hidehiko): Currently, the lifetime of ArcBridgeService and
+  // BrowserContextKeyedService is not nested.
+  // If ArcServiceManager::Get() returns nullptr, it is already destructed,
+  // so do not touch it.
+  if (ArcServiceManager::Get())
+    arc_bridge_service_->wallpaper()->RemoveObserver(this);
 }
 
 void ArcWallpaperService::OnInstanceReady() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   mojom::WallpaperInstance* wallpaper_instance =
-      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service()->wallpaper(), Init);
+      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->wallpaper(), Init);
   DCHECK(wallpaper_instance);
   mojom::WallpaperHostPtr host_proxy;
   binding_.Bind(mojo::MakeRequest(&host_proxy));
@@ -236,7 +271,7 @@
 
 void ArcWallpaperService::NotifyWallpaperChanged(int android_id) {
   mojom::WallpaperInstance* const wallpaper_instance =
-      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service()->wallpaper(),
+      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->wallpaper(),
                                   OnWallpaperChanged);
   if (wallpaper_instance == nullptr)
     return;
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.h b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.h
index b1eb04e..ed5e1a7 100644
--- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.h
+++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.h
@@ -12,23 +12,33 @@
 
 #include "ash/wallpaper/wallpaper_controller_observer.h"
 #include "base/macros.h"
-#include "components/arc/arc_service.h"
 #include "components/arc/common/wallpaper.mojom.h"
 #include "components/arc/instance_holder.h"
+#include "components/keyed_service/core/keyed_service.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
+namespace content {
+class BrowserContext;
+}  // namespace content
+
 namespace arc {
 
+class ArcBridgeService;
+
 // Lives on the UI thread.
 class ArcWallpaperService
-    : public ArcService,
+    : public KeyedService,
       public ash::WallpaperControllerObserver,
       public InstanceHolder<mojom::WallpaperInstance>::Observer,
       public mojom::WallpaperHost {
  public:
-  class AndroidIdStore;
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static ArcWallpaperService* GetForBrowserContext(
+      content::BrowserContext* context);
 
-  explicit ArcWallpaperService(ArcBridgeService* bridge_service);
+  ArcWallpaperService(content::BrowserContext* context,
+                      ArcBridgeService* bridge_service);
   ~ArcWallpaperService() override;
 
   // InstanceHolder<mojom::WallpaperInstance>::Observer overrides.
@@ -47,6 +57,7 @@
   void OnWallpaperDataChanged() override;
 
  private:
+  class AndroidIdStore;
   class DecodeRequest;
   struct WallpaperIdPair;
 
@@ -55,6 +66,8 @@
   // Notifies wallpaper change of |android_id|, then notify wallpaper change of
   // -1 to reset wallpaper cache at Android side.
   void NotifyWallpaperChangedAndReset(int android_id);
+
+  ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
   mojo::Binding<mojom::WallpaperHost> binding_;
   std::unique_ptr<DecodeRequest> decode_request_;
   std::vector<WallpaperIdPair> id_pairs_;
diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc
index 1cf0597..97d9f1e 100644
--- a/chrome/browser/chromeos/display/display_preferences_unittest.cc
+++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc
@@ -61,7 +61,7 @@
   return ash::Shell::Get()->screen_orientation_controller()->rotation_locked();
 }
 
-class DisplayPreferencesTest : public ash::test::AshTestBase {
+class DisplayPreferencesTest : public ash::AshTestBase {
  protected:
   DisplayPreferencesTest()
       : mock_user_manager_(new MockUserManager),
@@ -74,7 +74,7 @@
     EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
         .WillRepeatedly(testing::Return(false));
     EXPECT_CALL(*mock_user_manager_, Shutdown());
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
     RegisterDisplayLocalStatePrefs(local_state_.registry());
     TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
     observer_.reset(new DisplayConfigurationObserver());
@@ -83,7 +83,7 @@
   void TearDown() override {
     observer_.reset();
     TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr);
-    ash::test::AshTestBase::TearDown();
+    ash::AshTestBase::TearDown();
   }
 
   void LoggedInAsUser() {
diff --git a/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_controller_unittest.cc b/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_controller_unittest.cc
index ee4517b..7d085cb 100644
--- a/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_controller_unittest.cc
+++ b/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_controller_unittest.cc
@@ -21,7 +21,7 @@
 
 namespace chromeos {
 
-class TouchCalibratorControllerTest : public ash::test::AshTestBase {
+class TouchCalibratorControllerTest : public ash::AshTestBase {
  public:
   TouchCalibratorControllerTest() {}
 
diff --git a/chrome/browser/chromeos/events/event_rewriter_unittest.cc b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
index 552d77cd..69d6389 100644
--- a/chrome/browser/chromeos/events/event_rewriter_unittest.cc
+++ b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
@@ -121,7 +121,7 @@
 
 namespace chromeos {
 
-class EventRewriterTest : public ash::test::AshTestBase {
+class EventRewriterTest : public ash::AshTestBase {
  public:
   EventRewriterTest()
       : fake_user_manager_(new chromeos::FakeChromeUserManager),
@@ -2042,7 +2042,7 @@
 };
 
 // Tests of event rewriting that depend on the Ash window manager.
-class EventRewriterAshTest : public ash::test::AshTestBase {
+class EventRewriterAshTest : public ash::AshTestBase {
  public:
   EventRewriterAshTest()
       : source_(&buffer_),
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
index bc00d488..f86f60a 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
@@ -27,7 +27,7 @@
 const char kTestAccount1[] = "user1@test.com";
 const char kTestAccount2[] = "user2@test.com";
 
-class WallpaperPrivateApiUnittest : public ash::test::AshTestBase {
+class WallpaperPrivateApiUnittest : public ash::AshTestBase {
  public:
   WallpaperPrivateApiUnittest()
       : fake_user_manager_(new FakeChromeUserManager()),
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 9970e00..5cde8451 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -179,7 +179,8 @@
 WRAPPED_INSTANTIATE_TEST_CASE_P(
     QuickView,
     FileManagerBrowserTest,
-    ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openQuickView")));
+    ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openQuickView"),
+                      TestParameter(NOT_IN_GUEST_MODE, "closeQuickView")));
 
 #if defined(DISABLE_SLOW_FILESAPP_TESTS)
 #define MAYBE_DirectoryTreeContextMenu DISABLED_DirectoryTreeContextMenu
diff --git a/chrome/browser/chromeos/first_run/first_run.cc b/chrome/browser/chromeos/first_run/first_run.cc
index 012f3050..ea49346 100644
--- a/chrome/browser/chromeos/first_run/first_run.cc
+++ b/chrome/browser/chromeos/first_run/first_run.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/prefs/pref_service_syncable_util.h"
-#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/extensions/app_launch_params.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/common/chrome_switches.h"
@@ -111,13 +111,12 @@
 
     // If voice interaction value prop needs to be shown, the tutorial will be
     // shown after the voice interaction OOBE flow.
-    if (arc::IsArcPlayStoreEnabledForProfile(
-            ProfileManager::GetActiveUserProfile()) &&
+    if (arc::IsArcPlayStoreEnabledForProfile(profile_) &&
         !profile_->GetPrefs()->GetBoolean(
             prefs::kArcVoiceInteractionValuePropAccepted)) {
       auto* service =
-          arc::ArcServiceManager::Get()
-              ->GetService<arc::ArcVoiceInteractionFrameworkService>();
+          arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(
+              profile_);
       if (service)
         service->StartSessionFromUserInteraction(gfx::Rect());
     } else {
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index 2b54234f..7ac532c 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -125,6 +125,8 @@
     ::switches::kEnableViewport,
     ::switches::kEnableZeroCopy,
 #if defined(USE_OZONE)
+    ::switches::kEnableDrmAtomic,
+    ::switches::kEnableHardwareOverlays,
     ::switches::kExtraTouchNoiseFiltering,
     ::switches::kEdgeTouchFiltering,
 #endif
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc
index 4503144..e17f3a0 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc
@@ -33,7 +33,7 @@
 
 namespace chromeos {
 
-class WallpaperManagerCacheTest : public test::AshTestBase {
+class WallpaperManagerCacheTest : public AshTestBase {
  public:
   WallpaperManagerCacheTest()
       : fake_user_manager_(new FakeChromeUserManager()),
@@ -45,13 +45,13 @@
   FakeChromeUserManager* fake_user_manager() { return fake_user_manager_; }
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     WallpaperManager::Initialize();
   }
 
   void TearDown() override {
     WallpaperManager::Shutdown();
-    test::AshTestBase::TearDown();
+    AshTestBase::TearDown();
   }
 
   // Creates a test image of size 1x1.
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index 04bd2d5..beca138 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -91,7 +91,6 @@
 #include "chromeos/settings/timezone_settings.h"
 #include "chromeos/timezone/timezone_provider.h"
 #include "components/arc/arc_bridge_service.h"
-#include "components/arc/arc_service_manager.h"
 #include "components/crash/content/app/breakpad_linux.h"
 #include "components/pairing/bluetooth_controller_pairing_controller.h"
 #include "components/pairing/bluetooth_host_pairing_controller.h"
@@ -1608,9 +1607,9 @@
 }
 
 void WizardController::StartVoiceInteractionSetupWizard() {
-  arc::ArcVoiceInteractionFrameworkService* service =
-      arc::ArcServiceManager::Get()
-          ->GetService<arc::ArcVoiceInteractionFrameworkService>();
+  auto* service =
+      arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(
+          ProfileManager::GetActiveUserProfile());
   if (service)
     service->StartVoiceInteractionSetupWizard();
 }
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc
index 1fa8b59..8f6d97d0 100644
--- a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc
+++ b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc
@@ -190,7 +190,7 @@
 
 }  // namespace
 
-class DeviceCommandScreenshotTest : public ash::test::AshTestBase {
+class DeviceCommandScreenshotTest : public ash::AshTestBase {
  public:
   void VerifyResults(RemoteCommandJob* job,
                      RemoteCommandJob::Status expected_status,
@@ -199,7 +199,7 @@
  protected:
   DeviceCommandScreenshotTest();
 
-  // ash::test::AshTestBase:
+  // ash::AshTestBase:
   void SetUp() override;
 
   void InitializeScreenshotJob(RemoteCommandJob* job,
@@ -224,7 +224,7 @@
 }
 
 void DeviceCommandScreenshotTest::SetUp() {
-  ash::test::AshTestBase::SetUp();
+  ash::AshTestBase::SetUp();
   test_start_time_ = base::TimeTicks::Now();
 }
 
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_set_volume_job_unittest.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_set_volume_job_unittest.cc
index 4ce4776b..124e1b72 100644
--- a/chrome/browser/chromeos/policy/remote_commands/device_command_set_volume_job_unittest.cc
+++ b/chrome/browser/chromeos/policy/remote_commands/device_command_set_volume_job_unittest.cc
@@ -57,7 +57,7 @@
 
 }  // namespace
 
-class DeviceCommandSetVolumeTest : public ash::test::AshTestBase {
+class DeviceCommandSetVolumeTest : public ash::AshTestBase {
  protected:
   DeviceCommandSetVolumeTest();
 
@@ -74,7 +74,7 @@
 DeviceCommandSetVolumeTest::DeviceCommandSetVolumeTest() {}
 
 void DeviceCommandSetVolumeTest::SetUp() {
-  ash::test::AshTestBase::SetUp();
+  ash::AshTestBase::SetUp();
   test_start_time_ = base::TimeTicks::Now();
 }
 
diff --git a/chrome/browser/chromeos/printing/ppd_provider_factory.cc b/chrome/browser/chromeos/printing/ppd_provider_factory.cc
index 3d85d99..e146369b 100644
--- a/chrome/browser/chromeos/printing/ppd_provider_factory.cc
+++ b/chrome/browser/chromeos/printing/ppd_provider_factory.cc
@@ -15,9 +15,8 @@
 #include "net/url_request/url_request_context_getter.h"
 
 namespace chromeos {
-namespace printing {
 
-scoped_refptr<PpdProvider> CreateProvider(Profile* profile) {
+scoped_refptr<PpdProvider> CreatePpdProvider(Profile* profile) {
   base::FilePath ppd_cache_path =
       profile->GetPath().Append(FILE_PATH_LITERAL("PPDCache"));
 
@@ -26,5 +25,4 @@
                              PpdCache::Create(ppd_cache_path));
 }
 
-}  // namespace printing
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/ppd_provider_factory.h b/chrome/browser/chromeos/printing/ppd_provider_factory.h
index f172147..a63b52b 100644
--- a/chrome/browser/chromeos/printing/ppd_provider_factory.h
+++ b/chrome/browser/chromeos/printing/ppd_provider_factory.h
@@ -10,13 +10,11 @@
 class Profile;
 
 namespace chromeos {
-namespace printing {
 
 class PpdProvider;
 
-scoped_refptr<PpdProvider> CreateProvider(Profile* profile);
+scoped_refptr<PpdProvider> CreatePpdProvider(Profile* profile);
 
-}  // namespace printing
-}  // namsepace chromeos
+}  // namespace chromeos
 
 #endif  // CHROME_BROWSER_CHROMEOS_PRINTING_PPD_PROVIDER_FACTORY_H_
diff --git a/chrome/browser/chromeos/printing/printer_configurer.cc b/chrome/browser/chromeos/printing/printer_configurer.cc
index 7e8a857..158abcdf 100644
--- a/chrome/browser/chromeos/printing/printer_configurer.cc
+++ b/chrome/browser/chromeos/printing/printer_configurer.cc
@@ -4,7 +4,9 @@
 
 #include "chrome/browser/chromeos/printing/printer_configurer.h"
 
+#include <map>
 #include <memory>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -43,7 +45,7 @@
 class PrinterConfigurerImpl : public PrinterConfigurer {
  public:
   explicit PrinterConfigurerImpl(Profile* profile)
-      : ppd_provider_(printing::CreateProvider(profile)), weak_factory_(this) {}
+      : ppd_provider_(CreatePpdProvider(profile)), weak_factory_(this) {}
 
   PrinterConfigurerImpl(const PrinterConfigurerImpl&) = delete;
   PrinterConfigurerImpl& operator=(const PrinterConfigurerImpl&) = delete;
@@ -64,7 +66,7 @@
       return;
     }
 
-    auto* client = chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
+    auto* client = DBusThreadManager::Get()->GetDebugDaemonClient();
 
     client->CupsAddAutoConfiguredPrinter(
         printer.id(), printer.uri(),
@@ -119,7 +121,7 @@
   void AddPrinter(const Printer& printer,
                   const std::string& ppd_contents,
                   const PrinterSetupCallback& cb) {
-    auto* client = chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
+    auto* client = DBusThreadManager::Get()->GetDebugDaemonClient();
 
     client->CupsAddManuallyConfiguredPrinter(
         printer.id(), printer.uri(), ppd_contents,
@@ -179,31 +181,31 @@
 
   void ResolvePpdDone(const Printer& printer,
                       const PrinterSetupCallback& cb,
-                      printing::PpdProvider::CallbackResultCode result,
+                      PpdProvider::CallbackResultCode result,
                       const std::string& ppd_contents,
                       const std::vector<std::string>& ppd_filters) {
     DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
     switch (result) {
-      case chromeos::printing::PpdProvider::SUCCESS:
+      case PpdProvider::SUCCESS:
         DCHECK(!ppd_contents.empty());
         if (!RequiresComponent(printer, cb, ppd_contents, ppd_filters)) {
           AddPrinter(printer, ppd_contents, cb);
         }
         break;
-      case printing::PpdProvider::CallbackResultCode::NOT_FOUND:
+      case PpdProvider::CallbackResultCode::NOT_FOUND:
         cb.Run(PrinterSetupResult::kPpdNotFound);
         break;
-      case printing::PpdProvider::CallbackResultCode::SERVER_ERROR:
+      case PpdProvider::CallbackResultCode::SERVER_ERROR:
         cb.Run(PrinterSetupResult::kPpdUnretrievable);
         break;
-      case printing::PpdProvider::CallbackResultCode::INTERNAL_ERROR:
+      case PpdProvider::CallbackResultCode::INTERNAL_ERROR:
         // TODO(skau): Add kPpdTooLarge when it's reported by the PpdProvider.
         cb.Run(PrinterSetupResult::kFatalError);
         break;
     }
   }
 
-  scoped_refptr<printing::PpdProvider> ppd_provider_;
+  scoped_refptr<PpdProvider> ppd_provider_;
   base::WeakPtrFactory<PrinterConfigurerImpl> weak_factory_;
 };
 
diff --git a/chrome/browser/chromeos/printing/specifics_translation.cc b/chrome/browser/chromeos/printing/specifics_translation.cc
index bbbb300..d1cb623 100644
--- a/chrome/browser/chromeos/printing/specifics_translation.cc
+++ b/chrome/browser/chromeos/printing/specifics_translation.cc
@@ -16,7 +16,6 @@
 #include "components/sync/protocol/printer_specifics.pb.h"
 
 namespace chromeos {
-namespace printing {
 
 namespace {
 
@@ -125,5 +124,4 @@
                             printer.ppd_reference());
 }
 
-}  // namespace printing
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/specifics_translation.h b/chrome/browser/chromeos/printing/specifics_translation.h
index 386b944b..ede9a1707 100644
--- a/chrome/browser/chromeos/printing/specifics_translation.h
+++ b/chrome/browser/chromeos/printing/specifics_translation.h
@@ -11,7 +11,6 @@
 #include "components/sync/protocol/printer_specifics.pb.h"
 
 namespace chromeos {
-namespace printing {
 
 // Convert |printer| into its local representation.  Enforces that only one
 // field in PpdReference is filled in.  In order of preference, we populate
@@ -31,7 +30,6 @@
 void MergePrinterToSpecifics(const Printer& printer,
                              sync_pb::PrinterSpecifics* specifics);
 
-}  // namespace printing
 }  // namespace chromeos
 
 #endif  // CHROME_BROWSER_CHROMEOS_PRINTING_SPECIFICS_TRANSLATION_H_
diff --git a/chrome/browser/chromeos/printing/specifics_translation_unittest.cc b/chrome/browser/chromeos/printing/specifics_translation_unittest.cc
index 94a6bea..e32ca771 100644
--- a/chrome/browser/chromeos/printing/specifics_translation_unittest.cc
+++ b/chrome/browser/chromeos/printing/specifics_translation_unittest.cc
@@ -30,7 +30,6 @@
 }  // namespace
 
 namespace chromeos {
-namespace printing {
 
 TEST(SpecificsTranslationTest, SpecificsToPrinter) {
   sync_pb::PrinterSpecifics specifics;
@@ -223,5 +222,4 @@
   EXPECT_EQ(kMakeAndModel, printer->make_and_model());
 }
 
-}  // namespace printing
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/synced_printers_manager.cc b/chrome/browser/chromeos/printing/synced_printers_manager.cc
index 16e9b9e..5e230fa8 100644
--- a/chrome/browser/chromeos/printing/synced_printers_manager.cc
+++ b/chrome/browser/chromeos/printing/synced_printers_manager.cc
@@ -36,14 +36,14 @@
   base::Optional<sync_pb::PrinterSpecifics> specifics =
       sync_bridge->GetPrinter(id);
   if (!specifics.has_value()) {
-    sync_bridge->AddPrinter(printing::PrinterToSpecifics(printer));
+    sync_bridge->AddPrinter(PrinterToSpecifics(printer));
     return true;
   }
 
   // Preserve fields in the proto which we don't understand.
   std::unique_ptr<sync_pb::PrinterSpecifics> updated_printer =
       base::MakeUnique<sync_pb::PrinterSpecifics>(*specifics);
-  printing::MergePrinterToSpecifics(printer, updated_printer.get());
+  MergePrinterToSpecifics(printer, updated_printer.get());
   sync_bridge->AddPrinter(std::move(updated_printer));
 
   return false;
@@ -80,7 +80,7 @@
   std::vector<sync_pb::PrinterSpecifics> values =
       sync_bridge_->GetAllPrinters();
   for (const auto& value : values) {
-    printers.push_back(printing::SpecificsToPrinter(value));
+    printers.push_back(SpecificsToPrinter(value));
   }
 
   return printers;
@@ -112,7 +112,7 @@
 
   base::Optional<sync_pb::PrinterSpecifics> printer =
       sync_bridge_->GetPrinter(printer_id);
-  return printer.has_value() ? printing::SpecificsToPrinter(*printer) : nullptr;
+  return printer.has_value() ? SpecificsToPrinter(*printer) : nullptr;
 }
 
 void SyncedPrintersManager::RegisterPrinter(std::unique_ptr<Printer> printer) {
@@ -142,7 +142,7 @@
       sync_bridge_->GetPrinter(printer_id);
   bool success = false;
   if (printer.has_value()) {
-    std::unique_ptr<Printer> p = printing::SpecificsToPrinter(*printer);
+    std::unique_ptr<Printer> p = SpecificsToPrinter(*printer);
     success = sync_bridge_->RemovePrinter(p->id());
     if (success) {
       for (Observer& obs : observers_) {
@@ -201,7 +201,7 @@
     // unique so we'll hash the record.  This will not collide with the UUIDs
     // generated for user entries.
     std::string id = base::MD5String(printer_json);
-    printer_dictionary->SetString(printing::kPrinterId, id);
+    printer_dictionary->SetString(kPrinterId, id);
 
     if (base::ContainsKey(new_printers, id)) {
       // Skip duplicated entries.
@@ -216,7 +216,7 @@
       new_printers[id] = std::move(old->second);
     } else {
       auto printer =
-          printing::RecommendedPrinterToPrinter(*printer_dictionary, timestamp);
+          RecommendedPrinterToPrinter(*printer_dictionary, timestamp);
       printer->set_source(Printer::SRC_POLICY);
 
       new_printers[id] = std::move(printer);
diff --git a/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc b/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc
index 39e7c880..949ee39e 100644
--- a/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc
+++ b/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc
@@ -27,8 +27,8 @@
 
 namespace {
 
-const char kPrinterId[] = "UUID-UUID-UUID-PRINTER";
-const char kUri[] = "ipps://printer.chromium.org/ipp/print";
+const char kTestPrinterId[] = "UUID-UUID-UUID-PRINTER";
+const char kTestUri[] = "ipps://printer.chromium.org/ipp/print";
 
 const char kLexJson[] = R"json({
         "display_name": "LexaPrint",
@@ -109,11 +109,11 @@
 TEST_F(SyncedPrintersManagerTest, AddPrinter) {
   LoggingObserver observer;
   manager_.AddObserver(&observer);
-  manager_.RegisterPrinter(base::MakeUnique<Printer>(kPrinterId));
+  manager_.RegisterPrinter(base::MakeUnique<Printer>(kTestPrinterId));
 
   auto printers = manager_.GetPrinters();
   ASSERT_EQ(1U, printers.size());
-  EXPECT_EQ(kPrinterId, printers[0]->id());
+  EXPECT_EQ(kTestPrinterId, printers[0]->id());
   EXPECT_EQ(Printer::Source::SRC_USER_PREFS, printers[0]->source());
 
   EXPECT_TRUE(observer.AddCalled());
@@ -129,9 +129,9 @@
 }
 
 TEST_F(SyncedPrintersManagerTest, UpdatePrinter) {
-  manager_.RegisterPrinter(base::MakeUnique<Printer>(kPrinterId));
-  auto updated_printer = base::MakeUnique<Printer>(kPrinterId);
-  updated_printer->set_uri(kUri);
+  manager_.RegisterPrinter(base::MakeUnique<Printer>(kTestPrinterId));
+  auto updated_printer = base::MakeUnique<Printer>(kTestPrinterId);
+  updated_printer->set_uri(kTestUri);
 
   // Register observer so it only receives the update event.
   LoggingObserver observer;
@@ -141,7 +141,7 @@
 
   auto printers = manager_.GetPrinters();
   ASSERT_EQ(1U, printers.size());
-  EXPECT_EQ(kUri, printers[0]->uri());
+  EXPECT_EQ(kTestUri, printers[0]->uri());
 
   EXPECT_TRUE(observer.UpdateCalled());
   EXPECT_FALSE(observer.AddCalled());
@@ -149,15 +149,15 @@
 
 TEST_F(SyncedPrintersManagerTest, RemovePrinter) {
   manager_.RegisterPrinter(base::MakeUnique<Printer>("OtherUUID"));
-  manager_.RegisterPrinter(base::MakeUnique<Printer>(kPrinterId));
+  manager_.RegisterPrinter(base::MakeUnique<Printer>(kTestPrinterId));
   manager_.RegisterPrinter(base::MakeUnique<Printer>());
 
-  manager_.RemovePrinter(kPrinterId);
+  manager_.RemovePrinter(kTestPrinterId);
 
   auto printers = manager_.GetPrinters();
   ASSERT_EQ(2U, printers.size());
-  EXPECT_NE(kPrinterId, printers.at(0)->id());
-  EXPECT_NE(kPrinterId, printers.at(1)->id());
+  EXPECT_NE(kTestPrinterId, printers.at(0)->id());
+  EXPECT_NE(kTestPrinterId, printers.at(1)->id());
 }
 
 // Tests for policy printers
@@ -216,21 +216,21 @@
 }
 
 TEST_F(SyncedPrintersManagerTest, PrinterNotInstalled) {
-  Printer printer(kPrinterId, base::Time::FromInternalValue(1000));
+  Printer printer(kTestPrinterId, base::Time::FromInternalValue(1000));
   EXPECT_FALSE(manager_.IsConfigurationCurrent(printer));
 }
 
 TEST_F(SyncedPrintersManagerTest, PrinterIsInstalled) {
-  Printer printer(kPrinterId, base::Time::FromInternalValue(1000));
+  Printer printer(kTestPrinterId, base::Time::FromInternalValue(1000));
   manager_.PrinterInstalled(printer);
   EXPECT_TRUE(manager_.IsConfigurationCurrent(printer));
 }
 
 TEST_F(SyncedPrintersManagerTest, UpdatedPrinterConfiguration) {
-  Printer printer(kPrinterId, base::Time::FromInternalValue(1000));
+  Printer printer(kTestPrinterId, base::Time::FromInternalValue(1000));
   manager_.PrinterInstalled(printer);
 
-  Printer updated_printer(kPrinterId, base::Time::FromInternalValue(2000));
+  Printer updated_printer(kTestPrinterId, base::Time::FromInternalValue(2000));
   EXPECT_FALSE(manager_.IsConfigurationCurrent(updated_printer));
 }
 
diff --git a/chrome/browser/chromeos/printing/usb_printer_detector.cc b/chrome/browser/chromeos/printing/usb_printer_detector.cc
index 60723d7..ed444e15 100644
--- a/chrome/browser/chromeos/printing/usb_printer_detector.cc
+++ b/chrome/browser/chromeos/printing/usb_printer_detector.cc
@@ -37,8 +37,6 @@
 namespace chromeos {
 namespace {
 
-using printing::PpdProvider;
-
 // Aggregates the information needed for printer setup so it's easier to pass it
 // around.
 struct SetUpPrinterData {
@@ -211,8 +209,7 @@
     data->is_new = true;
 
     // Look for an exact match based on USB ids.
-    scoped_refptr<PpdProvider> ppd_provider =
-        printing::CreateProvider(profile_);
+    scoped_refptr<PpdProvider> ppd_provider = CreatePpdProvider(profile_);
     ppd_provider->ResolveUsbIds(
         device->vendor_id(), device->product_id(),
         base::Bind(&UsbPrinterDetectorImpl::ResolveUsbIdsDone,
diff --git a/chrome/browser/chromeos/profiles/profile_helper.h b/chrome/browser/chromeos/profiles/profile_helper.h
index bb0eb05..4c66225 100644
--- a/chrome/browser/chromeos/profiles/profile_helper.h
+++ b/chrome/browser/chromeos/profiles/profile_helper.h
@@ -36,9 +36,7 @@
 }
 
 namespace ash {
-namespace test {
 class MultiUserWindowManagerChromeOSTest;
-}  // namespace test
 }  // namespace ash
 
 namespace policy {
@@ -190,7 +188,7 @@
   friend class ProfileHelperTest;
   friend class ProfileListChromeOSTest;
   friend class SystemTrayDelegateChromeOSTest;
-  friend class ash::test::MultiUserWindowManagerChromeOSTest;
+  friend class ash::MultiUserWindowManagerChromeOSTest;
   friend class arc::ArcSessionManagerTest;
   friend class arc::ArcAuthServiceTest;
   friend class ::ArcAppTest;
diff --git a/chrome/browser/chromeos/ui/accessibility_focus_ring_controller_unittest.cc b/chrome/browser/chromeos/ui/accessibility_focus_ring_controller_unittest.cc
index 0c99cfc..97a2ed8 100644
--- a/chrome/browser/chromeos/ui/accessibility_focus_ring_controller_unittest.cc
+++ b/chrome/browser/chromeos/ui/accessibility_focus_ring_controller_unittest.cc
@@ -35,7 +35,7 @@
   int margin_;
 };
 
-class AccessibilityFocusRingControllerTest : public ash::test::AshTestBase {
+class AccessibilityFocusRingControllerTest : public ash::AshTestBase {
  public:
   AccessibilityFocusRingControllerTest() {}
   ~AccessibilityFocusRingControllerTest() override {}
diff --git a/chrome/browser/engagement/site_engagement_score.cc b/chrome/browser/engagement/site_engagement_score.cc
index cfedbf3..d9798ec 100644
--- a/chrome/browser/engagement/site_engagement_score.cc
+++ b/chrome/browser/engagement/site_engagement_score.cc
@@ -58,10 +58,10 @@
 
 const double SiteEngagementScore::kMaxPoints = 100;
 
-const char* SiteEngagementScore::kRawScoreKey = "rawScore";
-const char* SiteEngagementScore::kPointsAddedTodayKey = "pointsAddedToday";
-const char* SiteEngagementScore::kLastEngagementTimeKey = "lastEngagementTime";
-const char* SiteEngagementScore::kLastShortcutLaunchTimeKey =
+const char SiteEngagementScore::kRawScoreKey[] = "rawScore";
+const char SiteEngagementScore::kPointsAddedTodayKey[] = "pointsAddedToday";
+const char SiteEngagementScore::kLastEngagementTimeKey[] = "lastEngagementTime";
+const char SiteEngagementScore::kLastShortcutLaunchTimeKey[] =
     "lastShortcutLaunchTime";
 
 // static
diff --git a/chrome/browser/engagement/site_engagement_score.h b/chrome/browser/engagement/site_engagement_score.h
index 517520a..4d31986 100644
--- a/chrome/browser/engagement/site_engagement_score.h
+++ b/chrome/browser/engagement/site_engagement_score.h
@@ -192,10 +192,10 @@
   static ParamValues BuildParamValues();
 
   // Keys used in the content settings dictionary.
-  static const char* kRawScoreKey;
-  static const char* kPointsAddedTodayKey;
-  static const char* kLastEngagementTimeKey;
-  static const char* kLastShortcutLaunchTimeKey;
+  static const char kRawScoreKey[];
+  static const char kPointsAddedTodayKey[];
+  static const char kLastEngagementTimeKey[];
+  static const char kLastShortcutLaunchTimeKey[];
 
   // This version of the constructor is used in unit tests.
   SiteEngagementScore(base::Clock* clock,
diff --git a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
index e5dfc460..0c166c9 100644
--- a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
@@ -109,8 +109,8 @@
           base::CreateSingleThreadTaskRunnerWithTraits(
               {base::MayBlock(), base::TaskPriority::BACKGROUND}));
   std::unique_ptr<remoting::PolicyWatcher> policy_watcher =
-      remoting::PolicyWatcher::Create(g_browser_process->policy_service(),
-                                      context->file_task_runner());
+      remoting::PolicyWatcher::CreateWithPolicyService(
+          g_browser_process->policy_service());
   std::unique_ptr<NativeMessageHost> host(
       new remoting::It2MeNativeMessagingHost(
           /*needs_elevation=*/false, std::move(policy_watcher),
diff --git a/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc b/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
index f4998a6..16ae823 100644
--- a/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
+++ b/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
@@ -37,7 +37,7 @@
       ->EnableMaximizeModeWindowManager(enable);
 }
 
-class DisplayInfoProviderChromeosTest : public ash::test::AshTestBase {
+class DisplayInfoProviderChromeosTest : public ash::AshTestBase {
  public:
   DisplayInfoProviderChromeosTest() {}
 
@@ -46,7 +46,7 @@
   void SetUp() override {
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kUseFirstDisplayAsInternal);
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
   }
 
  protected:
@@ -1049,7 +1049,7 @@
   EXPECT_FALSE(screen_orientation_controller->rotation_locked());
 
   // ScreenOrientationController rotations override display info.
-  ash::test::ScreenOrientationControllerTestApi test_api(
+  ash::ScreenOrientationControllerTestApi test_api(
       screen_orientation_controller);
   test_api.SetDisplayRotation(display::Display::ROTATE_0,
                               display::Display::ROTATION_SOURCE_ACTIVE);
diff --git a/chrome/browser/extensions/extension_sync_service.cc b/chrome/browser/extensions/extension_sync_service.cc
index bc9add5..fd538cb 100644
--- a/chrome/browser/extensions/extension_sync_service.cc
+++ b/chrome/browser/extensions/extension_sync_service.cc
@@ -507,8 +507,11 @@
           profile_, id, extension_sync_data.launch_type());
     }
 
-    if (!extension_sync_data.bookmark_app_url().empty())
+    if (!extension_sync_data.bookmark_app_url().empty()) {
+      // Handles creating and updating the bookmark app.
       ApplyBookmarkAppSyncData(extension_sync_data);
+      return;
+    }
   }
 
   // Finally, trigger installation/update as required.
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index be6e9b6..523319e 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -308,7 +308,6 @@
       globals_(nullptr),
       is_quic_allowed_by_policy_(true),
       http_09_on_non_default_ports_enabled_(false),
-      creation_time_(base::TimeTicks::Now()),
       weak_factory_(this) {
   scoped_refptr<base::SingleThreadTaskRunner> io_thread_proxy =
       BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
@@ -750,10 +749,6 @@
         ->DisableQuic();
 }
 
-base::TimeTicks IOThread::creation_time() const {
-  return creation_time_;
-}
-
 net::SSLConfigService* IOThread::GetSSLConfigService() {
   return ssl_config_service_manager_->Get();
 }
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index 593491b..537d5fe1 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -20,7 +20,6 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string_piece.h"
-#include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/browser/net/chrome_network_delegate.h"
 #include "chrome/browser/net/system_network_context_manager.h"
@@ -210,8 +209,6 @@
   // supported for simplicity and requires a browser restart.
   void DisableQuic();
 
-  base::TimeTicks creation_time() const;
-
   // Returns the callback for updating data use prefs.
   metrics::UpdateUsagePrefCallbackType GetMetricsDataUseForwarder();
 
@@ -357,8 +354,6 @@
   // True if HTTP/0.9 is allowed on non-default ports by policy.
   bool http_09_on_non_default_ports_enabled_;
 
-  const base::TimeTicks creation_time_;
-
   base::WeakPtrFactory<IOThread> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(IOThread);
diff --git a/chrome/browser/media/media_engagement_contents_observer_unittest.cc b/chrome/browser/media/media_engagement_contents_observer_unittest.cc
index c3926cd..dabe98a 100644
--- a/chrome/browser/media/media_engagement_contents_observer_unittest.cc
+++ b/chrome/browser/media/media_engagement_contents_observer_unittest.cc
@@ -118,20 +118,18 @@
     EXPECT_EQ(contents_observer_->service_->GetScoreMapForTesting()[url],
               expected_score);
 
-    MediaEngagementScore* score =
+    MediaEngagementScore score =
         contents_observer_->service_->CreateEngagementScore(url);
-    EXPECT_EQ(score->visits(), expected_visits);
-    EXPECT_EQ(score->media_playbacks(), expected_media_playbacks);
-    delete score;
+    EXPECT_EQ(expected_visits, score.visits());
+    EXPECT_EQ(expected_media_playbacks, score.media_playbacks());
   }
 
   void SetScores(GURL url, int visits, int media_playbacks) {
-    MediaEngagementScore* score =
+    MediaEngagementScore score =
         contents_observer_->service_->CreateEngagementScore(url);
-    score->SetVisits(visits);
-    score->SetMediaPlaybacks(media_playbacks);
-    score->Commit();
-    delete score;
+    score.SetVisits(visits);
+    score.SetMediaPlaybacks(media_playbacks);
+    score.Commit();
   }
 
   void Navigate(GURL url) {
diff --git a/chrome/browser/media/media_engagement_score.cc b/chrome/browser/media/media_engagement_score.cc
index 6f0b147e..fa095a6 100644
--- a/chrome/browser/media/media_engagement_score.cc
+++ b/chrome/browser/media/media_engagement_score.cc
@@ -9,9 +9,9 @@
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 
-const char* MediaEngagementScore::kVisitsKey = "visits";
-const char* MediaEngagementScore::kMediaPlaybacksKey = "mediaPlaybacks";
-const char* MediaEngagementScore::kLastMediaPlaybackTimeKey =
+const char MediaEngagementScore::kVisitsKey[] = "visits";
+const char MediaEngagementScore::kMediaPlaybacksKey[] = "mediaPlaybacks";
+const char MediaEngagementScore::kLastMediaPlaybackTimeKey[] =
     "lastMediaPlaybackTime";
 
 const int MediaEngagementScore::kScoreMinVisits = 5;
@@ -70,6 +70,10 @@
 
 MediaEngagementScore::~MediaEngagementScore() = default;
 
+MediaEngagementScore::MediaEngagementScore(MediaEngagementScore&&) = default;
+MediaEngagementScore& MediaEngagementScore::operator=(MediaEngagementScore&&) =
+    default;
+
 double MediaEngagementScore::GetTotalScore() const {
   if (visits() < kScoreMinVisits)
     return 0;
diff --git a/chrome/browser/media/media_engagement_score.h b/chrome/browser/media/media_engagement_score.h
index 73d76f1..0735e4fb 100644
--- a/chrome/browser/media/media_engagement_score.h
+++ b/chrome/browser/media/media_engagement_score.h
@@ -23,9 +23,9 @@
   // will store the number of media playbacks on an origin.
   // kLastMediaPlaybackTimeKey will store the timestamp of the last
   // media playback on an origin.
-  static const char* kVisitsKey;
-  static const char* kMediaPlaybacksKey;
-  static const char* kLastMediaPlaybackTimeKey;
+  static const char kVisitsKey[];
+  static const char kMediaPlaybacksKey[];
+  static const char kLastMediaPlaybackTimeKey[];
 
   // Origins with a number of visits less than this number will recieve
   // a score of zero.
@@ -36,6 +36,9 @@
                        HostContentSettingsMap* settings);
   ~MediaEngagementScore();
 
+  MediaEngagementScore(MediaEngagementScore&&);
+  MediaEngagementScore& operator=(MediaEngagementScore&&);
+
   // Returns the total score, as per the formula.
   double GetTotalScore() const;
 
diff --git a/chrome/browser/media/media_engagement_service.cc b/chrome/browser/media/media_engagement_service.cc
index a15ccd26..c669cd16 100644
--- a/chrome/browser/media/media_engagement_service.cc
+++ b/chrome/browser/media/media_engagement_service.cc
@@ -54,15 +54,14 @@
     const ContentSettingsPattern& secondary_pattern) {
   GURL url(primary_pattern.ToString());
   DCHECK(url.is_valid());
-  MediaEngagementScore* score = service->CreateEngagementScore(url);
-  base::Time playback_time = score->last_media_playback_time();
-  delete score;
+  MediaEngagementScore score = service->CreateEngagementScore(url);
+  base::Time playback_time = score.last_media_playback_time();
   return playback_time >= delete_begin && playback_time <= delete_end;
 }
 
 }  // namespace
 
-const char* MediaEngagementService::kHistogramScoreAtStartupName =
+const char MediaEngagementService::kHistogramScoreAtStartupName[] =
     "Media.Engagement.ScoreAtStartup";
 
 // static
@@ -155,22 +154,20 @@
   for (auto const& kv : origins) {
     // Remove the number of visits consistent with the number
     // of URLs from the same origin we are removing.
-    MediaEngagementScore* score = CreateEngagementScore(kv.first);
-    double original_score = score->GetTotalScore();
-    score->SetVisits(score->visits() - kv.second);
+    MediaEngagementScore score = CreateEngagementScore(kv.first);
+    double original_score = score.GetTotalScore();
+    score.SetVisits(score.visits() - kv.second);
 
     // If this results in zero visits then clear the score.
-    if (score->visits() <= 0) {
+    if (score.visits() <= 0) {
       Clear(kv.first);
-      delete score;
       continue;
     }
 
     // Otherwise, recalculate the playbacks to keep the
     // MEI score consistent.
-    score->SetMediaPlaybacks(original_score * score->visits());
-    score->Commit();
-    delete score;
+    score.SetMediaPlaybacks(original_score * score.visits());
+    score.Commit();
   }
 }
 
@@ -182,10 +179,7 @@
 }
 
 double MediaEngagementService::GetEngagementScore(const GURL& url) const {
-  MediaEngagementScore* score = CreateEngagementScore(url);
-  double total_score = score->GetTotalScore();
-  delete score;
-  return total_score;
+  return CreateEngagementScore(url).GetTotalScore();
 }
 
 std::map<GURL, double> MediaEngagementService::GetScoreMapForTesting() const {
@@ -202,10 +196,9 @@
   if (!ShouldRecordEngagement(url))
     return;
 
-  MediaEngagementScore* score = CreateEngagementScore(url);
-  score->IncrementVisits();
-  score->Commit();
-  delete score;
+  MediaEngagementScore score = CreateEngagementScore(url);
+  score.IncrementVisits();
+  score.Commit();
 }
 
 std::vector<media::mojom::MediaEngagementScoreDetails>
@@ -215,11 +208,11 @@
   std::vector<media::mojom::MediaEngagementScoreDetails> details;
   details.reserve(origins.size());
   for (const GURL& origin : origins) {
+    // TODO(beccahughes): Why would an origin not be valid here?
     if (!origin.is_valid())
       continue;
-    MediaEngagementScore* score = CreateEngagementScore(origin);
-    details.push_back(score->GetScoreDetails());
-    delete score;
+    MediaEngagementScore score = CreateEngagementScore(origin);
+    details.push_back(score.GetScoreDetails());
   }
 
   return details;
@@ -229,18 +222,17 @@
   if (!ShouldRecordEngagement(url))
     return;
 
-  MediaEngagementScore* score = CreateEngagementScore(url);
-  score->IncrementMediaPlaybacks();
-  score->Commit();
-  delete score;
+  MediaEngagementScore score = CreateEngagementScore(url);
+  score.IncrementMediaPlaybacks();
+  score.Commit();
 }
 
-MediaEngagementScore* MediaEngagementService::CreateEngagementScore(
+MediaEngagementScore MediaEngagementService::CreateEngagementScore(
     const GURL& url) const {
   // If we are in incognito, |settings| will automatically have the data from
   // the original profile migrated in, so all engagement scores in incognito
   // will be initialised to the values from the original profile.
-  return new MediaEngagementScore(
+  return MediaEngagementScore(
       clock_.get(), url,
       HostContentSettingsMapFactory::GetForProfile(profile_));
 }
diff --git a/chrome/browser/media/media_engagement_service.h b/chrome/browser/media/media_engagement_service.h
index e31dac7..df0f638 100644
--- a/chrome/browser/media/media_engagement_service.h
+++ b/chrome/browser/media/media_engagement_service.h
@@ -80,10 +80,10 @@
                             const base::Time& delete_end);
 
   // Retrieves the MediaEngagementScore for |url|.
-  MediaEngagementScore* CreateEngagementScore(const GURL& url) const;
+  MediaEngagementScore CreateEngagementScore(const GURL& url) const;
 
   // The name of the histogram that scores are logged to on startup.
-  static const char* kHistogramScoreAtStartupName;
+  static const char kHistogramScoreAtStartupName[];
 
  private:
   friend class MediaEngagementServiceTest;
diff --git a/chrome/browser/media/media_engagement_service_unittest.cc b/chrome/browser/media/media_engagement_service_unittest.cc
index 0c7be08..4e17a9b 100644
--- a/chrome/browser/media/media_engagement_service_unittest.cc
+++ b/chrome/browser/media/media_engagement_service_unittest.cc
@@ -148,12 +148,11 @@
     EXPECT_EQ(service->GetEngagementScore(url), expected_score);
     EXPECT_EQ(service->GetScoreMapForTesting()[url], expected_score);
 
-    MediaEngagementScore* score = service->CreateEngagementScore(url);
-    EXPECT_EQ(score->visits(), expected_visits);
-    EXPECT_EQ(score->media_playbacks(), expected_media_playbacks);
-    EXPECT_EQ(score->last_media_playback_time(),
-              expected_last_media_playback_time);
-    delete score;
+    MediaEngagementScore score = service->CreateEngagementScore(url);
+    EXPECT_EQ(expected_visits, score.visits());
+    EXPECT_EQ(expected_media_playbacks, score.media_playbacks());
+    EXPECT_EQ(expected_last_media_playback_time,
+              score.last_media_playback_time());
   }
 
   void ExpectScores(GURL url,
@@ -166,26 +165,21 @@
   }
 
   void SetScores(GURL url, int visits, int media_playbacks) {
-    MediaEngagementScore* score = service_->CreateEngagementScore(url);
-    score->SetVisits(visits);
-    score->SetMediaPlaybacks(media_playbacks);
-    score->Commit();
-    delete score;
+    MediaEngagementScore score = service_->CreateEngagementScore(url);
+    score.SetVisits(visits);
+    score.SetMediaPlaybacks(media_playbacks);
+    score.Commit();
   }
 
   void SetLastMediaPlaybackTime(const GURL& url,
                                 base::Time last_media_playback_time) {
-    MediaEngagementScore* score = service_->CreateEngagementScore(url);
-    score->last_media_playback_time_ = last_media_playback_time;
-    score->Commit();
-    delete score;
+    MediaEngagementScore score = service_->CreateEngagementScore(url);
+    score.last_media_playback_time_ = last_media_playback_time;
+    score.Commit();
   }
 
   double GetTotalScore(GURL url) {
-    MediaEngagementScore* score = service_->CreateEngagementScore(url);
-    double total_score = score->GetTotalScore();
-    delete score;
-    return total_score;
+    return service_->CreateEngagementScore(url).GetTotalScore();
   }
 
   std::map<GURL, double> GetScoreMapForTesting() const {
diff --git a/chrome/browser/media/router/discovery/BUILD.gn b/chrome/browser/media/router/discovery/BUILD.gn
index a36fbb8..22de6209 100644
--- a/chrome/browser/media/router/discovery/BUILD.gn
+++ b/chrome/browser/media/router/discovery/BUILD.gn
@@ -64,11 +64,6 @@
     ]
   }
 
-  if (is_win) {
-    libs = [ "wlanapi.lib" ]
-    ldflags = [ "/DELAYLOAD:wlanapi.dll" ]
-  }
-
   if (is_mac) {
     libs = [ "CoreWLAN.framework" ]
   }
diff --git a/chrome/browser/media/router/discovery/discovery_network_list_win.cc b/chrome/browser/media/router/discovery/discovery_network_list_win.cc
index 9c3f96a..a18dd90 100644
--- a/chrome/browser/media/router/discovery/discovery_network_list_win.cc
+++ b/chrome/browser/media/router/discovery/discovery_network_list_win.cc
@@ -4,242 +4,7 @@
 
 #include "chrome/browser/media/router/discovery/discovery_network_list.h"
 
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#include <iphlpapi.h>  // NOLINT
-
-#include <windot11.h>  // NOLINT
-#include <wlanapi.h>   // NOLINT
-
-#include <algorithm>
-#include <cstring>
-#include <map>
-#include <utility>
-#include <vector>
-
-#include "base/containers/small_map.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_number_conversions.h"
-
-namespace {
-
-struct GuidOperatorLess {
-  bool operator()(const GUID& guid1, const GUID& guid2) const {
-    return memcmp(&guid1, &guid2, sizeof(GUID)) < 0;
-  }
-};
-
-void IfTable2Deleter(PMIB_IF_TABLE2 interface_table) {
-  if (interface_table) {
-    FreeMibTable(interface_table);
-  }
-}
-
-void WlanApiDeleter(void* p) {
-  if (p) {
-    WlanFreeMemory(p);
-  }
-}
-
-class ScopedWlanClientHandle {
- public:
-  ScopedWlanClientHandle() {}
-  ~ScopedWlanClientHandle() {
-    if (handle != nullptr) {
-      WlanCloseHandle(handle, nullptr);
-    }
-  }
-
-  HANDLE handle = nullptr;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ScopedWlanClientHandle);
-};
-
-// Returns a map from a network interface's GUID to its MAC address.  This
-// enumerates all network interfaces, not just wireless interfaces.
-base::small_map<std::map<GUID, std::string, GuidOperatorLess>>
-GetInterfaceGuidMacMap() {
-  PMIB_IF_TABLE2 interface_table_raw = nullptr;
-  auto result = GetIfTable2(&interface_table_raw);
-  if (result != ERROR_SUCCESS) {
-    LOG(WARNING) << "GetIfTable2() failed: " << result;
-    return {};
-  }
-  std::unique_ptr<MIB_IF_TABLE2, decltype(&IfTable2Deleter)> interface_table(
-      interface_table_raw, IfTable2Deleter);
-
-  base::small_map<std::map<GUID, std::string, GuidOperatorLess>> guid_mac_map;
-  for (ULONG i = 0; i < interface_table->NumEntries; ++i) {
-    const auto* interface_row = &interface_table->Table[i];
-    guid_mac_map.emplace(interface_row->InterfaceGuid,
-                         std::string{reinterpret_cast<const char*>(
-                                         interface_row->PhysicalAddress),
-                                     interface_row->PhysicalAddressLength});
-  }
-
-  return guid_mac_map;
-}
-
-// Returns the associated SSID of an interface identified by its interface GUID.
-// If it is not a wireless interface or if it's not currently associated with a
-// network, it returns an empty string.
-std::string GetSsidForInterfaceGuid(const HANDLE wlan_client_handle,
-                                    const GUID& interface_guid) {
-  WLAN_CONNECTION_ATTRIBUTES* connection_info_raw = nullptr;
-  DWORD connection_info_size = 0;
-  auto result = WlanQueryInterface(
-      wlan_client_handle, &interface_guid, wlan_intf_opcode_current_connection,
-      nullptr, &connection_info_size,
-      reinterpret_cast<void**>(&connection_info_raw), nullptr);
-  if (result != ERROR_SUCCESS) {
-    // We can't get the SSID for this interface so its network ID will
-    // fall back to its MAC address below.
-    DVLOG(2) << "Failed to get wireless connection info: " << result;
-    return {};
-  }
-  std::unique_ptr<WLAN_CONNECTION_ATTRIBUTES, decltype(&WlanApiDeleter)>
-      connection_info(connection_info_raw, WlanApiDeleter);
-  if (connection_info->isState != wlan_interface_state_connected) {
-    return {};
-  }
-  const auto* ssid = &connection_info->wlanAssociationAttributes.dot11Ssid;
-  return std::string(reinterpret_cast<const char*>(ssid->ucSSID),
-                     ssid->uSSIDLength);
-}
-
-// Returns a map from a network adapter's MAC address to its currently
-// associated WiFi SSID.
-base::small_map<std::map<std::string, std::string>> GetMacSsidMap() {
-  ScopedWlanClientHandle wlan_client_handle;
-  constexpr DWORD kWlanClientVersion = 2;
-  DWORD wlan_current_version = 0;
-
-  auto result =
-      WlanOpenHandle(kWlanClientVersion, nullptr, &wlan_current_version,
-                     &wlan_client_handle.handle);
-  if (result != ERROR_SUCCESS) {
-    LOG(WARNING) << "Failed to open Wlan client handle: " << result;
-    return {};
-  }
-
-  PWLAN_INTERFACE_INFO_LIST wlan_interface_list_raw = nullptr;
-  result = WlanEnumInterfaces(wlan_client_handle.handle, nullptr,
-                              &wlan_interface_list_raw);
-  if (result != ERROR_SUCCESS) {
-    LOG(WARNING) << "Failed to enumerate wireless interfaces: " << result;
-    return {};
-  }
-
-  std::unique_ptr<WLAN_INTERFACE_INFO_LIST, decltype(&WlanApiDeleter)>
-      wlan_interface_list(wlan_interface_list_raw, WlanApiDeleter);
-  auto guid_mac_map = GetInterfaceGuidMacMap();
-  base::small_map<std::map<std::string, std::string>> mac_ssid_map;
-
-  // This loop takes each wireless interface and maps its MAC address to its
-  // associated SSID, if it has one.  Each wireless interface has an interface
-  // GUID which we can use to get its MAC address via |guid_mac_map| and its
-  // associated SSID via WlanQueryInterface.
-  for (DWORD i = 0; i < wlan_interface_list->dwNumberOfItems; ++i) {
-    const auto* interface_info = &wlan_interface_list->InterfaceInfo[i];
-    const auto mac_entry = guid_mac_map.find(interface_info->InterfaceGuid);
-    if (mac_entry == guid_mac_map.end()) {
-      continue;
-    }
-    auto ssid = GetSsidForInterfaceGuid(wlan_client_handle.handle,
-                                        interface_info->InterfaceGuid);
-    if (ssid.empty()) {
-      continue;
-    }
-    mac_ssid_map.emplace(mac_entry->second, std::move(ssid));
-  }
-  return mac_ssid_map;
-}
-
-}  // namespace
-
+// TODO(btolsch): Implement this for Windows.
 std::vector<DiscoveryNetworkInfo> GetDiscoveryNetworkInfoList() {
-  // Max number of times to retry GetAdaptersAddresses due to
-  // ERROR_BUFFER_OVERFLOW. If GetAdaptersAddresses returns this indefinitely
-  // due to an unforeseen reason, we don't want to be stuck in an endless loop.
-  constexpr int kMaxGetAdaptersAddressTries = 10;
-
-  // Use an initial buffer size of 15KB, as recommended by MSDN. See:
-  // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx
-  constexpr int kInitialAddressBufferSize = 15000;
-
-  constexpr ULONG kAddressFlags =
-      GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
-      GAA_FLAG_SKIP_DNS_SERVER;
-
-  // Although we need to provide GetAdaptersAddresses with a buffer, there's no
-  // way to know what size to use.  We use a best-guess here but when
-  // GetAdaptersAddresses returns ERROR_BUFFER_OVERFLOW, it means our guess was
-  // too small.  When this happens it will also reset |addresses_buffer_size| to
-  // the required size.  Although it's very unlikely that two successive calls
-  // will both require increasing the buffer size, there's no guarantee that
-  // this won't happen; this is what the maximum retry count guards against.
-  ULONG addresses_buffer_size = kInitialAddressBufferSize;
-  std::unique_ptr<char[]> addresses_buffer;
-  PIP_ADAPTER_ADDRESSES adapter_addresses = nullptr;
-  ULONG result = ERROR_BUFFER_OVERFLOW;
-  for (int i = 0;
-       result == ERROR_BUFFER_OVERFLOW && i < kMaxGetAdaptersAddressTries;
-       ++i) {
-    addresses_buffer.reset(new char[addresses_buffer_size]);
-    adapter_addresses =
-        reinterpret_cast<PIP_ADAPTER_ADDRESSES>(addresses_buffer.get());
-    result = GetAdaptersAddresses(AF_UNSPEC, kAddressFlags, nullptr,
-                                  adapter_addresses, &addresses_buffer_size);
-  }
-
-  if (result != NO_ERROR) {
-    return {};
-  }
-
-  std::vector<DiscoveryNetworkInfo> network_ids;
-  auto mac_ssid_map = GetMacSsidMap();
-  for (const IP_ADAPTER_ADDRESSES* current_adapter = adapter_addresses;
-       current_adapter != nullptr; current_adapter = current_adapter->Next) {
-    // We only want adapters which are up and either Ethernet or wireless, so we
-    // skip everything else here.
-    if (current_adapter->OperStatus != IfOperStatusUp ||
-        (current_adapter->IfType != IF_TYPE_ETHERNET_CSMACD &&
-         current_adapter->IfType != IF_TYPE_IEEE80211)) {
-      continue;
-    }
-
-    // We have to use a slightly roundabout way to get the SSID for each
-    // adapter:
-    // - Enumerate wifi devices to get list of interface GUIDs.
-    // - Enumerate interfaces to get interface GUID -> physical address map.
-    // - Map interface GUIDs to SSID.
-    // - Use GUID -> MAC map to do MAC -> interface GUID  -> SSID.
-    // Although it's theoretically possible to have multiple interfaces per
-    // adapter, most wireless cards don't actually allow multiple
-    // managed-mode interfaces.  However, in the event that there really
-    // are multiple interfaces per adapter (i.e. physical address), we will
-    // simply use the SSID of the first match.  It's unclear how Windows would
-    // handle this case since it's somewhat loose with its use of the words
-    // "adapter" and "interface".
-    std::string name(current_adapter->AdapterName);
-    if (current_adapter->IfType == IF_TYPE_IEEE80211) {
-      std::string adapter_mac(
-          reinterpret_cast<const char*>(current_adapter->PhysicalAddress),
-          current_adapter->PhysicalAddressLength);
-      const auto ssid_entry = mac_ssid_map.find(adapter_mac);
-      if (ssid_entry != mac_ssid_map.end()) {
-        network_ids.emplace_back(name, ssid_entry->second);
-        continue;
-      }
-    }
-    network_ids.emplace_back(
-        name, base::HexEncode(current_adapter->PhysicalAddress,
-                              current_adapter->PhysicalAddressLength));
-  }
-
-  StableSortDiscoveryNetworkInfo(network_ids.begin(), network_ids.end());
-
-  return network_ids;
+  return std::vector<DiscoveryNetworkInfo>();
 }
diff --git a/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc b/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc
index b5b0956c..af66a267 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc
@@ -33,7 +33,7 @@
                void(DesktopMediaList* list, int index));
 };
 
-class DesktopMediaListAshTest : public ash::test::AshTestBase {
+class DesktopMediaListAshTest : public ash::AshTestBase {
  public:
   DesktopMediaListAshTest() {}
   ~DesktopMediaListAshTest() override {}
@@ -41,7 +41,7 @@
   void TearDown() override {
     // Reset the unique_ptr so the list stops refreshing.
     list_.reset();
-    ash::test::AshTestBase::TearDown();
+    ash::AshTestBase::TearDown();
   }
 
   void CreateList(content::DesktopMediaID::Type type) {
diff --git a/chrome/browser/notifications/login_state_notification_blocker_chromeos_unittest.cc b/chrome/browser/notifications/login_state_notification_blocker_chromeos_unittest.cc
index 7c32d54d..0ec35a5a 100644
--- a/chrome/browser/notifications/login_state_notification_blocker_chromeos_unittest.cc
+++ b/chrome/browser/notifications/login_state_notification_blocker_chromeos_unittest.cc
@@ -21,7 +21,7 @@
 using session_manager::SessionState;
 
 class LoginStateNotificationBlockerChromeOSTest
-    : public ash::test::AshTestBase,
+    : public ash::AshTestBase,
       public message_center::NotificationBlocker::Observer {
  public:
   LoginStateNotificationBlockerChromeOSTest()
@@ -33,7 +33,7 @@
     session_manager_ = base::MakeUnique<SessionManager>();
     session_manager_->SetSessionState(SessionState::LOGIN_PRIMARY);
 
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
     blocker_.reset(new LoginStateNotificationBlockerChromeOS(
         message_center::MessageCenter::Get()));
     blocker_->AddObserver(this);
@@ -42,7 +42,7 @@
   void TearDown() override {
     blocker_->RemoveObserver(this);
     blocker_.reset();
-    ash::test::AshTestBase::TearDown();
+    ash::AshTestBase::TearDown();
   }
 
   // message_center::NotificationBlocker::Observer overrides:
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc
index a43bd707..b5e3d1239 100644
--- a/chrome/browser/password_manager/password_manager_test_base.cc
+++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -222,7 +222,8 @@
 
 void BubbleObserver::AcceptSavePrompt() const {
   ASSERT_TRUE(IsShowingSavePrompt());
-  passwords_ui_controller_->SavePassword();
+  passwords_ui_controller_->SavePassword(
+      passwords_ui_controller_->GetPendingPassword().username_value);
   EXPECT_FALSE(IsShowingSavePrompt());
 }
 
diff --git a/chrome/browser/permissions/permission_prompt_android.cc b/chrome/browser/permissions/permission_prompt_android.cc
index baec61e..2bdb079 100644
--- a/chrome/browser/permissions/permission_prompt_android.cc
+++ b/chrome/browser/permissions/permission_prompt_android.cc
@@ -18,21 +18,14 @@
 #include "ui/base/l10n/l10n_util.h"
 
 PermissionPromptAndroid::PermissionPromptAndroid(
-    content::WebContents* web_contents)
+    content::WebContents* web_contents,
+    Delegate* delegate)
     : web_contents_(web_contents),
-      delegate_(nullptr),
+      delegate_(delegate),
       persist_(true),
       weak_factory_(this) {
   DCHECK(web_contents);
-}
 
-PermissionPromptAndroid::~PermissionPromptAndroid() {}
-
-void PermissionPromptAndroid::SetDelegate(Delegate* delegate) {
-  delegate_ = delegate;
-}
-
-void PermissionPromptAndroid::Show() {
   bool has_gesture = true;
   for (const PermissionRequest* request : delegate_->Requests()) {
     has_gesture &=
@@ -53,20 +46,12 @@
       delegate_->Requests()[0]->GetOrigin());
 }
 
+PermissionPromptAndroid::~PermissionPromptAndroid() {}
+
 bool PermissionPromptAndroid::CanAcceptRequestUpdate() {
   return false;
 }
 
-bool PermissionPromptAndroid::HidesAutomatically() {
-  return true;
-}
-
-void PermissionPromptAndroid::Hide() {
-  // Hide() is only called if HidesAutomatically() returns false or
-  // CanAcceptRequestUpdate() return true.
-  NOTREACHED();
-}
-
 void PermissionPromptAndroid::UpdateAnchorPosition() {
   NOTREACHED() << "UpdateAnchorPosition is not implemented";
 }
@@ -77,38 +62,32 @@
 }
 
 void PermissionPromptAndroid::Closing() {
-  if (delegate_)
-    delegate_->Closing();
+  delegate_->Closing();
 }
 
 void PermissionPromptAndroid::TogglePersist(bool value) {
   persist_ = value;
-  if (delegate_)
-    delegate_->TogglePersist(value);
+  delegate_->TogglePersist(value);
 }
 
 void PermissionPromptAndroid::Accept() {
-  if (delegate_) {
-    if (ShouldShowPersistenceToggle()) {
-      for (const PermissionRequest* request : delegate_->Requests()) {
-        PermissionUmaUtil::PermissionPromptAcceptedWithPersistenceToggle(
-            request->GetContentSettingsType(), persist_);
-      }
+  if (ShouldShowPersistenceToggle()) {
+    for (const PermissionRequest* request : delegate_->Requests()) {
+      PermissionUmaUtil::PermissionPromptAcceptedWithPersistenceToggle(
+          request->GetContentSettingsType(), persist_);
     }
-    delegate_->Accept();
   }
+  delegate_->Accept();
 }
 
 void PermissionPromptAndroid::Deny() {
-  if (delegate_) {
-    if (ShouldShowPersistenceToggle()) {
-      for (const PermissionRequest* request : delegate_->Requests()) {
-        PermissionUmaUtil::PermissionPromptDeniedWithPersistenceToggle(
-            request->GetContentSettingsType(), persist_);
-      }
+  if (ShouldShowPersistenceToggle()) {
+    for (const PermissionRequest* request : delegate_->Requests()) {
+      PermissionUmaUtil::PermissionPromptDeniedWithPersistenceToggle(
+          request->GetContentSettingsType(), persist_);
     }
-    delegate_->Deny();
   }
+  delegate_->Deny();
 }
 
 size_t PermissionPromptAndroid::PermissionCount() const {
@@ -183,6 +162,7 @@
 
 // static
 std::unique_ptr<PermissionPrompt> PermissionPrompt::Create(
-    content::WebContents* web_contents) {
-  return base::MakeUnique<PermissionPromptAndroid>(web_contents);
+    content::WebContents* web_contents,
+    Delegate* delegate) {
+  return base::MakeUnique<PermissionPromptAndroid>(web_contents, delegate);
 }
diff --git a/chrome/browser/permissions/permission_prompt_android.h b/chrome/browser/permissions/permission_prompt_android.h
index 28d74f7..8364b56 100644
--- a/chrome/browser/permissions/permission_prompt_android.h
+++ b/chrome/browser/permissions/permission_prompt_android.h
@@ -19,15 +19,12 @@
 
 class PermissionPromptAndroid : public PermissionPrompt {
  public:
-  explicit PermissionPromptAndroid(content::WebContents* web_contents);
+  PermissionPromptAndroid(content::WebContents* web_contents,
+                          Delegate* delegate);
   ~PermissionPromptAndroid() override;
 
   // PermissionPrompt:
-  void SetDelegate(Delegate* delegate) override;
-  void Show() override;
   bool CanAcceptRequestUpdate() override;
-  bool HidesAutomatically() override;
-  void Hide() override;
   void UpdateAnchorPosition() override;
   gfx::NativeWindow GetNativeWindow() override;
 
diff --git a/chrome/browser/permissions/permission_request_manager.cc b/chrome/browser/permissions/permission_request_manager.cc
index 8d967f4..8686773 100644
--- a/chrome/browser/permissions/permission_request_manager.cc
+++ b/chrome/browser/permissions/permission_request_manager.cc
@@ -404,9 +404,7 @@
   DCHECK(main_frame_has_fully_loaded_);
   DCHECK(tab_can_show_prompts_);
 
-  view_ = view_factory_.Run(web_contents());
-  view_->SetDelegate(this);
-  view_->Show();
+  view_ = view_factory_.Run(web_contents(), this);
   PermissionUmaUtil::PermissionPromptShown(requests_);
   NotifyBubbleAdded();
 
@@ -417,9 +415,6 @@
 
 void PermissionRequestManager::DeleteBubble() {
   DCHECK(view_);
-  if (!view_->HidesAutomatically())
-    view_->Hide();
-  view_->SetDelegate(nullptr);
   view_.reset();
 }
 
diff --git a/chrome/browser/permissions/permission_request_manager.h b/chrome/browser/permissions/permission_request_manager.h
index 3a1be984..59fa3fe 100644
--- a/chrome/browser/permissions/permission_request_manager.h
+++ b/chrome/browser/permissions/permission_request_manager.h
@@ -118,7 +118,6 @@
   // lot of friends.
   friend class GeolocationBrowserTest;
   friend class GeolocationPermissionContextTests;
-  friend class MockPermissionPrompt;
   friend class MockPermissionPromptFactory;
   friend class PermissionContextBaseTests;
   friend class PermissionRequestManagerTest;
diff --git a/chrome/browser/printing/cloud_print/privet_http_impl.cc b/chrome/browser/printing/cloud_print/privet_http_impl.cc
index a576f6cd..35c78df 100644
--- a/chrome/browser/printing/cloud_print/privet_http_impl.cc
+++ b/chrome/browser/printing/cloud_print/privet_http_impl.cc
@@ -729,7 +729,7 @@
   replacements.SetPortStr(port);
 
   net::NetworkTrafficAnnotationTag traffic_annotation =
-      net::DefineNetworkTrafficAnnotation("cloud_print", R"(
+      net::DefineNetworkTrafficAnnotation("privet_http_impl", R"(
         semantics {
           sender: "Cloud Print"
           description:
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc
index e600164..53c2d86 100644
--- a/chrome/browser/resource_coordinator/tab_manager.cc
+++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -224,7 +224,7 @@
   // in the following way:
   // https://docs.google.com/document/d/1hPHkKtXXBTlsZx9s-9U17XC-ofEIzPo9FYbBEc7PPbk/edit?usp=sharing
   std::string purge_and_suspend_time = variations::GetVariationParamValue(
-      "PurgeAndSuspend", "purge-and-suspend-time");
+      "PurgeAndSuspendAggressive", "purge-and-suspend-time");
   unsigned int min_time_to_purge_sec = 0;
   if (purge_and_suspend_time.empty() ||
       !base::StringToUint(purge_and_suspend_time, &min_time_to_purge_sec))
@@ -233,7 +233,7 @@
     min_time_to_purge_ = base::TimeDelta::FromSeconds(min_time_to_purge_sec);
 
   std::string max_purge_and_suspend_time = variations::GetVariationParamValue(
-      "PurgeAndSuspend", "max-purge-and-suspend-time");
+      "PurgeAndSuspendAggressive", "max-purge-and-suspend-time");
   unsigned int max_time_to_purge_sec = 0;
   // If max-purge-and-suspend-time is not specified or
   // max-purge-and-suspend-time is not valid (not number or smaller than
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
index aa999f7c..63ed0fe 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
@@ -394,15 +394,15 @@
    * @private
    */
   onEditableChanged_: function(evt) {
+    if (!this.createTextEditHandlerIfNeeded_(evt.target))
+      return;
+
     if (!ChromeVoxState.instance.currentRange) {
       this.onEventDefault(evt);
       ChromeVoxState.instance.setCurrentRange(
           cursors.Range.fromNode(evt.target));
     }
 
-    if (!this.createTextEditHandlerIfNeeded_(evt.target))
-      return;
-
     // Sync the ChromeVox range to the editable, if a selection exists.
     var anchorObject = evt.target.root.anchorObject;
     var anchorOffset = evt.target.root.anchorOffset || 0;
@@ -527,7 +527,8 @@
       return false;
 
     var topRoot = AutomationUtil.getTopLevelRoot(node);
-    if (topRoot && topRoot.parent && !topRoot.parent.state.focused)
+    if (!node.state.focused ||
+        (topRoot && topRoot.parent && !topRoot.parent.state.focused))
       return false;
 
     // Re-target the node to the root of the editable.
diff --git a/chrome/browser/resources/md_bookmarks/app.js b/chrome/browser/resources/md_bookmarks/app.js
index f11db766..24b2f1b 100644
--- a/chrome/browser/resources/md_bookmarks/app.js
+++ b/chrome/browser/resources/md_bookmarks/app.js
@@ -122,6 +122,11 @@
         return node.id;
       });
       this.dispatch(bookmarks.actions.setSearchResults(ids));
+      this.fire('iron-announce', {
+        text: ids.length > 0 ?
+            loadTimeData.getStringF('searchResults', this.searchTerm_) :
+            loadTimeData.getString('noSearchResults')
+      });
     }.bind(this));
   },
 
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.js b/chrome/browser/resources/md_bookmarks/command_manager.js
index 020f92b1..ce6ae6b1 100644
--- a/chrome/browser/resources/md_bookmarks/command_manager.js
+++ b/chrome/browser/resources/md_bookmarks/command_manager.js
@@ -273,6 +273,9 @@
             if (command == Command.COPY_URL) {
               labelPromise =
                   Promise.resolve(loadTimeData.getString('toastUrlCopied'));
+            } else if (idList.length == 1) {
+              labelPromise =
+                  Promise.resolve(loadTimeData.getString('toastItemCopied'));
             } else {
               labelPromise = cr.sendWithPromise(
                   'getPluralString', 'toastItemsCopied', idList.length);
@@ -290,8 +293,16 @@
         case Command.DELETE:
           var idList = Array.from(this.minimizeDeletionSet_(itemIds));
           var title = state.nodes[idList[0]].title;
-          var labelPromise = cr.sendWithPromise(
-              'getPluralString', 'toastItemsDeleted', idList.length);
+          var labelPromise;
+
+          if (idList.length == 1) {
+            labelPromise =
+                Promise.resolve(loadTimeData.getString('toastItemDeleted'));
+          } else {
+            labelPromise = cr.sendWithPromise(
+                'getPluralString', 'toastItemsDeleted', idList.length);
+          }
+
           chrome.bookmarkManagerPrivate.removeTrees(idList, function() {
             this.showTitleToast_(labelPromise, title, true);
           }.bind(this));
diff --git a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
index 46eaf42..1810e03 100644
--- a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
+++ b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
@@ -27,6 +27,7 @@
     {
       'target_name': 'app',
       'dependencies': [
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
         '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:splitter',
         '<(EXTERNS_GYP):chrome_extensions',
         'api_listener',
diff --git a/chrome/browser/resources/md_extensions/detail_view.html b/chrome/browser/resources/md_extensions/detail_view.html
index 4424074..cc60306 100644
--- a/chrome/browser/resources/md_extensions/detail_view.html
+++ b/chrome/browser/resources/md_extensions/detail_view.html
@@ -68,7 +68,6 @@
 
       .section {
         border-bottom: 1px solid var(--paper-grey-400);
-        font-size: 13px;
         padding: 16px 20px;
       }
 
diff --git a/chrome/browser/resources/md_extensions/extensions.html b/chrome/browser/resources/md_extensions/extensions.html
index 531a1605..fb287b7b 100644
--- a/chrome/browser/resources/md_extensions/extensions.html
+++ b/chrome/browser/resources/md_extensions/extensions.html
@@ -13,14 +13,15 @@
 
     html,
     body {
-      font-family: Roboto;
       height: 100%;
+      line-height: 154%;
       margin: 0;
     }
   </style>
 </head>
 <body>
   <extensions-manager></extensions-manager>
+  <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
   <link rel="import" href="chrome://resources/html/load_time_data.html">
   <link rel="import" href="chrome://extensions/strings.html">
   <link rel="import" href="chrome://extensions/service.html">
diff --git a/chrome/browser/resources/md_extensions/item.html b/chrome/browser/resources/md_extensions/item.html
index 7c5e1c6..2c6a58f 100644
--- a/chrome/browser/resources/md_extensions/item.html
+++ b/chrome/browser/resources/md_extensions/item.html
@@ -33,7 +33,6 @@
         background: white;
         display: flex;
         flex-direction: column;
-        font-size: 13px;
         height: 160px;
         width: 400px;
       }
@@ -83,12 +82,6 @@
         color: var(--paper-grey-600);
       }
 
-      #description,
-      #extension-id,
-      #inspect-views {
-        line-height: 20px;
-      }
-
       #inspect-views paper-button {
         color: var(--google-blue-700);
         height: 20px;
diff --git a/chrome/browser/resources/md_extensions/keyboard_shortcuts.html b/chrome/browser/resources/md_extensions/keyboard_shortcuts.html
index 347e9a0d..c4b1e18 100644
--- a/chrome/browser/resources/md_extensions/keyboard_shortcuts.html
+++ b/chrome/browser/resources/md_extensions/keyboard_shortcuts.html
@@ -25,7 +25,6 @@
       .command-entry {
         align-items: center;
         display: flex;
-        font-size: 13px;
         height: 48px;
       }
 
diff --git a/chrome/browser/resources/md_extensions/load_error.html b/chrome/browser/resources/md_extensions/load_error.html
index 0f4c095..f1fd855 100644
--- a/chrome/browser/resources/md_extensions/load_error.html
+++ b/chrome/browser/resources/md_extensions/load_error.html
@@ -9,12 +9,6 @@
 <dom-module id="extensions-load-error">
   <template>
     <style include="cr-shared-style">
-      .body {
-        /* TODO(scottchen): make a shared font-size/line-height css file. */
-        font-size: 13px;
-        line-height: 20px;
-      }
-
       .description-row {
         display: flex;
       }
@@ -29,7 +23,6 @@
         border-radius: 2px;
         cursor: pointer;
         display: flex;
-        font-size: 13px;
         justify-content: center;
         padding: 8px 12px;
         text-transform: uppercase;
diff --git a/chrome/browser/resources/md_extensions/manager.html b/chrome/browser/resources/md_extensions/manager.html
index dfa7722..4349db64 100644
--- a/chrome/browser/resources/md_extensions/manager.html
+++ b/chrome/browser/resources/md_extensions/manager.html
@@ -67,7 +67,6 @@
 
       extensions-toolbar {
         background: var(--md-toolbar-color);
-        font-size: 13px;
       }
     </style>
     <extensions-drop-overlay></extensions-drop-overlay>
diff --git a/chrome/browser/resources/md_extensions/pack_dialog.html b/chrome/browser/resources/md_extensions/pack_dialog.html
index 9ef2cd4..f276ea1 100644
--- a/chrome/browser/resources/md_extensions/pack_dialog.html
+++ b/chrome/browser/resources/md_extensions/pack_dialog.html
@@ -15,18 +15,11 @@
         border-radius: 2px;
         cursor: pointer;
         display: flex;
-        font-size: 13px;
         justify-content: center;
         padding: 8px 12px;
         text-transform: uppercase;
       }
 
-      .body {
-        /* TODO(scottchen): make a shared font-size/line-height css file. */
-        font-size: 13px;
-        line-height: 20px;
-      }
-
       .file-input {
         display: flex;
         --paper-input-container-input: {
diff --git a/chrome/browser/resources/md_extensions/shortcut_input.html b/chrome/browser/resources/md_extensions/shortcut_input.html
index 3645469..381c52b0 100644
--- a/chrome/browser/resources/md_extensions/shortcut_input.html
+++ b/chrome/browser/resources/md_extensions/shortcut_input.html
@@ -24,7 +24,7 @@
         --paper-input-container-color: var(--paper-grey-400);
         --paper-input-container-focus-color: var(--google-blue-500);
         --paper-input-container-input: {
-          font-size: 13px;
+          font-size: inherit;
         };
       }
 
diff --git a/chrome/browser/resources/md_extensions/sidebar.html b/chrome/browser/resources/md_extensions/sidebar.html
index 925f4c9a..c8dcb01 100644
--- a/chrome/browser/resources/md_extensions/sidebar.html
+++ b/chrome/browser/resources/md_extensions/sidebar.html
@@ -38,7 +38,6 @@
         -webkit-padding-start: 24px;
         color: #5A5A5A;
         cursor: pointer;
-        font-size: 13px;
         height: 48px;
       }
 
diff --git a/chrome/browser/resources/md_extensions/toolbar.html b/chrome/browser/resources/md_extensions/toolbar.html
index b1f44efdf..d825277 100644
--- a/chrome/browser/resources/md_extensions/toolbar.html
+++ b/chrome/browser/resources/md_extensions/toolbar.html
@@ -19,7 +19,6 @@
       cr-toolbar {
         --cr-toolbar-field-width: var(--toolbar-width);
         background: var(--toolbar-color);
-        font-size: 13px;
       }
 
       .dev-controls {
@@ -40,7 +39,6 @@
         -webkit-margin-end: 16px;
         -webkit-margin-start: 0;
         color: white;
-        font-size: 13px;
         padding: 12px 9px;
       }
 
diff --git a/chrome/browser/sync/sync_error_notifier_ash_unittest.cc b/chrome/browser/sync/sync_error_notifier_ash_unittest.cc
index 04a0a0a65..9ae2b97 100644
--- a/chrome/browser/sync/sync_error_notifier_ash_unittest.cc
+++ b/chrome/browser/sync/sync_error_notifier_ash_unittest.cc
@@ -77,7 +77,7 @@
   return base::MakeUnique<FakeLoginUIService>();
 }
 
-class SyncErrorNotifierTest : public AshTestBase  {
+class SyncErrorNotifierTest : public AshTestBase {
  public:
   SyncErrorNotifierTest() {}
   ~SyncErrorNotifierTest() override {}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.cc b/chrome/browser/ui/app_list/arc/arc_app_test.cc
index 69e3bc9..61cff8d 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_test.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_test.cc
@@ -189,7 +189,7 @@
   arc_service_manager_.reset();
   if (dbus_thread_manager_initialized_) {
     // DBusThreadManager may be initialized from other testing utility,
-    // such as ash::test::AshTestHelper::SetUp(), so Shutdown() only when
+    // such as ash::AshTestHelper::SetUp(), so Shutdown() only when
     // it is initialized in ArcAppTest::SetUp().
     chromeos::DBusThreadManager::Shutdown();
     dbus_thread_manager_initialized_ = false;
diff --git a/chrome/browser/ui/ash/accessibility/ax_tree_source_aura_unittest.cc b/chrome/browser/ui/ash/accessibility/ax_tree_source_aura_unittest.cc
index 76d2100..6a0eaf1 100644
--- a/chrome/browser/ui/ash/accessibility/ax_tree_source_aura_unittest.cc
+++ b/chrome/browser/ui/ash/accessibility/ax_tree_source_aura_unittest.cc
@@ -47,7 +47,7 @@
   return count;
 }
 
-class AXTreeSourceAuraTest : public ash::test::AshTestBase {
+class AXTreeSourceAuraTest : public ash::AshTestBase {
  public:
   AXTreeSourceAuraTest() {}
   ~AXTreeSourceAuraTest() override {}
diff --git a/chrome/browser/ui/ash/app_list/app_list_presenter_service.cc b/chrome/browser/ui/ash/app_list/app_list_presenter_service.cc
index 10324452..ea494f3e 100644
--- a/chrome/browser/ui/ash/app_list/app_list_presenter_service.cc
+++ b/chrome/browser/ui/ash/app_list/app_list_presenter_service.cc
@@ -9,13 +9,13 @@
 #include "ash/public/interfaces/constants.mojom.h"
 #include "chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h"
 #include "chrome/browser/ui/ash/app_list/app_list_service_ash.h"
-#include "components/arc/arc_service_manager.h"
 #include "content/public/common/service_manager_connection.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "ui/app_list/presenter/app_list_presenter_impl.h"
 #include "ui/gfx/geometry/rect.h"
 
-AppListPresenterService::AppListPresenterService() : binding_(this) {
+AppListPresenterService::AppListPresenterService(Profile* profile)
+    : profile_(profile), binding_(this) {
   content::ServiceManagerConnection* connection =
       content::ServiceManagerConnection::GetForProcess();
   if (connection && connection->GetConnector()) {
@@ -47,8 +47,8 @@
 }
 
 void AppListPresenterService::StartVoiceInteractionSession() {
-  auto* service = arc::ArcServiceManager::Get()
-                      ->GetService<arc::ArcVoiceInteractionFrameworkService>();
+  auto* service =
+      arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile_);
   if (service)
     service->StartSessionFromUserInteraction(gfx::Rect());
 }
diff --git a/chrome/browser/ui/ash/app_list/app_list_presenter_service.h b/chrome/browser/ui/ash/app_list/app_list_presenter_service.h
index 89b52b353..17c4d0b88 100644
--- a/chrome/browser/ui/ash/app_list/app_list_presenter_service.h
+++ b/chrome/browser/ui/ash/app_list/app_list_presenter_service.h
@@ -9,6 +9,8 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "ui/app_list/presenter/app_list_presenter.mojom.h"
 
+class Profile;
+
 namespace app_list {
 class AppListPresenterImpl;
 }
@@ -16,7 +18,7 @@
 // A service providing the Mojo interface to manipulate the App List.
 class AppListPresenterService : public app_list::mojom::AppListPresenter {
  public:
-  AppListPresenterService();
+  explicit AppListPresenterService(Profile* profile);
   ~AppListPresenterService() override;
 
   // app_list::mojom::AppListPresenter:
@@ -28,6 +30,7 @@
  private:
   app_list::AppListPresenterImpl* GetPresenter();
 
+  Profile* const profile_;  // Owned by ProfileManager.
   mojo::Binding<app_list::mojom::AppListPresenter> binding_;
 
   DISALLOW_COPY_AND_ASSIGN(AppListPresenterService);
diff --git a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
index e690aa6..6b3e7ff 100644
--- a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
+++ b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
@@ -111,7 +111,8 @@
   // The AppListPresenterService ctor calls AppListServiceAsh::GetInstance(),
   // which isn't available in the AppListServiceAsh constructor, so init here.
   // This establishes the mojo connections between the app list and presenter.
-  app_list_presenter_service_ = base::MakeUnique<AppListPresenterService>();
+  app_list_presenter_service_ =
+      base::MakeUnique<AppListPresenterService>(initial_profile);
 
   // Ensure the StartPageService is created here. This early initialization is
   // necessary to allow the WebContents to load before the app list is shown.
diff --git a/chrome/browser/ui/ash/chrome_screenshot_grabber.h b/chrome/browser/ui/ash/chrome_screenshot_grabber.h
index eb6da75..c58c88dc 100644
--- a/chrome/browser/ui/ash/chrome_screenshot_grabber.h
+++ b/chrome/browser/ui/ash/chrome_screenshot_grabber.h
@@ -14,9 +14,7 @@
 class Profile;
 
 namespace ash {
-namespace test {
 class ChromeScreenshotGrabberTest;
-}  // namespace test
 }  // namespace ash
 
 class ChromeScreenshotGrabber : public ash::ScreenshotDelegate,
@@ -48,7 +46,7 @@
                              const base::FilePath& screenshot_path) override;
 
  private:
-  friend class ash::test::ChromeScreenshotGrabberTest;
+  friend class ash::ChromeScreenshotGrabberTest;
 
   Notification* CreateNotification(
       ui::ScreenshotGrabberObserver::Result screenshot_result,
diff --git a/chrome/browser/ui/ash/chrome_screenshot_grabber_unittest.cc b/chrome/browser/ui/ash/chrome_screenshot_grabber_unittest.cc
index 45a009f..9920f3df 100644
--- a/chrome/browser/ui/ash/chrome_screenshot_grabber_unittest.cc
+++ b/chrome/browser/ui/ash/chrome_screenshot_grabber_unittest.cc
@@ -27,7 +27,6 @@
 #include "ui/snapshot/screenshot_grabber.h"
 
 namespace ash {
-namespace test {
 
 class ChromeScreenshotGrabberTest : public AshTestBase,
                                     public ui::ScreenshotGrabberObserver {
@@ -135,5 +134,4 @@
   chromeos::LoginState::Shutdown();
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/chrome/browser/ui/ash/keyboard_controller_browsertest.cc b/chrome/browser/ui/ash/keyboard_controller_browsertest.cc
index b5b6bbf..964e183 100644
--- a/chrome/browser/ui/ash/keyboard_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/keyboard_controller_browsertest.cc
@@ -204,7 +204,7 @@
   controller->ui()->GetContentsWindow()->SetBounds(test_bounds);
   gfx::Rect keyboard_bounds = controller->GetContainerWindow()->bounds();
   // Starts overscroll.
-  controller->NotifyKeyboardBoundsChanging(keyboard_bounds);
+  controller->NotifyContentsBoundsChanging(keyboard_bounds);
 
   // Non ime window should have smaller visible view port due to overlap with
   // virtual keyboard.
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
index 4ef87da1..6668d76d 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -316,7 +316,7 @@
   // Try to rip off |item_index|.
   void RipOffItemIndex(int index,
                        ui::test::EventGenerator* generator,
-                       ash::test::ShelfViewTestAPI* test,
+                       ash::ShelfViewTestAPI* test,
                        RipOffCommand command) {
     ash::ShelfButton* button = test->GetButton(index);
     gfx::Point start_point = button->GetBoundsInScreen().CenterPoint();
@@ -1893,7 +1893,7 @@
   // Get a number of interfaces we need.
   ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow(),
                                      gfx::Point());
-  ash::test::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
+  ash::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
   AppListService* service = AppListService::Get();
 
   // There should be two items in our launcher by this time.
@@ -2020,7 +2020,7 @@
   ash::Shelf* secondary_shelf = ash::Shelf::ForWindow(secondary_root_window);
 
   ui::test::EventGenerator generator(secondary_root_window, gfx::Point());
-  ash::test::ShelfViewTestAPI test(secondary_shelf->GetShelfViewForTesting());
+  ash::ShelfViewTestAPI test(secondary_shelf->GetShelfViewForTesting());
   AppListService* service = AppListService::Get();
 
   // There should be two items in our shelf by this time.
@@ -2104,7 +2104,7 @@
 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest, DISABLED_DragOffShelf) {
   ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow(),
                                      gfx::Point());
-  ash::test::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
+  ash::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
   test.SetAnimationDuration(1);  // Speed up animations for test.
   // Create a known application and check that we have 3 items in the shelf.
   CreateShortcut("app1");
@@ -2203,7 +2203,7 @@
 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest, ShelfButtonContextMenu) {
   ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow(),
                                      gfx::Point());
-  ash::test::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
+  ash::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
   const int browser_index = GetIndexOfShelfItemType(ash::TYPE_BROWSER_SHORTCUT);
   ASSERT_LE(0, browser_index);
   ash::ShelfButton* button = test.GetButton(browser_index);
@@ -2234,7 +2234,7 @@
   // Get a number of interfaces we need.
   ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow(),
                                      gfx::Point());
-  ash::test::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
+  ash::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
   AppListService* service = AppListService::Get();
   // There should be two items in our shelf by this time.
   EXPECT_EQ(2, model_->item_count());
@@ -2343,7 +2343,7 @@
   // No overflow yet.
   EXPECT_FALSE(shelf_->shelf_widget()->IsShowingOverflowBubble());
 
-  ash::test::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
+  ash::ShelfViewTestAPI test(shelf_->GetShelfViewForTesting());
 
   int items_added = 0;
   while (!test.IsOverflowButtonVisible()) {
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index a474346..22ccec7 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -382,7 +382,7 @@
 // A shell delegate that owns a ChromeLauncherController, like production.
 // TODO(msw): Refine ChromeLauncherController lifetime management.
 // TODO(msw): Avoid relying on TestShellDelegate's ShelfInitializer.
-class ChromeLauncherTestShellDelegate : public ash::test::TestShellDelegate {
+class ChromeLauncherTestShellDelegate : public ash::TestShellDelegate {
  public:
   explicit ChromeLauncherTestShellDelegate(ash::ShelfModel* shelf_model)
       : shelf_model_(shelf_model) {}
@@ -394,7 +394,7 @@
     return launcher_controller_.get();
   }
 
-  // ash::test::TestShellDelegate:
+  // ash::TestShellDelegate:
   void ShelfShutdown() override { launcher_controller_.reset(); }
 
  private:
diff --git a/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc b/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc
index 4eb1833..d7cf021 100644
--- a/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc
@@ -38,14 +38,14 @@
 namespace {
 
 // A shell delegate that owns a ChromeLauncherController, like production.
-class ChromeLauncherTestShellDelegate : public ash::test::TestShellDelegate {
+class ChromeLauncherTestShellDelegate : public ash::TestShellDelegate {
  public:
   explicit ChromeLauncherTestShellDelegate(Profile* profile)
       : profile_(profile) {}
 
   ChromeLauncherController* controller() { return controller_.get(); }
 
-  // ash::test::TestShellDelegate:
+  // ash::TestShellDelegate:
   void ShelfInit() override {
     if (!controller_) {
       controller_ = base::MakeUnique<ChromeLauncherController>(
@@ -62,7 +62,7 @@
   DISALLOW_COPY_AND_ASSIGN(ChromeLauncherTestShellDelegate);
 };
 
-class LauncherContextMenuTest : public ash::test::AshTestBase {
+class LauncherContextMenuTest : public ash::AshTestBase {
  protected:
   static bool IsItemPresentInMenu(LauncherContextMenu* menu, int command_id) {
     return menu->GetIndexOfCommandId(command_id) != -1;
@@ -75,7 +75,7 @@
     session_manager_ = base::MakeUnique<session_manager::SessionManager>();
     shell_delegate_ = new ChromeLauncherTestShellDelegate(&profile_);
     ash_test_helper()->set_test_shell_delegate(shell_delegate_);
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
   }
 
   ash::Shelf* GetShelf(int64_t display_id) {
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos_unittest.cc
index e4eec75..684dd9b 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos_unittest.cc
@@ -20,7 +20,6 @@
 #include "ui/base/models/menu_model.h"
 
 namespace ash {
-namespace test {
 
 // A test class for preparing the chrome::MultiUserContextMenu.
 class MultiUserContextMenuChromeOSTest : public AshTestBase {
@@ -120,5 +119,4 @@
   }
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc
index 6b1af4aa..525ae64d 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc
@@ -23,7 +23,7 @@
 using base::UTF8ToUTF16;
 
 class MultiUserNotificationBlockerChromeOSTest
-    : public ash::test::AshTestBase,
+    : public ash::AshTestBase,
       public message_center::NotificationBlocker::Observer {
  public:
   MultiUserNotificationBlockerChromeOSTest()
@@ -34,17 +34,17 @@
         user_manager_enabler_(fake_user_manager_) {}
   ~MultiUserNotificationBlockerChromeOSTest() override {}
 
-  // ash::test::AshTestBase overrides:
+  // ash::AshTestBase overrides:
   void SetUp() override {
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
     ASSERT_TRUE(testing_profile_manager_.SetUp());
 
     // MultiUserWindowManager is initialized after the log in.
     testing_profile_manager_.CreateTestingProfile(GetDefaultUserId());
     fake_user_manager_->AddUser(AccountId::FromUserEmail(GetDefaultUserId()));
 
-    ash::test::TestShellDelegate* shell_delegate =
-        static_cast<ash::test::TestShellDelegate*>(
+    ash::TestShellDelegate* shell_delegate =
+        static_cast<ash::TestShellDelegate*>(
             ash::Shell::Get()->shell_delegate());
     shell_delegate->set_multi_profiles_enabled(true);
     chrome::MultiUserWindowManager::CreateInstance();
@@ -65,7 +65,7 @@
     GetMultiUserWindowManager()->notification_blocker_->RemoveObserver(this);
     if (chrome::MultiUserWindowManager::GetInstance())
       chrome::MultiUserWindowManager::DeleteInstance();
-    ash::test::AshTestBase::TearDown();
+    ash::AshTestBase::TearDown();
     chromeos::WallpaperManager::Shutdown();
   }
 
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_util_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_util_chromeos_unittest.cc
index ca44d76..c53b2ad9 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_util_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_util_chromeos_unittest.cc
@@ -16,7 +16,6 @@
 #include "components/user_manager/user.h"
 
 namespace ash {
-namespace test {
 
 namespace {
 
@@ -127,5 +126,4 @@
             multi_user_util::GetAccountIdFromProfile(profile()).GetUserEmail());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h
index 6ced23f..db262fb 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h
@@ -33,9 +33,7 @@
 }  // namespace aura
 
 namespace ash {
-namespace test {
 class MultiUserWindowManagerChromeOSTest;
-}  // namespace test
 }  // namespace ash
 
 namespace chrome {
@@ -189,7 +187,7 @@
 
  private:
   friend class ::MultiUserNotificationBlockerChromeOSTest;
-  friend class ash::test::MultiUserWindowManagerChromeOSTest;
+  friend class ash::MultiUserWindowManagerChromeOSTest;
 
   typedef std::map<AccountId, AppObserver*> AccountIdToAppWindowObserver;
   typedef std::map<aura::Window*, bool> TransientWindowToVisibility;
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
index ba92bc4..3db3bc1 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
@@ -113,7 +113,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestShellContentState);
 };
 
-class TestShellDelegateChromeOS : public ash::test::TestShellDelegate {
+class TestShellDelegateChromeOS : public ash::TestShellDelegate {
  public:
   TestShellDelegateChromeOS() {}
 
@@ -142,7 +142,6 @@
 }  // namespace
 
 namespace ash {
-namespace test {
 
 // A test class for preparing the chrome::MultiUserWindowManager. It creates
 // various windows and instantiates the chrome::MultiUserWindowManager.
@@ -307,8 +306,8 @@
 
 void MultiUserWindowManagerChromeOSTest::SetUp() {
   ash_test_helper()->set_test_shell_delegate(new TestShellDelegateChromeOS);
-  ash::test::AshTestEnvironmentContent* test_environment =
-      static_cast<ash::test::AshTestEnvironmentContent*>(
+  ash::AshTestEnvironmentContent* test_environment =
+      static_cast<ash::AshTestEnvironmentContent*>(
           ash_test_helper()->ash_test_environment());
   test_environment->set_content_state(new ::TestShellContentState);
   AshTestBase::SetUp();
@@ -1642,5 +1641,4 @@
   EXPECT_EQ(nullptr, ChromeNewWindowClient::GetActiveBrowser());
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/chrome/browser/ui/ash/multi_user/user_switch_util_unittest.cc b/chrome/browser/ui/ash/multi_user/user_switch_util_unittest.cc
index 0dbc1b60..201047a2 100644
--- a/chrome/browser/ui/ash/multi_user/user_switch_util_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/user_switch_util_unittest.cc
@@ -16,7 +16,7 @@
 
 namespace ash {
 
-class TrySwitchingUserTest : public ash::test::AshTestBase {
+class TrySwitchingUserTest : public ash::AshTestBase {
  public:
   // The action type to perform / check for upon user switching.
   enum ActionType {
@@ -33,7 +33,7 @@
   ~TrySwitchingUserTest() override {}
 
   void SetUp() override {
-    test::AshTestBase::SetUp();
+    AshTestBase::SetUp();
     TrayItemView::DisableAnimationsForTest();
     SystemTray* system_tray = GetPrimarySystemTray();
     share_item_ = system_tray->GetScreenShareItem();
diff --git a/chrome/browser/ui/ash/palette_delegate_chromeos.cc b/chrome/browser/ui/ash/palette_delegate_chromeos.cc
index 998a37b..a1367685 100644
--- a/chrome/browser/ui/ash/palette_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/palette_delegate_chromeos.cc
@@ -12,15 +12,12 @@
 #include "ash/utility/screenshot_controller.h"
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h"
 #include "chrome/browser/chromeos/note_taking_helper.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/pref_names.h"
-#include "components/arc/arc_bridge_service.h"
-#include "components/arc/arc_service_manager.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_service.h"
 #include "components/user_manager/user_manager.h"
@@ -31,8 +28,9 @@
 
 class VoiceInteractionScreenshotDelegate : public ash::ScreenshotDelegate {
  public:
-  VoiceInteractionScreenshotDelegate() {}
-  ~VoiceInteractionScreenshotDelegate() override {}
+  explicit VoiceInteractionScreenshotDelegate(Profile* profile)
+      : profile_(profile) {}
+  ~VoiceInteractionScreenshotDelegate() override = default;
 
  private:
   void HandleTakeScreenshotForAllRootWindows() override { NOTIMPLEMENTED(); }
@@ -40,8 +38,8 @@
   void HandleTakePartialScreenshot(aura::Window* window,
                                    const gfx::Rect& rect) override {
     auto* framework =
-        arc::ArcServiceManager::Get()
-            ->GetService<arc::ArcVoiceInteractionFrameworkService>();
+        arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(
+            profile_);
     if (!framework)
       return;
     double device_scale_factor = window->layer()->device_scale_factor();
@@ -55,6 +53,8 @@
 
   bool CanTakeScreenshot() override { return true; }
 
+  Profile* const profile_;  // Owned by ProfileManager.
+
   DISALLOW_COPY_AND_ASSIGN(VoiceInteractionScreenshotDelegate);
 };
 
@@ -181,7 +181,7 @@
     // into a separate tool next to "Capture region".
     if (!voice_interaction_screenshot_delegate_) {
       voice_interaction_screenshot_delegate_ =
-          base::MakeUnique<VoiceInteractionScreenshotDelegate>();
+          base::MakeUnique<VoiceInteractionScreenshotDelegate>(profile_);
     }
     screenshot_delegate = voice_interaction_screenshot_delegate_.get();
   } else {
@@ -203,19 +203,14 @@
 }
 
 bool PaletteDelegateChromeOS::IsMetalayerSupported() {
-  if (!arc::IsArcAllowedForProfile(profile_))
-    return false;
-
-  arc::ArcVoiceInteractionFrameworkService* service =
-      arc::ArcServiceManager::Get()
-          ->GetService<arc::ArcVoiceInteractionFrameworkService>();
+  auto* service =
+      arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile_);
   return service && service->IsMetalayerSupported();
 }
 
 void PaletteDelegateChromeOS::ShowMetalayer(const base::Closure& closed) {
-  arc::ArcVoiceInteractionFrameworkService* service =
-      arc::ArcServiceManager::Get()
-          ->GetService<arc::ArcVoiceInteractionFrameworkService>();
+  auto* service =
+      arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile_);
   if (!service) {
     if (!closed.is_null())
       closed.Run();
@@ -225,9 +220,8 @@
 }
 
 void PaletteDelegateChromeOS::HideMetalayer() {
-  arc::ArcVoiceInteractionFrameworkService* service =
-      arc::ArcServiceManager::Get()
-          ->GetService<arc::ArcVoiceInteractionFrameworkService>();
+  auto* service =
+      arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile_);
   if (!service)
     return;
   service->HideMetalayer();
diff --git a/chrome/browser/ui/ash/window_positioner_unittest.cc b/chrome/browser/ui/ash/window_positioner_unittest.cc
index e11a735..a3fde08 100644
--- a/chrome/browser/ui/ash/window_positioner_unittest.cc
+++ b/chrome/browser/ui/ash/window_positioner_unittest.cc
@@ -21,7 +21,6 @@
 #include "ui/display/screen.h"
 
 namespace ash {
-namespace test {
 
 // A test class for preparing window positioner tests - it creates a testing
 // base by adding a window and a popup which can be independently
@@ -225,5 +224,4 @@
                       full);
 }
 
-}  // namespace test
 }  // namespace ash
diff --git a/chrome/browser/ui/cocoa/passwords/save_pending_password_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/save_pending_password_view_controller_unittest.mm
index 6039edc..50f4038 100644
--- a/chrome/browser/ui/cocoa/passwords/save_pending_password_view_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/save_pending_password_view_controller_unittest.mm
@@ -14,9 +14,13 @@
 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 
+// Gmock matcher
+using testing::_;
+
 namespace {
 
 class SavePendingPasswordViewControllerTest
@@ -42,7 +46,10 @@
   profile()->GetPrefs()->SetBoolean(
       password_manager::prefs::kWasSignInPasswordPromoClicked, true);
   SetUpSavePendingState(false);
-  EXPECT_CALL(*ui_controller(), SavePassword());
+  EXPECT_CALL(
+      *ui_controller(),
+      SavePassword(
+          GetModelAndCreateIfNull()->pending_password().username_value));
   EXPECT_CALL(*ui_controller(), NeverSavePassword()).Times(0);
   [controller().saveButton performClick:nil];
 
@@ -52,7 +59,7 @@
 TEST_F(SavePendingPasswordViewControllerTest,
        ShouldNeverAndDismissWhenNeverClicked) {
   SetUpSavePendingState(false);
-  EXPECT_CALL(*ui_controller(), SavePassword()).Times(0);
+  EXPECT_CALL(*ui_controller(), SavePassword(_)).Times(0);
   EXPECT_CALL(*ui_controller(), NeverSavePassword());
   [controller().neverButton performClick:nil];
 
@@ -61,7 +68,7 @@
 
 TEST_F(SavePendingPasswordViewControllerTest, ShouldDismissWhenCrossClicked) {
   SetUpSavePendingState(false);
-  EXPECT_CALL(*ui_controller(), SavePassword()).Times(0);
+  EXPECT_CALL(*ui_controller(), SavePassword(_)).Times(0);
   EXPECT_CALL(*ui_controller(), NeverSavePassword()).Times(0);
   [controller().closeButton performClick:nil];
 
@@ -84,7 +91,7 @@
   // A user may press mouse down, some navigation closes the bubble, mouse up
   // still sends the action.
   SetUpSavePendingState(false);
-  EXPECT_CALL(*ui_controller(), SavePassword()).Times(0);
+  EXPECT_CALL(*ui_controller(), SavePassword(_)).Times(0);
   EXPECT_CALL(*ui_controller(), NeverSavePassword()).Times(0);
   [delegate() setModel:nil];
   [controller().neverButton performClick:nil];
diff --git a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa.h b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa.h
index 775d550..b3d4ce2c 100644
--- a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa.h
+++ b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa.h
@@ -20,15 +20,11 @@
 
 class PermissionBubbleCocoa : public PermissionPrompt {
  public:
-  explicit PermissionBubbleCocoa(Browser* browser);
+  PermissionBubbleCocoa(Browser* browser, Delegate* delegate);
   ~PermissionBubbleCocoa() override;
 
   // PermissionPrompt:
-  void Show() override;
-  void Hide() override;
-  void SetDelegate(Delegate* delegate) override;
   bool CanAcceptRequestUpdate() override;
-  bool HidesAutomatically() override;
   void UpdateAnchorPosition() override;
   gfx::NativeWindow GetNativeWindow() override;
 
diff --git a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa.mm b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa.mm
index 6f644ad..4412909e 100644
--- a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa.mm
+++ b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa.mm
@@ -11,13 +11,9 @@
 #include "content/public/browser/web_contents.h"
 #import "ui/base/cocoa/nsview_additions.h"
 
-PermissionBubbleCocoa::PermissionBubbleCocoa(Browser* browser)
-    : browser_(browser), delegate_(nullptr), bubbleController_(nil) {}
-
-PermissionBubbleCocoa::~PermissionBubbleCocoa() {
-}
-
-void PermissionBubbleCocoa::Show() {
+PermissionBubbleCocoa::PermissionBubbleCocoa(Browser* browser,
+                                             Delegate* delegate)
+    : browser_(browser), delegate_(delegate), bubbleController_(nil) {
   DCHECK(browser_);
 
   if (!bubbleController_) {
@@ -29,24 +25,14 @@
   [bubbleController_ showWithDelegate:delegate_];
 }
 
-void PermissionBubbleCocoa::Hide() {
+PermissionBubbleCocoa::~PermissionBubbleCocoa() {
   [bubbleController_ close];
 }
 
-void PermissionBubbleCocoa::SetDelegate(Delegate* delegate) {
-  if (delegate_ == delegate)
-    return;
-  delegate_ = delegate;
-}
-
 bool PermissionBubbleCocoa::CanAcceptRequestUpdate() {
   return ![[[bubbleController_ window] contentView] cr_isMouseInView];
 }
 
-bool PermissionBubbleCocoa::HidesAutomatically() {
-  return false;
-}
-
 void PermissionBubbleCocoa::UpdateAnchorPosition() {
   [bubbleController_ updateAnchorPosition];
 }
diff --git a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_browser_test.mm b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_browser_test.mm
index a2a7fe5..64fa66a2 100644
--- a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_browser_test.mm
+++ b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_browser_test.mm
@@ -15,20 +15,15 @@
 #include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
 
 IN_PROC_BROWSER_TEST_F(PermissionBubbleBrowserTest, HasLocationBarByDefault) {
-  PermissionBubbleCocoa bubble(browser());
-  bubble.SetDelegate(test_delegate());
-  bubble.Show();
+  PermissionBubbleCocoa bubble(browser(), test_delegate());
   EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
-  bubble.Hide();
 }
 
 IN_PROC_BROWSER_TEST_F(PermissionBubbleBrowserTest,
                        BrowserFullscreenHasLocationBar) {
   ui::test::ScopedFakeNSWindowFullscreen faker;
 
-  PermissionBubbleCocoa bubble(browser());
-  bubble.SetDelegate(test_delegate());
-  bubble.Show();
+  PermissionBubbleCocoa bubble(browser(), test_delegate());
   EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
 
   FullscreenController* controller =
@@ -52,16 +47,13 @@
   faker.FinishTransition();
 
   EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
-  bubble.Hide();
 }
 
 IN_PROC_BROWSER_TEST_F(PermissionBubbleBrowserTest,
                        TabFullscreenHasLocationBar) {
   ui::test::ScopedFakeNSWindowFullscreen faker;
 
-  PermissionBubbleCocoa bubble(browser());
-  bubble.SetDelegate(test_delegate());
-  bubble.Show();
+  PermissionBubbleCocoa bubble(browser(), test_delegate());
   EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
 
   FullscreenController* controller =
@@ -76,25 +68,18 @@
   faker.FinishTransition();
 
   EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
-  bubble.Hide();
 }
 
 IN_PROC_BROWSER_TEST_F(PermissionBubbleBrowserTest, AppHasNoLocationBar) {
   Browser* app_browser = OpenExtensionAppWindow();
-  PermissionBubbleCocoa bubble(app_browser);
-  bubble.SetDelegate(test_delegate());
-  bubble.Show();
+  PermissionBubbleCocoa bubble(app_browser, test_delegate());
   EXPECT_FALSE([bubble.bubbleController_ hasVisibleLocationBar]);
-  bubble.Hide();
 }
 
 // http://crbug.com/470724
 // Kiosk mode on Mac has a location bar but it shouldn't.
 IN_PROC_BROWSER_TEST_F(PermissionBubbleKioskBrowserTest,
                        DISABLED_KioskHasNoLocationBar) {
-  PermissionBubbleCocoa bubble(browser());
-  bubble.SetDelegate(test_delegate());
-  bubble.Show();
+  PermissionBubbleCocoa bubble(browser(), test_delegate());
   EXPECT_FALSE([bubble.bubbleController_ hasVisibleLocationBar]);
-  bubble.Hide();
 }
diff --git a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_controller_unittest.mm
index 0acc057..36acb6310 100644
--- a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_controller_unittest.mm
@@ -78,8 +78,8 @@
 
   void SetUp() override {
     CocoaProfileTest::SetUp();
-    bridge_.reset(new PermissionBubbleCocoa(browser()));
     AddRequest(kPermissionA);
+    bridge_.reset(new PermissionBubbleCocoa(browser(), this));
     controller_ =
         [[PermissionBubbleController alloc] initWithBrowser:browser()
                                                      bridge:bridge_.get()];
diff --git a/chrome/browser/ui/cocoa/permission_bubble/permission_prompt_impl_views_mac.mm b/chrome/browser/ui/cocoa/permission_bubble/permission_prompt_impl_views_mac.mm
index 8822b74..95bc5e7 100644
--- a/chrome/browser/ui/cocoa/permission_bubble/permission_prompt_impl_views_mac.mm
+++ b/chrome/browser/ui/cocoa/permission_bubble/permission_prompt_impl_views_mac.mm
@@ -35,11 +35,12 @@
 
 // static
 std::unique_ptr<PermissionPrompt> PermissionPrompt::Create(
-    content::WebContents* web_contents) {
+    content::WebContents* web_contents,
+    Delegate* delegate) {
   if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
     return base::WrapUnique(new PermissionPromptImpl(
-        chrome::FindBrowserWithWebContents(web_contents)));
+        chrome::FindBrowserWithWebContents(web_contents), delegate));
   }
   return base::MakeUnique<PermissionBubbleCocoa>(
-      chrome::FindBrowserWithWebContents(web_contents));
+      chrome::FindBrowserWithWebContents(web_contents), delegate);
 }
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
index 63df6d8..175de7d 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
@@ -407,7 +407,7 @@
   interaction_keeper_->set_update_password_submission_event(
       GetUpdateDismissalReason(UPDATE_CLICKED));
   CleanStatisticsForSite(GetProfile(), origin_);
-  delegate_->SavePassword();
+  delegate_->SavePassword(pending_password_.username_value);
 }
 
 void ManagePasswordsBubbleModel::OnNopeUpdateClicked() {
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
index b3e03e2..4ba64af7 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -263,7 +263,7 @@
   stats.update_time = now;
   EXPECT_CALL(*GetStore(), AddSiteStatsImpl(stats));
   EXPECT_CALL(*controller(), OnNoInteraction());
-  EXPECT_CALL(*controller(), SavePassword()).Times(0);
+  EXPECT_CALL(*controller(), SavePassword(_)).Times(0);
   EXPECT_CALL(*controller(), NeverSavePassword()).Times(0);
   DestroyModelExpectReason(
       password_manager::metrics_util::NO_DIRECT_INTERACTION);
@@ -273,7 +273,7 @@
   PretendPasswordWaiting();
 
   EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
-  EXPECT_CALL(*controller(), SavePassword());
+  EXPECT_CALL(*controller(), SavePassword(GetPendingPassword().username_value));
   EXPECT_CALL(*controller(), NeverSavePassword()).Times(0);
   model()->OnSaveClicked();
   DestroyModelExpectReason(password_manager::metrics_util::CLICKED_SAVE);
@@ -283,7 +283,7 @@
   PretendPasswordWaiting();
 
   EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
-  EXPECT_CALL(*controller(), SavePassword()).Times(0);
+  EXPECT_CALL(*controller(), SavePassword(_)).Times(0);
   EXPECT_CALL(*controller(), NeverSavePassword());
   model()->OnNeverForThisSiteClicked();
   EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE, model()->state());
@@ -338,7 +338,7 @@
   base::HistogramTester histogram_tester;
   PretendPasswordWaiting();
   EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
-  EXPECT_CALL(*controller(), SavePassword());
+  EXPECT_CALL(*controller(), SavePassword(GetPendingPassword().username_value));
   model()->OnSaveClicked();
 
   EXPECT_FALSE(model()->ReplaceToShowPromotionIfNeeded());
@@ -353,7 +353,7 @@
   base::HistogramTester histogram_tester;
   PretendPasswordWaiting();
   EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
-  EXPECT_CALL(*controller(), SavePassword());
+  EXPECT_CALL(*controller(), SavePassword(GetPendingPassword().username_value));
   model()->OnSaveClicked();
 
   EXPECT_TRUE(model()->ReplaceToShowPromotionIfNeeded());
@@ -377,7 +377,7 @@
   base::HistogramTester histogram_tester;
   PretendPasswordWaiting();
   EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
-  EXPECT_CALL(*controller(), SavePassword());
+  EXPECT_CALL(*controller(), SavePassword(GetPendingPassword().username_value));
   model()->OnSaveClicked();
 
   EXPECT_TRUE(model()->ReplaceToShowPromotionIfNeeded());
@@ -400,7 +400,7 @@
   base::HistogramTester histogram_tester;
   PretendPasswordWaiting();
   EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
-  EXPECT_CALL(*controller(), SavePassword());
+  EXPECT_CALL(*controller(), SavePassword(GetPendingPassword().username_value));
   model()->OnSaveClicked();
 
   EXPECT_TRUE(model()->ReplaceToShowPromotionIfNeeded());
@@ -536,27 +536,28 @@
                      !update) {
             EXPECT_CALL(*GetStore(),
                         RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
-            EXPECT_CALL(*controller(), SavePassword());
+            EXPECT_CALL(*controller(),
+                        SavePassword(GetPendingPassword().username_value));
             model()->OnSaveClicked();
           } else if (interaction == BubbleDismissalReason::kDeclined &&
                      update) {
-            EXPECT_CALL(*controller(), SavePassword()).Times(0);
+            EXPECT_CALL(*controller(), SavePassword(_)).Times(0);
             model()->OnNopeUpdateClicked();
           } else if (interaction == BubbleDismissalReason::kDeclined &&
                      !update) {
             EXPECT_CALL(*GetStore(),
                         RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
-            EXPECT_CALL(*controller(), SavePassword()).Times(0);
+            EXPECT_CALL(*controller(), SavePassword(_)).Times(0);
             EXPECT_CALL(*controller(), NeverSavePassword());
             model()->OnNeverForThisSiteClicked();
           } else if (interaction == BubbleDismissalReason::kIgnored && update) {
-            EXPECT_CALL(*controller(), SavePassword()).Times(0);
+            EXPECT_CALL(*controller(), SavePassword(_)).Times(0);
             EXPECT_CALL(*controller(), NeverSavePassword()).Times(0);
           } else if (interaction == BubbleDismissalReason::kIgnored &&
                      !update) {
             EXPECT_CALL(*GetStore(), AddSiteStatsImpl(testing::_));
             EXPECT_CALL(*controller(), OnNoInteraction());
-            EXPECT_CALL(*controller(), SavePassword()).Times(0);
+            EXPECT_CALL(*controller(), SavePassword(_)).Times(0);
             EXPECT_CALL(*controller(), NeverSavePassword()).Times(0);
           } else {
             NOTREACHED();
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
index bc4c761..6ef8efa 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -309,8 +309,12 @@
   // The state stays the same.
 }
 
-void ManagePasswordsUIController::SavePassword() {
+void ManagePasswordsUIController::SavePassword(const base::string16& username) {
   DCHECK_EQ(password_manager::ui::PENDING_PASSWORD_STATE, GetState());
+  if (passwords_data_.form_manager()->pending_credentials().username_value !=
+      username) {
+    passwords_data_.form_manager()->UpdateUsername(username);
+  }
   SavePasswordInternal();
   passwords_data_.TransitionToState(password_manager::ui::MANAGE_STATE);
   // The icon is to be updated after the bubble (either "Save password" or "Sign
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
index f325b3f..3c756d9 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -101,7 +101,7 @@
   void OnNoInteraction() override;
   void OnNopeUpdateClicked() override;
   void NeverSavePassword() override;
-  void SavePassword() override;
+  void SavePassword(const base::string16& username) override;
   void UpdatePassword(const autofill::PasswordForm& password_form) override;
   void ChooseCredential(
       const autofill::PasswordForm& form,
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h
index 1a450479..15281f3 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h
@@ -33,7 +33,7 @@
   MOCK_METHOD0(OnNoInteraction, void());
   MOCK_METHOD0(OnNopeUpdateClicked, void());
   MOCK_METHOD0(NeverSavePassword, void());
-  MOCK_METHOD0(SavePassword, void());
+  MOCK_METHOD1(SavePassword, void(const base::string16&));
   MOCK_METHOD1(UpdatePassword, void(const autofill::PasswordForm&));
   MOCK_METHOD2(ChooseCredential, void(const autofill::PasswordForm&,
                                       password_manager::CredentialType));
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
index 06bade7..db036a0 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -406,7 +406,7 @@
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
 
-  controller()->SavePassword();
+  controller()->SavePassword(test_local_form().username_value);
   ExpectIconStateIs(password_manager::ui::MANAGE_STATE);
 }
 
@@ -447,7 +447,7 @@
       CreateFormManager());
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
-  controller()->SavePassword();
+  controller()->SavePassword(test_local_form().username_value);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnBubbleHidden();
   ExpectIconStateIs(password_manager::ui::MANAGE_STATE);
diff --git a/chrome/browser/ui/passwords/passwords_model_delegate.h b/chrome/browser/ui/passwords/passwords_model_delegate.h
index c8339c93..e5f75af5 100644
--- a/chrome/browser/ui/passwords/passwords_model_delegate.h
+++ b/chrome/browser/ui/passwords/passwords_model_delegate.h
@@ -83,8 +83,10 @@
   // Called from the model when the user chooses to never save passwords.
   virtual void NeverSavePassword() = 0;
 
-  // Called from the model when the user chooses to save a password.
-  virtual void SavePassword() = 0;
+  // Called from the model when the user chooses to save a password. The
+  // username seen on the ui is sent as a parameter, and handled accordingly if
+  // user had edited it.
+  virtual void SavePassword(const base::string16& username) = 0;
 
   // Called from the model when the user chooses to update a password.
   virtual void UpdatePassword(const autofill::PasswordForm& password_form) = 0;
diff --git a/chrome/browser/ui/passwords/passwords_model_delegate_mock.h b/chrome/browser/ui/passwords/passwords_model_delegate_mock.h
index 6f999293..2f1aefc1 100644
--- a/chrome/browser/ui/passwords/passwords_model_delegate_mock.h
+++ b/chrome/browser/ui/passwords/passwords_model_delegate_mock.h
@@ -36,7 +36,7 @@
   MOCK_METHOD0(OnNoInteraction, void());
   MOCK_METHOD0(OnNopeUpdateClicked, void());
   MOCK_METHOD0(NeverSavePassword, void());
-  MOCK_METHOD0(SavePassword, void());
+  MOCK_METHOD1(SavePassword, void(const base::string16&));
   MOCK_METHOD1(UpdatePassword, void(const autofill::PasswordForm&));
   MOCK_METHOD2(ChooseCredential, void(const autofill::PasswordForm&,
                                       password_manager::CredentialType));
diff --git a/chrome/browser/ui/permission_bubble/mock_permission_prompt.cc b/chrome/browser/ui/permission_bubble/mock_permission_prompt.cc
index 87f3801..e34c6430 100644
--- a/chrome/browser/ui/permission_bubble/mock_permission_prompt.cc
+++ b/chrome/browser/ui/permission_bubble/mock_permission_prompt.cc
@@ -6,7 +6,7 @@
 
 #include "base/bind.h"
 #include "base/run_loop.h"
-#include "chrome/browser/permissions/permission_request_manager.h"
+#include "build/build_config.h"
 #include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -15,43 +15,14 @@
 #endif
 
 MockPermissionPrompt::~MockPermissionPrompt() {
-  Hide();
-}
-
-void MockPermissionPrompt::Show() {
-  factory_->ShowView(this);
-  factory_->show_count_++;
-  factory_->requests_count_ = manager_->requests_.size();
-  for (const PermissionRequest* request : manager_->requests_) {
-    factory_->request_types_seen_.push_back(
-        request->GetPermissionRequestType());
-    // The actual prompt will call these, so test they're sane.
-    EXPECT_FALSE(request->GetMessageTextFragment().empty());
-#if defined(OS_ANDROID)
-    EXPECT_FALSE(request->GetMessageText().empty());
-    EXPECT_NE(0, request->GetIconId());
-#else
-    EXPECT_FALSE(request->GetIconId().is_empty());
-#endif
-  }
-  factory_->UpdateResponseType();
-  is_visible_ = true;
+  if (factory_)
+    factory_->HideView(this);
 }
 
 bool MockPermissionPrompt::CanAcceptRequestUpdate() {
   return can_update_ui_;
 }
 
-bool MockPermissionPrompt::HidesAutomatically() {
-  return false;
-}
-
-void MockPermissionPrompt::Hide() {
-  if (is_visible_ && factory_)
-    factory_->HideView(this);
-  is_visible_ = false;
-}
-
 void MockPermissionPrompt::UpdateAnchorPosition() {}
 
 gfx::NativeWindow MockPermissionPrompt::GetNativeWindow() {
@@ -60,13 +31,18 @@
   return nullptr;
 }
 
-bool MockPermissionPrompt::IsVisible() {
-  return is_visible_;
-}
-
 MockPermissionPrompt::MockPermissionPrompt(MockPermissionPromptFactory* factory,
-                                           PermissionRequestManager* manager)
-    : factory_(factory),
-      manager_(manager),
-      can_update_ui_(true),
-      is_visible_(false) {}
+                                           Delegate* delegate,
+                                           bool can_update_ui)
+    : factory_(factory), delegate_(delegate), can_update_ui_(can_update_ui) {
+  for (const PermissionRequest* request : delegate_->Requests()) {
+    // The actual prompt will call these, so test they're sane.
+    EXPECT_FALSE(request->GetMessageTextFragment().empty());
+#if defined(OS_ANDROID)
+    EXPECT_FALSE(request->GetMessageText().empty());
+    EXPECT_NE(0, request->GetIconId());
+#else
+    EXPECT_FALSE(request->GetIconId().is_empty());
+#endif
+  }
+}
diff --git a/chrome/browser/ui/permission_bubble/mock_permission_prompt.h b/chrome/browser/ui/permission_bubble/mock_permission_prompt.h
index 7ae6942..3a29258 100644
--- a/chrome/browser/ui/permission_bubble/mock_permission_prompt.h
+++ b/chrome/browser/ui/permission_bubble/mock_permission_prompt.h
@@ -8,7 +8,6 @@
 #include "chrome/browser/ui/permission_bubble/permission_prompt.h"
 
 class MockPermissionPromptFactory;
-class PermissionRequestManager;
 
 // Provides a skeleton class for unit and browser testing when trying to test
 // the request manager logic. Should not be used for anything that requires
@@ -19,11 +18,7 @@
   ~MockPermissionPrompt() override;
 
   // PermissionPrompt:
-  void SetDelegate(Delegate* delegate) override {}
-  void Show() override;
   bool CanAcceptRequestUpdate() override;
-  bool HidesAutomatically() override;
-  void Hide() override;
   void UpdateAnchorPosition() override;
   gfx::NativeWindow GetNativeWindow() override;
 
@@ -33,12 +28,12 @@
   friend class MockPermissionPromptFactory;
 
   MockPermissionPrompt(MockPermissionPromptFactory* factory,
-                       PermissionRequestManager* manager);
+                       Delegate* delegate,
+                       bool can_update_ui);
 
   MockPermissionPromptFactory* factory_;
-  PermissionRequestManager* manager_;
+  Delegate* delegate_;
   bool can_update_ui_;
-  bool is_visible_;
 };
 
 #endif  // CHROME_BROWSER_UI_PERMISSION_BUBBLE_MOCK_PERMISSION_PROMPT_H_
diff --git a/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.cc b/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.cc
index de7fc7e..3447053 100644
--- a/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.cc
+++ b/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.cc
@@ -32,9 +32,21 @@
 }
 
 std::unique_ptr<PermissionPrompt> MockPermissionPromptFactory::Create(
-    content::WebContents* web_contents) {
-  MockPermissionPrompt* prompt = new MockPermissionPrompt(this, manager_);
-  prompt->can_update_ui_ = can_update_ui_;
+    content::WebContents* web_contents,
+    PermissionPrompt::Delegate* delegate) {
+  MockPermissionPrompt* prompt =
+      new MockPermissionPrompt(this, delegate, can_update_ui_);
+
+  prompts_.push_back(prompt);
+  show_count_++;
+  requests_count_ = delegate->Requests().size();
+  for (const PermissionRequest* request : delegate->Requests())
+    request_types_seen_.push_back(request->GetPermissionRequestType());
+
+  if (!show_bubble_quit_closure_.is_null())
+    show_bubble_quit_closure_.Run();
+
+  manager_->set_auto_response_for_test(response_type_);
   return base::WrapUnique(prompt);
 }
 
@@ -55,11 +67,7 @@
 }
 
 bool MockPermissionPromptFactory::is_visible() {
-  for (auto* prompt : prompts_) {
-    if (prompt->IsVisible())
-      return true;
-  }
-  return false;
+  return !prompts_.empty();
 }
 
 int MockPermissionPromptFactory::TotalRequestCount() {
@@ -82,22 +90,10 @@
 
 // static
 std::unique_ptr<PermissionPrompt> MockPermissionPromptFactory::DoNotCreate(
-    content::WebContents* web_contents) {
+    content::WebContents* web_contents,
+    PermissionPrompt::Delegate* delegate) {
   NOTREACHED();
-  return base::WrapUnique(new MockPermissionPrompt(nullptr, nullptr));
-}
-
-void MockPermissionPromptFactory::UpdateResponseType() {
-  manager_->set_auto_response_for_test(response_type_);
-}
-
-void MockPermissionPromptFactory::ShowView(MockPermissionPrompt* prompt) {
-  if (base::ContainsValue(prompts_, prompt))
-    return;
-  prompts_.push_back(prompt);
-
-  if (!show_bubble_quit_closure_.is_null())
-    show_bubble_quit_closure_.Run();
+  return base::WrapUnique(new MockPermissionPrompt(nullptr, nullptr, false));
 }
 
 void MockPermissionPromptFactory::HideView(MockPermissionPrompt* prompt) {
diff --git a/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h b/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h
index 32d689b..2671e919 100644
--- a/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h
+++ b/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h
@@ -10,9 +10,9 @@
 
 #include "chrome/browser/permissions/permission_request.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
+#include "chrome/browser/ui/permission_bubble/permission_prompt.h"
 
 class MockPermissionPrompt;
-class PermissionPrompt;
 
 namespace content {
 class WebContents;
@@ -29,7 +29,9 @@
   ~MockPermissionPromptFactory();
 
   // Create method called by the PBM to show a bubble.
-  std::unique_ptr<PermissionPrompt> Create(content::WebContents* web_contents);
+  std::unique_ptr<PermissionPrompt> Create(
+      content::WebContents* web_contents,
+      PermissionPrompt::Delegate* delegate);
 
   void SetCanUpdateUi(bool can_update_ui);
 
@@ -64,10 +66,9 @@
   // This shouldn't be called. Is here to fail tests that try to create a bubble
   // after the factory has been destroyed.
   static std::unique_ptr<PermissionPrompt> DoNotCreate(
-      content::WebContents* web_contents);
+      content::WebContents* web_contents,
+      PermissionPrompt::Delegate* delegate);
 
-  void UpdateResponseType();
-  void ShowView(MockPermissionPrompt* view);
   void HideView(MockPermissionPrompt* view);
 
   bool can_update_ui_;
diff --git a/chrome/browser/ui/permission_bubble/permission_prompt.h b/chrome/browser/ui/permission_bubble/permission_prompt.h
index e81cf8e..b034e2b 100644
--- a/chrome/browser/ui/permission_bubble/permission_prompt.h
+++ b/chrome/browser/ui/permission_bubble/permission_prompt.h
@@ -39,34 +39,21 @@
     virtual void Closing() = 0;
   };
 
-  typedef base::Callback<std::unique_ptr<PermissionPrompt>(
-      content::WebContents*)>
+  typedef base::Callback<
+      std::unique_ptr<PermissionPrompt>(content::WebContents*, Delegate*)>
       Factory;
 
-  // Create a platform specific instance.
+  // Create and display a platform specific prompt.
   static std::unique_ptr<PermissionPrompt> Create(
-      content::WebContents* web_contents);
+      content::WebContents* web_contents,
+      Delegate* delegate);
   virtual ~PermissionPrompt() {}
 
-  // Sets the delegate which will receive UI events forwarded from the prompt.
-  virtual void SetDelegate(Delegate* delegate) = 0;
-
-  // Show a prompt with the requests from the delegate. This will only be called
-  // if there is no prompt showing.
-  virtual void Show() = 0;
-
   // Returns true if the view can accept a new Show() command to coalesce
   // requests. Currently the policy is that this should return true if the view
   // is being shown and the mouse is not over the view area (!IsMouseHovered).
   virtual bool CanAcceptRequestUpdate() = 0;
 
-  // Returns true if the prompt UI will manage hiding itself when the user
-  // resolves the prompt, on page navigation/destruction, and on tab switching.
-  virtual bool HidesAutomatically() = 0;
-
-  // Hides the permission prompt.
-  virtual void Hide() = 0;
-
   // Updates where the prompt should be anchored. ex: fullscreen toggle.
   virtual void UpdateAnchorPosition() = 0;
 
diff --git a/chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.h b/chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.h
index 47e80de..1bb053cc 100644
--- a/chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.h
+++ b/chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.h
@@ -23,6 +23,9 @@
   // Returns active WebContents.
   virtual content::WebContents* GetActiveWebContents() const = 0;
 
+  // ToolbarModelDelegate:
+  bool ShouldDisplayURL() const override;
+
  protected:
   ChromeToolbarModelDelegate();
   ~ChromeToolbarModelDelegate() override;
@@ -32,7 +35,6 @@
       const GURL& url,
       const base::string16& formatted_url) const override;
   bool GetURL(GURL* url) const override;
-  bool ShouldDisplayURL() const override;
   SecurityLevel GetSecurityLevel() const override;
   scoped_refptr<net::X509Certificate> GetCertificate() const override;
   bool FailsMalwareCheck() const override;
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_ash_unittest.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_ash_unittest.cc
index b9ba6298..6297fff 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_ash_unittest.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_ash_unittest.cc
@@ -22,14 +22,14 @@
 
 }  // namespace
 
-class AppInfoDialogAshTest : public ash::test::AshTestBase {
+class AppInfoDialogAshTest : public ash::AshTestBase {
  public:
   AppInfoDialogAshTest()
       : extension_environment_(base::MessageLoopForUI::current()) {}
 
   // Overridden from testing::Test:
   void SetUp() override {
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
     ash_test_helper()->test_views_delegate()->set_layout_provider(
         base::MakeUnique<ChromeLayoutProvider>());
     widget_ = views::DialogDelegate::CreateDialogWidget(
@@ -43,7 +43,7 @@
 
   void TearDown() override {
     widget_->CloseNow();
-    ash::test::AshTestBase::TearDown();
+    ash::AshTestBase::TearDown();
   }
 
  protected:
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index b77191b..cae699e 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -796,6 +796,9 @@
   // Tell the model to reset itself.
   model()->OnKillFocus();
 
+  // Deselect the text. Ensures the cursor is an I-beam.
+  SelectRange(gfx::Range(0));
+
   // When deselected, elide and reset scroll position. After eliding, the old
   // scroll offset is meaningless (since the string is guaranteed to fit within
   // the view). The scroll must be reset or the text may be rendered partly or
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
index c1955e5c..fb4136e 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
@@ -149,9 +149,10 @@
   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
   EXPECT_TRUE(omnibox_view->IsSelectAll());
 
-  // Clicking in another view should clear focus.
+  // Clicking in another view should clear focus and the selection.
   ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter());
   EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
+  EXPECT_FALSE(omnibox_view->IsSelectAll());
 
   // Clicking in the omnibox again should take focus and select all text again.
   ASSERT_NO_FATAL_FAILURE(Click(ui_controls::LEFT,
@@ -244,6 +245,7 @@
   // Take the focus away from the omnibox.
   ASSERT_NO_FATAL_FAILURE(TapBrowserWindowCenter());
   EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
+  EXPECT_FALSE(omnibox_view->IsSelectAll());
 
   // Tapping in the omnibox should take focus and select all text.
   const gfx::Rect omnibox_bounds = BrowserView::GetBrowserViewForBrowser(
@@ -253,9 +255,10 @@
   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
   EXPECT_TRUE(omnibox_view->IsSelectAll());
 
-  // Tapping in another view should clear focus.
+  // Tapping in another view should clear focus and the selection.
   ASSERT_NO_FATAL_FAILURE(TapBrowserWindowCenter());
   EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
+  EXPECT_FALSE(omnibox_view->IsSelectAll());
 
   // Tapping in the omnibox again should take focus and select all text again.
   ASSERT_NO_FATAL_FAILURE(Tap(tap_location, tap_location));
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
index c687b445..78f1e40 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -329,6 +329,8 @@
   // the entire domain fits in 60 pixels. However, 60px is so small it should
   // never happen with any font.
   EXPECT_GT(0, render_text->GetUpdatedDisplayOffset().x());
+  omnibox_view()->SelectAll(false);
+  EXPECT_TRUE(omnibox_view()->IsSelectAll());
 
   // Now enter blurred mode, where the text should be elided to 60px. This means
   // the string itself is truncated. Scrolling would therefore mean the text is
@@ -336,6 +338,7 @@
   omnibox_view()->OnBlur();
   EXPECT_EQ(gfx::ELIDE_TAIL, render_text->elide_behavior());
   EXPECT_EQ(0, render_text->GetUpdatedDisplayOffset().x());
+  EXPECT_FALSE(omnibox_view()->IsSelectAll());
 }
 
 TEST_F(OmniboxViewViewsTest, Emphasis) {
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
index 671dfa8..9276604 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
@@ -249,68 +249,20 @@
 //////////////////////////////////////////////////////////////////////////////
 // PermissionPromptImpl
 
-PermissionPromptImpl::PermissionPromptImpl(Browser* browser)
-    : browser_(browser),
-      delegate_(nullptr),
-      bubble_delegate_(nullptr) {}
+PermissionPromptImpl::PermissionPromptImpl(Browser* browser, Delegate* delegate)
+    : browser_(browser), delegate_(delegate), bubble_delegate_(nullptr) {
+  Show();
+}
 
 PermissionPromptImpl::~PermissionPromptImpl() {
-}
-
-void PermissionPromptImpl::SetDelegate(Delegate* delegate) {
-  delegate_ = delegate;
-}
-
-void PermissionPromptImpl::Show() {
-  DCHECK(browser_);
-  DCHECK(browser_->window());
-
   if (bubble_delegate_)
     bubble_delegate_->CloseBubble();
-
-  bubble_delegate_ =
-      new PermissionsBubbleDialogDelegateView(this, delegate_->Requests());
-
-  // Set |parent_window| because some valid anchors can become hidden.
-  bubble_delegate_->set_parent_window(
-      platform_util::GetViewForWindow(browser_->window()->GetNativeWindow()));
-
-  // Compensate for vertical padding in the anchor view's image. Note this is
-  // ignored whenever the anchor view is null.
-  bubble_delegate_->set_anchor_view_insets(gfx::Insets(
-      GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
-
-  views::Widget* widget =
-      views::BubbleDialogDelegateView::CreateBubble(bubble_delegate_);
-  // If a browser window (or popup) other than the bubble parent has focus,
-  // don't take focus.
-  if (browser_->window()->IsActive())
-    widget->Show();
-  else
-    widget->ShowInactive();
-
-  bubble_delegate_->SizeToContents();
-
-  bubble_delegate_->UpdateAnchor(GetAnchorView(),
-                                 GetAnchorPoint(),
-                                 GetAnchorArrow());
 }
 
 bool PermissionPromptImpl::CanAcceptRequestUpdate() {
   return !(bubble_delegate_ && bubble_delegate_->IsMouseHovered());
 }
 
-bool PermissionPromptImpl::HidesAutomatically() {
-  return false;
-}
-
-void PermissionPromptImpl::Hide() {
-  if (bubble_delegate_) {
-    bubble_delegate_->CloseBubble();
-    bubble_delegate_ = nullptr;
-  }
-}
-
 void PermissionPromptImpl::UpdateAnchorPosition() {
   DCHECK(browser_);
   DCHECK(browser_->window());
@@ -351,3 +303,34 @@
   if (delegate_)
     delegate_->Deny();
 }
+
+void PermissionPromptImpl::Show() {
+  DCHECK(browser_);
+  DCHECK(browser_->window());
+
+  bubble_delegate_ =
+      new PermissionsBubbleDialogDelegateView(this, delegate_->Requests());
+
+  // Set |parent_window| because some valid anchors can become hidden.
+  bubble_delegate_->set_parent_window(
+      platform_util::GetViewForWindow(browser_->window()->GetNativeWindow()));
+
+  // Compensate for vertical padding in the anchor view's image. Note this is
+  // ignored whenever the anchor view is null.
+  bubble_delegate_->set_anchor_view_insets(gfx::Insets(
+      GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
+
+  views::Widget* widget =
+      views::BubbleDialogDelegateView::CreateBubble(bubble_delegate_);
+  // If a browser window (or popup) other than the bubble parent has focus,
+  // don't take focus.
+  if (browser_->window()->IsActive())
+    widget->Show();
+  else
+    widget->ShowInactive();
+
+  bubble_delegate_->SizeToContents();
+
+  bubble_delegate_->UpdateAnchor(GetAnchorView(), GetAnchorPoint(),
+                                 GetAnchorArrow());
+}
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h
index cc6173f..f4a490c 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h
@@ -23,15 +23,11 @@
 
 class PermissionPromptImpl : public PermissionPrompt {
  public:
-  explicit PermissionPromptImpl(Browser* browser);
+  PermissionPromptImpl(Browser* browser, Delegate* delegate);
   ~PermissionPromptImpl() override;
 
   // PermissionPrompt:
-  void SetDelegate(Delegate* delegate) override;
-  void Show() override;
   bool CanAcceptRequestUpdate() override;
-  bool HidesAutomatically() override;
-  void Hide() override;
   void UpdateAnchorPosition() override;
   gfx::NativeWindow GetNativeWindow() override;
 
@@ -41,6 +37,8 @@
   void Deny();
 
  private:
+  void Show();
+
   // These three functions have separate implementations for Views-based and
   // Cocoa-based browsers, to allow this bubble to be used in either.
 
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl_views.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl_views.cc
index 1b688ec..5e46af4 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl_views.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl_views.cc
@@ -50,7 +50,8 @@
 
 // static
 std::unique_ptr<PermissionPrompt> PermissionPrompt::Create(
-    content::WebContents* web_contents) {
+    content::WebContents* web_contents,
+    Delegate* delegate) {
   return base::WrapUnique(new PermissionPromptImpl(
-      chrome::FindBrowserWithWebContents(web_contents)));
+      chrome::FindBrowserWithWebContents(web_contents), delegate));
 }
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index aa33bb8e..abea6e3 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -2144,7 +2144,7 @@
   }
 
   float GetCursorDeviceScaleFactor() const {
-    ash::test::CursorManagerTestApi cursor_test_api(
+    ash::CursorManagerTestApi cursor_test_api(
         ash::Shell::Get()->cursor_manager());
     return cursor_test_api.GetCurrentCursor().device_scale_factor();
   }
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc
index acf074ae..b24ff16 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc
@@ -21,12 +21,12 @@
 
 namespace {
 
-class OobeDisplayChooserTest : public ash::test::AshTestBase {
+class OobeDisplayChooserTest : public ash::AshTestBase {
  public:
-  OobeDisplayChooserTest() : ash::test::AshTestBase() {}
+  OobeDisplayChooserTest() : ash::AshTestBase() {}
 
   void SetUp() override {
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
     display_manager_test_api_.reset(
         new display::test::DisplayManagerTestApi(display_manager()));
   }
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc b/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
index 105c980..3199189 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
@@ -36,7 +36,7 @@
 
 namespace chromeos {
 
-class SigninPrepareUserListTest : public ash::test::AshTestBase,
+class SigninPrepareUserListTest : public ash::AshTestBase,
                                   public MultiProfileUserControllerDelegate {
  public:
   SigninPrepareUserListTest()
@@ -46,7 +46,7 @@
   ~SigninPrepareUserListTest() override {}
 
   void SetUp() override {
-    ash::test::AshTestBase::SetUp();
+    ash::AshTestBase::SetUp();
     profile_manager_.reset(
         new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
     ASSERT_TRUE(profile_manager_->SetUp());
@@ -70,7 +70,7 @@
     chromeos::WallpaperManager::Shutdown();
     controller_.reset();
     profile_manager_.reset();
-    ash::test::AshTestBase::TearDown();
+    ash::AshTestBase::TearDown();
   }
 
   // MultiProfileUserControllerDelegate overrides:
diff --git a/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc b/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc
index 12316c4..d688f7a7 100644
--- a/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc
+++ b/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc
@@ -99,10 +99,16 @@
                      IDS_MD_BOOKMARK_MANAGER_FOLDER_RENAME_TITLE);
   AddLocalizedString(source, "searchPrompt",
                      IDS_BOOKMARK_MANAGER_SEARCH_BUTTON);
+  AddLocalizedString(source, "searchResults",
+                     IDS_MD_BOOKMARK_MANAGER_SEARCH_RESULTS);
   AddLocalizedString(source, "saveEdit", IDS_SAVE);
   AddLocalizedString(source, "title", IDS_MD_BOOKMARK_MANAGER_TITLE);
   AddLocalizedString(source, "toastFolderSorted",
                      IDS_MD_BOOKMARK_MANAGER_TOAST_FOLDER_SORTED);
+  AddLocalizedString(source, "toastItemCopied",
+                     IDS_MD_BOOKMARK_MANAGER_TOAST_ITEM_COPIED);
+  AddLocalizedString(source, "toastItemDeleted",
+                     IDS_MD_BOOKMARK_MANAGER_TOAST_ITEM_DELETED);
   AddLocalizedString(source, "toastUrlCopied",
                      IDS_MD_BOOKMARK_MANAGER_TOAST_URL_COPIED);
   AddLocalizedString(source, "undo", IDS_BOOKMARK_BAR_UNDO);
diff --git a/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc b/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc
index 303cd17..6773ea6 100644
--- a/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc
+++ b/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc
@@ -185,7 +185,7 @@
   }
 
   chromeos::SyncedPrintersManager* prefs_;
-  scoped_refptr<chromeos::printing::PpdProvider> ppd_provider_;
+  scoped_refptr<chromeos::PpdProvider> ppd_provider_;
   std::unique_ptr<chromeos::PrinterConfigurer> printer_configurer_;
   base::WeakPtrFactory<PrinterBackendProxyChromeos> weak_factory_;
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
index d23a203..5243cece 100644
--- a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -269,7 +269,6 @@
 
   UserImageManager* user_image_manager =
       ChromeUserManager::Get()->GetUserImageManager(GetUser()->GetAccountId());
-  int image_index = user_manager::User::USER_IMAGE_INVALID;
   bool waiting_for_camera_photo = false;
 
   if (image_type == "old") {
@@ -284,8 +283,11 @@
                                default_user_image::kHistogramImageOld,
                                default_user_image::kHistogramImagesCount);
     VLOG(1) << "Selected old user image";
-  } else if (image_type == "default" &&
-             default_user_image::IsDefaultImageUrl(image_url, &image_index)) {
+  } else if (image_type == "default") {
+    int image_index = user_manager::User::USER_IMAGE_INVALID;
+    if (!default_user_image::IsDefaultImageUrl(image_url, &image_index))
+      LOG(FATAL) << "Invalid image_url for default image type: " << image_url;
+
     // One of the default user images.
     user_image_manager->SaveUserDefaultImageIndex(image_index);
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
index 11bd680..2fe6cdf 100644
--- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -131,7 +131,7 @@
     : printer_detector_(nullptr),
       profile_(Profile::FromWebUI(webui)),
       weak_factory_(this) {
-  ppd_provider_ = printing::CreateProvider(profile_);
+  ppd_provider_ = CreatePpdProvider(profile_);
   printer_configurer_ = PrinterConfigurer::Create(profile_);
 }
 
@@ -516,28 +516,28 @@
 
 void CupsPrintersHandler::ResolveManufacturersDone(
     const std::string& js_callback,
-    printing::PpdProvider::CallbackResultCode result_code,
+    PpdProvider::CallbackResultCode result_code,
     const std::vector<std::string>& manufacturers) {
   auto manufacturers_value = base::MakeUnique<base::ListValue>();
-  if (result_code == printing::PpdProvider::SUCCESS) {
+  if (result_code == PpdProvider::SUCCESS) {
     manufacturers_value->AppendStrings(manufacturers);
   }
   base::DictionaryValue response;
-  response.SetBoolean("success", result_code == printing::PpdProvider::SUCCESS);
+  response.SetBoolean("success", result_code == PpdProvider::SUCCESS);
   response.Set("manufacturers", std::move(manufacturers_value));
   ResolveJavascriptCallback(base::Value(js_callback), response);
 }
 
 void CupsPrintersHandler::ResolvePrintersDone(
     const std::string& js_callback,
-    printing::PpdProvider::CallbackResultCode result_code,
+    PpdProvider::CallbackResultCode result_code,
     const std::vector<std::string>& printers) {
   auto printers_value = base::MakeUnique<base::ListValue>();
-  if (result_code == printing::PpdProvider::SUCCESS) {
+  if (result_code == PpdProvider::SUCCESS) {
     printers_value->AppendStrings(printers);
   }
   base::DictionaryValue response;
-  response.SetBoolean("success", result_code == printing::PpdProvider::SUCCESS);
+  response.SetBoolean("success", result_code == PpdProvider::SUCCESS);
   response.Set("models", std::move(printers_value));
   ResolveJavascriptCallback(base::Value(js_callback), response);
 }
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
index 424ff52c..9af867b0 100644
--- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
+++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
@@ -25,11 +25,9 @@
 class Profile;
 
 namespace chromeos {
-namespace printing {
-class PpdProvider;
-}
 
 class CombiningPrinterDetector;
+class PpdProvider;
 
 namespace settings {
 
@@ -89,14 +87,12 @@
   void HandleSelectPPDFile(const base::ListValue* args);
 
   // PpdProvider callback handlers.
-  void ResolveManufacturersDone(
-      const std::string& js_callback,
-      printing::PpdProvider::CallbackResultCode result_code,
-      const std::vector<std::string>& available);
-  void ResolvePrintersDone(
-      const std::string& js_callback,
-      printing::PpdProvider::CallbackResultCode result_code,
-      const std::vector<std::string>& available);
+  void ResolveManufacturersDone(const std::string& js_callback,
+                                PpdProvider::CallbackResultCode result_code,
+                                const std::vector<std::string>& available);
+  void ResolvePrintersDone(const std::string& js_callback,
+                           PpdProvider::CallbackResultCode result_code,
+                           const std::vector<std::string>& available);
 
   // ui::SelectFileDialog::Listener override:
   void FileSelected(const base::FilePath& path,
@@ -120,7 +116,7 @@
                         bool ipp_everywhere);
 
   std::unique_ptr<CombiningPrinterDetector> printer_detector_;
-  scoped_refptr<printing::PpdProvider> ppd_provider_;
+  scoped_refptr<PpdProvider> ppd_provider_;
   std::unique_ptr<PrinterConfigurer> printer_configurer_;
 
   Profile* profile_;
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
index 69b02c3..d6f10ef 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
@@ -27,7 +27,7 @@
 #include "ui/display/screen.h"
 #include "ui/wm/public/activation_client.h"
 
-typedef ash::test::AshTestBase WindowSizerAshTest;
+using WindowSizerAshTest = ash::AshTestBase;
 
 namespace {
 
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json
index 1492dd4..3a0191d3 100644
--- a/chrome/common/extensions/api/_api_features.json
+++ b/chrome/common/extensions/api/_api_features.json
@@ -479,10 +479,6 @@
     "dependencies": ["permission:fileManagerPrivate"],
     "contexts": ["blessed_extension"]
   },
-  "fileSystem": {
-    "dependencies": ["permission:fileSystem"],
-    "contexts": ["blessed_extension"]
-  },
   "fileSystemProvider": {
     "dependencies": ["permission:fileSystemProvider"],
     "contexts": ["blessed_extension"]
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 99d6e66..0213405e 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -343,54 +343,6 @@
       "397F221E63F86BE34C30165613E95B6CC8D22A52"   // http://crbug.com/415846
     ]
   },
-  "fileSystem": [{
-    "channel": "stable",
-    "extension_types": ["platform_app"],
-    "default_parent": true
-  },{
-    "channel": "stable",
-    "extension_types": ["extension"],
-    "whitelist": [
-      "2FC374607C2DF285634B67C64A2E356C607091C3",  // Quickoffice
-      "3727DD3E564B6055387425027AD74C58784ACC15",  // Quickoffice internal
-      "12E618C3C6E97495AAECF2AC12DEB082353241C6",  // QO component extension
-      "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2",  // http://crbug.com/312900
-      "D57DE394F36DC1C3220E7604C575D29C51A6C495",  // http://crbug.com/319444
-      "3F65507A3B39259B38C8173C6FFA3D12DF64CCE9",  // http://crbug.com/371562
-      "2B6C6A4A5940017146F3E58B7F90116206E84685",  // http://crbug.com/642141
-      "B6C2EFAB3EC3BF6EF03701408B6B09A67B2D0069",  // http://crbug.com/642141
-      "96FF2FFA5C9173C76D47184B3E86D267B37781DE",  // http://crbug.com/642141
-      "0136FCB13DB29FD5CD442F56E59E53B61F1DF96F"   // http://crbug.com/642141
-    ]
-  }],
-  "fileSystem.directory": {
-    "channel": "stable",
-    "extension_types": ["platform_app"]
-  },
-  "fileSystem.retainEntries": {
-    "channel": "stable",
-    "extension_types": ["platform_app"]
-  },
-  "fileSystem.write": [{
-    "channel": "stable",
-    "extension_types": ["platform_app"]
-  },{
-    "channel": "stable",
-    "extension_types": ["extension"],
-    "whitelist": [
-      "2FC374607C2DF285634B67C64A2E356C607091C3",  // Quickoffice
-      "3727DD3E564B6055387425027AD74C58784ACC15",  // Quickoffice internal
-      "12E618C3C6E97495AAECF2AC12DEB082353241C6",  // QO component extension
-      "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2",  // http://crbug.com/312900
-      "D57DE394F36DC1C3220E7604C575D29C51A6C495",  // http://crbug.com/319444
-      "3F65507A3B39259B38C8173C6FFA3D12DF64CCE9"   // http://crbug.com/371562
-    ]
-  }],
-  "fileSystem.requestFileSystem": {
-    "channel": "stable",
-    "extension_types": ["platform_app"],
-    "platforms": ["chromeos"]
-  },
   "fileSystemProvider": [{
     "channel": "stable",
     "extension_types": ["extension", "platform_app"],
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc
index f500f010..caa73ba 100644
--- a/chrome/common/extensions/permissions/chrome_api_permissions.cc
+++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -216,18 +216,7 @@
 
       // Platform-app permissions.
 
-      // The permission string for "fileSystem" is only shown when
-      // "write" or "directory" is present. Read-only access is only
-      // granted after the user has been shown a file or directory
-      // chooser dialog and selected a file or directory. Selecting
-      // the file or directory is considered consent to read it.
-      {APIPermission::kFileSystem, "fileSystem"},
-      {APIPermission::kFileSystemDirectory, "fileSystem.directory"},
       {APIPermission::kFileSystemProvider, "fileSystemProvider"},
-      {APIPermission::kFileSystemRequestFileSystem,
-       "fileSystem.requestFileSystem"},
-      {APIPermission::kFileSystemRetainEntries, "fileSystem.retainEntries"},
-      {APIPermission::kFileSystemWrite, "fileSystem.write"},
       {APIPermission::kMediaGalleries, "mediaGalleries",
        APIPermissionInfo::kFlagNone,
        &CreateAPIPermission<MediaGalleriesPermission>},
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn
index eec4b43..3f4c2ae 100644
--- a/chrome/renderer/BUILD.gn
+++ b/chrome/renderer/BUILD.gn
@@ -306,8 +306,6 @@
       "resources/extensions/declarative_content_custom_bindings.js",
       "resources/extensions/enterprise_platform_keys_custom_bindings.js",
       "resources/extensions/feedback_private_custom_bindings.js",
-      "resources/extensions/file_entry_binding_util.js",
-      "resources/extensions/file_system_custom_bindings.js",
       "resources/extensions/gcm_custom_bindings.js",
       "resources/extensions/identity_custom_bindings.js",
       "resources/extensions/image_writer_private_custom_bindings.js",
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
index 288de6377..f16b2eb 100644
--- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
+++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -179,7 +179,6 @@
   source_map->RegisterSource("downloads", IDR_DOWNLOADS_CUSTOM_BINDINGS_JS);
   source_map->RegisterSource("feedbackPrivate",
                              IDR_FEEDBACK_PRIVATE_CUSTOM_BINDINGS_JS);
-  source_map->RegisterSource("fileSystem", IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS);
   source_map->RegisterSource("gcm", IDR_GCM_CUSTOM_BINDINGS_JS);
   source_map->RegisterSource("identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS);
   source_map->RegisterSource("imageWriterPrivate",
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd
index 67382cb7..2fa8731a 100644
--- a/chrome/renderer/resources/renderer_resources.grd
+++ b/chrome/renderer/resources/renderer_resources.grd
@@ -48,7 +48,6 @@
         <include name="IDR_DEVELOPER_PRIVATE_CUSTOM_BINDINGS_JS" file="extensions\developer_private_custom_bindings.js" type="BINDATA" />
         <include name="IDR_DOWNLOADS_CUSTOM_BINDINGS_JS" file="extensions\downloads_custom_bindings.js" type="BINDATA" />
         <include name="IDR_FEEDBACK_PRIVATE_CUSTOM_BINDINGS_JS" file="extensions\feedback_private_custom_bindings.js" type="BINDATA" />
-        <include name="IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS" file="extensions\file_system_custom_bindings.js" type="BINDATA" />
         <include name="IDR_GCM_CUSTOM_BINDINGS_JS" file="extensions\gcm_custom_bindings.js" type="BINDATA" />
         <include name="IDR_IDENTITY_CUSTOM_BINDINGS_JS" file="extensions\identity_custom_bindings.js" type="BINDATA" />
         <include name="IDR_IMAGE_WRITER_PRIVATE_CUSTOM_BINDINGS_JS" file="extensions\image_writer_private_custom_bindings.js" type="BINDATA" />
diff --git a/chrome/test/base/ash_test_environment_chrome.cc b/chrome/test/base/ash_test_environment_chrome.cc
index 1e94c07..5a86d12 100644
--- a/chrome/test/base/ash_test_environment_chrome.cc
+++ b/chrome/test/base/ash_test_environment_chrome.cc
@@ -12,7 +12,7 @@
 
 AshTestEnvironmentChrome::~AshTestEnvironmentChrome() {}
 
-std::unique_ptr<ash::test::AshTestViewsDelegate>
+std::unique_ptr<ash::AshTestViewsDelegate>
 AshTestEnvironmentChrome::CreateViewsDelegate() {
-  return base::MakeUnique<ash::test::AshTestViewsDelegate>();
+  return base::MakeUnique<ash::AshTestViewsDelegate>();
 }
diff --git a/chrome/test/base/ash_test_environment_chrome.h b/chrome/test/base/ash_test_environment_chrome.h
index 5388d6d..3f7391f 100644
--- a/chrome/test/base/ash_test_environment_chrome.h
+++ b/chrome/test/base/ash_test_environment_chrome.h
@@ -8,14 +8,13 @@
 #include "ash/test/ash_test_environment.h"
 #include "base/macros.h"
 
-class AshTestEnvironmentChrome : public ash::test::AshTestEnvironment {
+class AshTestEnvironmentChrome : public ash::AshTestEnvironment {
  public:
   AshTestEnvironmentChrome();
   ~AshTestEnvironmentChrome() override;
 
   // AshTestEnvironment:
-  std::unique_ptr<ash::test::AshTestViewsDelegate> CreateViewsDelegate()
-      override;
+  std::unique_ptr<ash::AshTestViewsDelegate> CreateViewsDelegate() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AshTestEnvironmentChrome);
diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc
index 8ac0ca74..58dc3be 100644
--- a/chrome/test/base/browser_with_test_window_test.cc
+++ b/chrome/test/base/browser_with_test_window_test.cc
@@ -51,7 +51,7 @@
 #if defined(OS_CHROMEOS)
   ash_test_environment_ = base::MakeUnique<AshTestEnvironmentChrome>();
   ash_test_helper_ =
-      base::MakeUnique<ash::test::AshTestHelper>(ash_test_environment_.get());
+      base::MakeUnique<ash::AshTestHelper>(ash_test_environment_.get());
 #endif
 }
 
diff --git a/chrome/test/base/browser_with_test_window_test.h b/chrome/test/base/browser_with_test_window_test.h
index 40a3624..4101c18 100644
--- a/chrome/test/base/browser_with_test_window_test.h
+++ b/chrome/test/base/browser_with_test_window_test.h
@@ -108,7 +108,7 @@
   }
 
 #if defined(OS_CHROMEOS)
-  ash::test::AshTestHelper* ash_test_helper() { return ash_test_helper_.get(); }
+  ash::AshTestHelper* ash_test_helper() { return ash_test_helper_.get(); }
 #endif
 
   // The context to help determine desktop type when creating new Widgets.
@@ -187,8 +187,8 @@
   content::RenderViewHostTestEnabler rvh_test_enabler_;
 
 #if defined(OS_CHROMEOS)
-  std::unique_ptr<ash::test::AshTestEnvironment> ash_test_environment_;
-  std::unique_ptr<ash::test::AshTestHelper> ash_test_helper_;
+  std::unique_ptr<ash::AshTestEnvironment> ash_test_environment_;
+  std::unique_ptr<ash::AshTestHelper> ash_test_helper_;
 #elif defined(TOOLKIT_VIEWS)
   std::unique_ptr<views::ScopedViewsTestHelper> views_test_helper_;
 #endif
diff --git a/chrome/test/base/view_event_test_platform_part_chromeos.cc b/chrome/test/base/view_event_test_platform_part_chromeos.cc
index 99e485f..b9e4a9f 100644
--- a/chrome/test/base/view_event_test_platform_part_chromeos.cc
+++ b/chrome/test/base/view_event_test_platform_part_chromeos.cc
@@ -59,8 +59,7 @@
   chromeos::NetworkHandler::Initialize();
 
   env_ = aura::Env::CreateInstance();
-  ash::test::TestShellDelegate* shell_delegate =
-      new ash::test::TestShellDelegate();
+  ash::TestShellDelegate* shell_delegate = new ash::TestShellDelegate();
   ash::ShellInitParams init_params;
   init_params.delegate = shell_delegate;
   init_params.context_factory = context_factory;
@@ -68,7 +67,7 @@
   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       switches::kHostWindowBounds, "0+0-1280x800");
   ash::Shell::CreateInstance(init_params);
-  ash::test::TestSessionControllerClient session_controller_client(
+  ash::TestSessionControllerClient session_controller_client(
       ash::Shell::Get()->session_controller());
   session_controller_client.CreatePredefinedUserSessions(1);
   GetContext()->GetHost()->Show();
diff --git a/chromeos/components/tether/tether_connector.cc b/chromeos/components/tether/tether_connector.cc
index 01faf42..4d64c1d2 100644
--- a/chromeos/components/tether/tether_connector.cc
+++ b/chromeos/components/tether/tether_connector.cc
@@ -147,8 +147,7 @@
 
   PA_LOG(INFO) << "Received successful ConnectTetheringResponse from device "
                << "with ID " << remote_device.GetTruncatedDeviceIdForLogs()
-               << ". SSID: \"" << ssid << "\", Password: \"" << password
-               << "\"";
+               << ". SSID: \"" << ssid << "\".";
 
   // Make a copy of the device ID, SSID, and password to pass below before
   // destroying |connect_tethering_operation_|.
diff --git a/chromeos/dbus/cryptohome_client.cc b/chromeos/dbus/cryptohome_client.cc
index c683b86..ccae843 100644
--- a/chromeos/dbus/cryptohome_client.cc
+++ b/chromeos/dbus/cryptohome_client.cc
@@ -399,11 +399,9 @@
     dbus::MessageWriter writer(&method_call);
     writer.AppendString(cryptohome_id.id());
     proxy_->CallMethod(
-        &method_call, kTpmDBusTimeoutMs ,
-        base::Bind(
-            &CryptohomeClientImpl::OnPkcs11GetTpmTokenInfoForUser,
-            weak_ptr_factory_.GetWeakPtr(),
-            callback));
+        &method_call, kTpmDBusTimeoutMs,
+        base::Bind(&CryptohomeClientImpl::OnPkcs11GetTpmTokenInfo,
+                   weak_ptr_factory_.GetWeakPtr(), callback));
   }
 
   // CryptohomeClient override.
@@ -1136,7 +1134,8 @@
     callback.Run(DBUS_METHOD_CALL_SUCCESS, true, reply);
   }
 
-  // Handles responses for Pkcs11GetTpmTokenInfo.
+  // Handles responses for Pkcs11GetTpmTokenInfo and
+  // Pkcs11GetTpmTokenInfoForUser.
   void OnPkcs11GetTpmTokenInfo(const Pkcs11GetTpmTokenInfoCallback& callback,
                                dbus::Response* response) {
     if (!response) {
@@ -1146,26 +1145,6 @@
     dbus::MessageReader reader(response);
     std::string label;
     std::string user_pin;
-    if (!reader.PopString(&label) || !reader.PopString(&user_pin)) {
-      callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
-      LOG(ERROR) << "Invalid response: " << response->ToString();
-      return;
-    }
-    const int kDefaultSlot = 0;
-    callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin, kDefaultSlot);
-  }
-
-  // Handles responses for Pkcs11GetTpmTokenInfoForUser.
-  void OnPkcs11GetTpmTokenInfoForUser(
-      const Pkcs11GetTpmTokenInfoCallback& callback,
-      dbus::Response* response) {
-    if (!response) {
-      callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
-      return;
-    }
-    dbus::MessageReader reader(response);
-    std::string label;
-    std::string user_pin;
     int slot = 0;
     if (!reader.PopString(&label) || !reader.PopString(&user_pin) ||
         !reader.PopInt32(&slot)) {
diff --git a/chromeos/printing/ppd_cache.cc b/chromeos/printing/ppd_cache.cc
index 653c56bf..edda0239 100644
--- a/chromeos/printing/ppd_cache.cc
+++ b/chromeos/printing/ppd_cache.cc
@@ -27,7 +27,6 @@
 #include "net/filter/gzip_header.h"
 
 namespace chromeos {
-namespace printing {
 namespace {
 
 // Return the (full) path to the file we expect to find the given key at.
@@ -165,5 +164,4 @@
   return scoped_refptr<PpdCache>(new PpdCacheImpl(cache_base_dir));
 }
 
-}  // namespace printing
 }  // namespace chromeos
diff --git a/chromeos/printing/ppd_cache.h b/chromeos/printing/ppd_cache.h
index dfc2b6f..78b932a8 100644
--- a/chromeos/printing/ppd_cache.h
+++ b/chromeos/printing/ppd_cache.h
@@ -15,7 +15,6 @@
 #include "chromeos/chromeos_export.h"
 
 namespace chromeos {
-namespace printing {
 
 // PpdCache manages a cache of locally-stored PPD files.  At its core, it
 // operates like a persistent hash from PpdReference to files.  If you give the
@@ -62,7 +61,6 @@
   virtual ~PpdCache() {}
 };
 
-}  // namespace printing
 }  // namespace chromeos
 
 #endif  // CHROMEOS_PRINTING_PPD_CACHE_H_
diff --git a/chromeos/printing/ppd_cache_unittest.cc b/chromeos/printing/ppd_cache_unittest.cc
index dd021f3..d7d3dae 100644
--- a/chromeos/printing/ppd_cache_unittest.cc
+++ b/chromeos/printing/ppd_cache_unittest.cc
@@ -21,7 +21,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
-namespace printing {
 namespace {
 
 // This fixture just points the cache at a temporary directory for the life of
@@ -114,5 +113,4 @@
 }
 
 }  // namespace
-}  // namespace printing
 }  // namespace chromeos
diff --git a/chromeos/printing/ppd_provider.cc b/chromeos/printing/ppd_provider.cc
index 464453bb..03b6468 100644
--- a/chromeos/printing/ppd_provider.cc
+++ b/chromeos/printing/ppd_provider.cc
@@ -40,7 +40,6 @@
 #include "url/gurl.h"
 
 namespace chromeos {
-namespace printing {
 namespace {
 
 // Extract cupsFilter/cupsFilter2 filter names from the contents
@@ -1020,5 +1019,4 @@
   return scoped_refptr<PpdProvider>(new PpdProviderImpl(
       browser_locale, url_context_getter, ppd_cache, options));
 }
-}  // namespace printing
 }  // namespace chromeos
diff --git a/chromeos/printing/ppd_provider.h b/chromeos/printing/ppd_provider.h
index faf81f34..d36430d 100644
--- a/chromeos/printing/ppd_provider.h
+++ b/chromeos/printing/ppd_provider.h
@@ -20,7 +20,6 @@
 }
 
 namespace chromeos {
-namespace printing {
 
 class PpdCache;
 
@@ -137,7 +136,6 @@
   virtual ~PpdProvider() {}
 };
 
-}  // namespace printing
 }  // namespace chromeos
 
 #endif  // CHROMEOS_PRINTING_PPD_PROVIDER_H_
diff --git a/chromeos/printing/ppd_provider_unittest.cc b/chromeos/printing/ppd_provider_unittest.cc
index 1019fa1..4ae251e 100644
--- a/chromeos/printing/ppd_provider_unittest.cc
+++ b/chromeos/printing/ppd_provider_unittest.cc
@@ -26,7 +26,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
-namespace printing {
 
 namespace {
 
@@ -556,5 +555,4 @@
 }
 
 }  // namespace
-}  // namespace printing
 }  // namespace chromeos
diff --git a/chromeos/printing/printer_translator.cc b/chromeos/printing/printer_translator.cc
index 7f7499a..d933bfd9 100644
--- a/chromeos/printing/printer_translator.cc
+++ b/chromeos/printing/printer_translator.cc
@@ -80,8 +80,6 @@
 
 }  // namespace
 
-namespace printing {
-
 const char kPrinterId[] = "id";
 
 std::unique_ptr<Printer> RecommendedPrinterToPrinter(
@@ -90,7 +88,7 @@
   DCHECK(!timestamp.is_null());
 
   std::string id;
-  if (!pref.GetString(printing::kPrinterId, &id)) {
+  if (!pref.GetString(kPrinterId, &id)) {
     LOG(WARNING) << "Record id required";
     return nullptr;
   }
@@ -117,5 +115,4 @@
   return printer;
 }
 
-}  // namespace printing
 }  // namespace chromeos
diff --git a/chromeos/printing/printer_translator.h b/chromeos/printing/printer_translator.h
index a3730671..8ae60fa 100644
--- a/chromeos/printing/printer_translator.h
+++ b/chromeos/printing/printer_translator.h
@@ -16,7 +16,6 @@
 }
 
 namespace chromeos {
-namespace printing {
 
 CHROMEOS_EXPORT extern const char kPrinterId[];
 
@@ -26,7 +25,6 @@
     const base::DictionaryValue& pref,
     const base::Time& timestamp);
 
-}  // namespace printing
 }  // namespace chromeos
 
 #endif  // CHROMEOS_PRINTING_PRINTER_TRANSLATOR_H_
diff --git a/chromeos/printing/printer_translator_unittest.cc b/chromeos/printing/printer_translator_unittest.cc
index 0723be1..22393ec2e 100644
--- a/chromeos/printing/printer_translator_unittest.cc
+++ b/chromeos/printing/printer_translator_unittest.cc
@@ -13,7 +13,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
-namespace printing {
 
 // Printer test data
 const char kHash[] = "ABCDEF123456";
@@ -161,5 +160,4 @@
   EXPECT_EQ(kMake, printer->make_and_model());
 }
 
-}  // namespace printing
 }  // namespace chromeos
diff --git a/chromeos/printing/printing_constants.h b/chromeos/printing/printing_constants.h
index 65e3229..1ea5716 100644
--- a/chromeos/printing/printing_constants.h
+++ b/chromeos/printing/printing_constants.h
@@ -6,14 +6,12 @@
 #define CHROMEOS_PRINTING_PRINTING_CONSTANTS_H_
 
 namespace chromeos {
-namespace printing {
 
 // Maximum size of a PPD file that we will accept, currently 250k.  This number
 // is relatively
 // arbitrary, we just don't want to try to handle ridiculously huge files.
 constexpr size_t kMaxPpdSizeBytes = 250 * 1024;
 
-}  // namespace printing
 }  // namespace chromeos
 
 #endif  // CHROMEOS_PRINTING_PRINTING_CONSTANTS_H_
diff --git a/components/arc/volume_mounter/arc_volume_mounter_bridge.cc b/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
index 4c54099d..d34a0c2b 100644
--- a/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
+++ b/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
@@ -6,9 +6,11 @@
 
 #include "base/bind.h"
 #include "base/logging.h"
+#include "base/memory/singleton.h"
 #include "base/task_scheduler/post_task.h"
 #include "chromeos/disks/disk_mount_manager.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 
 using chromeos::disks::DiskMountManager;
 
@@ -25,18 +27,49 @@
   }
 }
 
+// Singleton factory for ArcVolumeMounterBridge.
+class ArcVolumeMounterBridgeFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          ArcVolumeMounterBridge,
+          ArcVolumeMounterBridgeFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName = "ArcVolumeMounterBridgeFactory";
+
+  static ArcVolumeMounterBridgeFactory* GetInstance() {
+    return base::Singleton<ArcVolumeMounterBridgeFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<ArcVolumeMounterBridgeFactory>;
+  ArcVolumeMounterBridgeFactory() = default;
+  ~ArcVolumeMounterBridgeFactory() override = default;
+};
+
 }  // namespace
 
-ArcVolumeMounterBridge::ArcVolumeMounterBridge(ArcBridgeService* bridge_service)
-    : ArcService(bridge_service) {
-  arc_bridge_service()->volume_mounter()->AddObserver(this);
+// static
+ArcVolumeMounterBridge* ArcVolumeMounterBridge::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return ArcVolumeMounterBridgeFactory::GetForBrowserContext(context);
+}
+
+ArcVolumeMounterBridge::ArcVolumeMounterBridge(content::BrowserContext* context,
+                                               ArcBridgeService* bridge_service)
+    : arc_bridge_service_(bridge_service) {
+  arc_bridge_service_->volume_mounter()->AddObserver(this);
   DCHECK(DiskMountManager::GetInstance());
   DiskMountManager::GetInstance()->AddObserver(this);
 }
 
 ArcVolumeMounterBridge::~ArcVolumeMounterBridge() {
   DiskMountManager::GetInstance()->RemoveObserver(this);
-  arc_bridge_service()->volume_mounter()->RemoveObserver(this);
+  // TODO(hidehiko): Currently, the lifetime of ArcBridgeService and
+  // BrowserContextKeyedService is not nested.
+  // If ArcServiceManager::Get() returns nullptr, it is already destructed,
+  // so do not touch it.
+  if (ArcServiceManager::Get())
+    arc_bridge_service_->volume_mounter()->RemoveObserver(this);
 }
 
 void ArcVolumeMounterBridge::OnInstanceReady() {
@@ -94,7 +127,7 @@
   }
 
   mojom::VolumeMounterInstance* volume_mounter_instance =
-      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service()->volume_mounter(),
+      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->volume_mounter(),
                                   OnMountEvent);
 
   if (!volume_mounter_instance)
diff --git a/components/arc/volume_mounter/arc_volume_mounter_bridge.h b/components/arc/volume_mounter/arc_volume_mounter_bridge.h
index c5990064..ae57e7a 100644
--- a/components/arc/volume_mounter/arc_volume_mounter_bridge.h
+++ b/components/arc/volume_mounter/arc_volume_mounter_bridge.h
@@ -9,11 +9,15 @@
 
 #include "base/macros.h"
 #include "chromeos/disks/disk_mount_manager.h"
-#include "components/arc/arc_service.h"
 #include "components/arc/common/volume_mounter.mojom.h"
 #include "components/arc/instance_holder.h"
+#include "components/keyed_service/core/keyed_service.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
+namespace content {
+class BrowserContext;
+}  // namespace content
+
 namespace arc {
 
 class ArcBridgeService;
@@ -21,11 +25,17 @@
 // This class handles Volume mount/unmount requests from cros-disks and
 // send them to Android.
 class ArcVolumeMounterBridge
-    : public ArcService,
+    : public KeyedService,
       public chromeos::disks::DiskMountManager::Observer,
       public InstanceHolder<mojom::VolumeMounterInstance>::Observer {
  public:
-  explicit ArcVolumeMounterBridge(ArcBridgeService* bridge_service);
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static ArcVolumeMounterBridge* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  ArcVolumeMounterBridge(content::BrowserContext* context,
+                         ArcBridgeService* bridge_service);
   ~ArcVolumeMounterBridge() override;
 
   // InstanceHolder<mojom::VolumeMounterInstance>::Observer overrides:
@@ -46,6 +56,8 @@
                      const std::string& device_path) override;
 
  private:
+  ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
+
   DISALLOW_COPY_AND_ASSIGN(ArcVolumeMounterBridge);
 };
 
diff --git a/components/download/content/internal/download_driver_impl.cc b/components/download/content/internal/download_driver_impl.cc
index 74b7c801..99686e18 100644
--- a/components/download/content/internal/download_driver_impl.cc
+++ b/components/download/content/internal/download_driver_impl.cc
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/download/internal/driver_entry.h"
 #include "content/public/browser/download_interrupt_reasons.h"
@@ -58,6 +59,12 @@
   }
 }
 
+// Logs interrupt reason when download fails.
+void LogDownloadInterruptReason(content::DownloadInterruptReason reason) {
+  UMA_HISTOGRAM_SPARSE_SLOWLY("Download.Service.Driver.InterruptReason",
+                              reason);
+}
+
 }  // namespace
 
 // static
@@ -228,6 +235,7 @@
     client_->OnDownloadUpdated(entry);
   } else if (reason !=
              content::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE) {
+    LogDownloadInterruptReason(reason);
     client_->OnDownloadFailed(entry, FailureTypeFromInterruptReason(reason));
   }
 }
diff --git a/components/download/internal/controller.h b/components/download/internal/controller.h
index fac0be40..6d6d30c1 100644
--- a/components/download/internal/controller.h
+++ b/components/download/internal/controller.h
@@ -33,6 +33,8 @@
   UNKNOWN = 4,
   // The download is cancelled by the client.
   CANCEL = 5,
+  // The count of entries for the enum.
+  COUNT = 6,
 };
 
 // The core Controller responsible for gluing various DownloadService components
diff --git a/components/download/internal/controller_impl.cc b/components/download/internal/controller_impl.cc
index 97f24f4c..5489bcb 100644
--- a/components/download/internal/controller_impl.cc
+++ b/components/download/internal/controller_impl.cc
@@ -326,6 +326,7 @@
   using ShouldDownload = download::Client::ShouldDownload;
   ShouldDownload should_download = client->OnDownloadStarted(
       download.guid, download.url_chain, download.response_headers);
+  stats::LogStartDownloadResponse(entry->client, should_download);
   if (should_download == ShouldDownload::ABORT) {
     HandleCompleteDownload(CompletionType::ABORT, entry->guid);
   }
@@ -640,6 +641,9 @@
             driver_->Remove(entry->guid);
         }
         break;
+      case Entry::State::COUNT:
+        NOTREACHED();
+        break;
     }
   }
 }
@@ -754,20 +758,24 @@
                                             const std::string& guid) {
   Entry* entry = model_->Get(guid);
   DCHECK(entry);
-  stats::LogDownloadCompletion(type, entry->attempt_count);
 
   if (entry->state == Entry::State::COMPLETE) {
     DVLOG(1) << "Download is already completed.";
     return;
   }
 
+  auto driver_entry = driver_->Find(guid);
+  uint64_t file_size =
+      driver_entry.has_value() ? driver_entry->bytes_downloaded : 0;
+  stats::LogDownloadCompletion(
+      type, entry->completion_time - entry->create_time, file_size);
+
   if (type == CompletionType::SUCCEED) {
-    auto driver_entry = driver_->Find(guid);
     DCHECK(driver_entry.has_value());
-    if (driver_entry->current_file_path != entry->target_file_path) {
-      stats::LogFilePathsAreStrangelyDifferent();
-      entry->target_file_path = driver_entry->current_file_path;
-    }
+    stats::LogFilePathRenamed(driver_entry->current_file_path !=
+                              entry->target_file_path);
+    entry->target_file_path = driver_entry->current_file_path;
+
     entry->completion_time = driver_entry->completion_time;
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE, base::Bind(&ControllerImpl::SendOnDownloadSucceeded,
diff --git a/components/download/internal/controller_impl_unittest.cc b/components/download/internal/controller_impl_unittest.cc
index 7abc8b7..65dc396 100644
--- a/components/download/internal/controller_impl_unittest.cc
+++ b/components/download/internal/controller_impl_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
+#include "base/test/histogram_tester.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/download/internal/client_set.h"
@@ -206,6 +207,7 @@
 
 TEST_F(DownloadServiceControllerImplTest, SuccessfulInitModelFirst) {
   EXPECT_CALL(*client_, OnServiceInitialized(_)).Times(0);
+  base::HistogramTester histogram_tester;
 
   InitializeController();
   EXPECT_TRUE(store_->init_called());
@@ -226,6 +228,11 @@
   EXPECT_TRUE(controller_->GetStartupStatus()->Ok());
 
   task_runner_->RunUntilIdle();
+
+  histogram_tester.ExpectBucketCount(
+      "Download.Service.StartUpStatus",
+      static_cast<base::HistogramBase::Sample>(stats::StartUpResult::SUCCESS),
+      1);
 }
 
 TEST_F(DownloadServiceControllerImplTest, SuccessfulInitDriverFirst) {
@@ -322,6 +329,7 @@
 }
 
 TEST_F(DownloadServiceControllerImplTest, FailedInitWithBadModel) {
+  base::HistogramTester histogram_tester;
   EXPECT_CALL(*client_, OnServiceInitialized(_)).Times(0);
   EXPECT_CALL(*client_, OnServiceUnavailable()).Times(1);
 
@@ -330,6 +338,17 @@
   driver_->MakeReady();
 
   task_runner_->RunUntilIdle();
+  histogram_tester.ExpectBucketCount(
+      "Download.Service.StartUpStatus",
+      static_cast<base::HistogramBase::Sample>(stats::StartUpResult::FAILURE),
+      1);
+  histogram_tester.ExpectBucketCount(
+      "Download.Service.StartUpStatus",
+      static_cast<base::HistogramBase::Sample>(
+          stats::StartUpResult::FAILURE_REASON_MODEL),
+      1);
+
+  histogram_tester.ExpectTotalCount("Download.Service.StartUpStatus", 2);
 }
 
 TEST_F(DownloadServiceControllerImplTest, GetOwnerOfDownload) {
diff --git a/components/download/internal/download_service_impl.cc b/components/download/internal/download_service_impl.cc
index e2ba3bfc..bf75aba5 100644
--- a/components/download/internal/download_service_impl.cc
+++ b/components/download/internal/download_service_impl.cc
@@ -71,7 +71,7 @@
   stats::LogServiceApiAction(download_params.client,
                              stats::ServiceApiAction::START_DOWNLOAD);
   DCHECK_EQ(download_params.guid, base::ToUpperASCII(download_params.guid));
-
+  stats::LogDownloadParams(download_params);
   if (startup_completed_) {
     controller_->StartDownload(download_params);
   } else {
diff --git a/components/download/internal/download_service_impl_unittest.cc b/components/download/internal/download_service_impl_unittest.cc
index 5bda4402..efeaecd 100644
--- a/components/download/internal/download_service_impl_unittest.cc
+++ b/components/download/internal/download_service_impl_unittest.cc
@@ -9,9 +9,11 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
+#include "base/test/histogram_tester.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/download/internal/startup_status.h"
+#include "components/download/internal/stats.h"
 #include "components/download/internal/test/download_params_utils.h"
 #include "components/download/internal/test/mock_controller.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -84,7 +86,32 @@
   EXPECT_CALL(*controller_, CancelDownload(params.guid)).Times(0);
   EXPECT_CALL(*controller_, ChangeDownloadCriteria(params.guid, _)).Times(0);
 
-  service_->StartDownload(params);
+  {
+    base::HistogramTester histogram_tester;
+
+    service_->StartDownload(params);
+
+    histogram_tester.ExpectBucketCount(
+        "Download.Service.Request.ClientAction",
+        static_cast<base::HistogramBase::Sample>(
+            stats::ServiceApiAction::START_DOWNLOAD),
+        1);
+    histogram_tester.ExpectBucketCount(
+        "Download.Service.Request.ClientAction.__Test__",
+        static_cast<base::HistogramBase::Sample>(
+            stats::ServiceApiAction::START_DOWNLOAD),
+        1);
+    histogram_tester.ExpectBucketCount(
+        "Download.Service.Request.BatteryRequirement",
+        static_cast<base::HistogramBase::Sample>(
+            params.scheduling_params.battery_requirements),
+        1);
+
+    histogram_tester.ExpectTotalCount("Download.Service.Request.ClientAction",
+                                      1);
+    histogram_tester.ExpectTotalCount(
+        "Download.Service.Request.ClientAction.__Test__", 1);
+  }
   service_->PauseDownload(params.guid);
   service_->ResumeDownload(params.guid);
   service_->CancelDownload(params.guid);
diff --git a/components/download/internal/entry.h b/components/download/internal/entry.h
index a04f456e..2076631 100644
--- a/components/download/internal/entry.h
+++ b/components/download/internal/entry.h
@@ -36,6 +36,9 @@
     // The download is 'complete' and successful.  At this point we are leaving
     // this entry around to make sure the files on disk are cleaned up.
     COMPLETE = 4,
+
+    // The count of entries for the enum.
+    COUNT = 5,
   };
 
   Entry();
diff --git a/components/download/internal/file_monitor_impl.cc b/components/download/internal/file_monitor_impl.cc
index cf0d57b7..639db4b9 100644
--- a/components/download/internal/file_monitor_impl.cc
+++ b/components/download/internal/file_monitor_impl.cc
@@ -10,6 +10,7 @@
 #include "base/files/file_util.h"
 #include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
+#include "base/sys_info.h"
 #include "base/task_runner_util.h"
 #include "base/threading/thread_restrictions.h"
 
@@ -17,12 +18,63 @@
 
 namespace {
 
-bool CreateDirectoryIfNotExists(const base::FilePath& dir_path) {
+// Helper function to calculate total file size in a directory, the total
+// disk space and free disk space of the volume that contains that directory.
+// Returns false if failed to query disk space or total disk space is empty.
+bool CalculateDiskUtilization(const base::FilePath& file_dir,
+                              int64_t& total_disk_space,
+                              int64_t& free_disk_space,
+                              int64_t& files_size) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  base::FileEnumerator file_enumerator(file_dir, false /* recursive */,
+                                       base::FileEnumerator::FILES);
+
+  int64_t size = 0;
+  // Compute the total size of all files in |file_dir|.
+  for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
+       path = file_enumerator.Next()) {
+    if (!base::GetFileSize(path, &size)) {
+      DVLOG(1) << "File size query failed.";
+      return false;
+    }
+    files_size += size;
+  }
+
+  // Disk space of the volume that |file_dir| belongs to.
+  total_disk_space = base::SysInfo::AmountOfTotalDiskSpace(file_dir);
+  free_disk_space = base::SysInfo::AmountOfFreeDiskSpace(file_dir);
+  if (total_disk_space == -1 || free_disk_space == -1) {
+    DVLOG(1) << "System disk space query failed.";
+    return false;
+  }
+
+  if (total_disk_space == 0) {
+    DVLOG(1) << "Empty total system disk space.";
+    return false;
+  }
+  return true;
+}
+
+// Creates the download directory if it doesn't exist.
+bool InitializeAndCreateDownloadDirectory(const base::FilePath& dir_path) {
+  // Create the download directory.
   bool success = base::PathExists(dir_path);
   if (!success) {
-    base::File::Error error;
+    base::File::Error error = base::File::Error::FILE_OK;
     success = base::CreateDirectoryAndGetError(dir_path, &error);
+    if (!success)
+      stats::LogsFileDirectoryCreationError(error);
   }
+  // Records disk utilization histograms.
+  if (success) {
+    int64_t files_size = 0, total_disk_space = 0, free_disk_space = 0;
+    if (CalculateDiskUtilization(dir_path, total_disk_space, free_disk_space,
+                                 files_size)) {
+      stats::LogFileDirDiskUtilization(total_disk_space, free_disk_space,
+                                       files_size);
+    }
+  }
+
   return success;
 }
 
@@ -81,7 +133,7 @@
   GetFilesInDirectory(directory, files_in_dir);
   DeleteFilesOnFileThread(files_in_dir,
                           stats::FileCleanupReason::HARD_RECOVERY);
-  return CreateDirectoryIfNotExists(directory);
+  return InitializeAndCreateDownloadDirectory(directory);
 }
 
 }  // namespace
@@ -100,7 +152,8 @@
 void FileMonitorImpl::Initialize(const InitCallback& callback) {
   base::PostTaskAndReplyWithResult(
       file_thread_task_runner_.get(), FROM_HERE,
-      base::Bind(&CreateDirectoryIfNotExists, download_file_dir_), callback);
+      base::Bind(&InitializeAndCreateDownloadDirectory, download_file_dir_),
+      callback);
 }
 
 void FileMonitorImpl::DeleteUnknownFiles(
@@ -131,6 +184,10 @@
 
     entries_to_remove.push_back(entry);
     files_to_remove.insert(entry->target_file_path);
+
+    // TODO(xingliu): Consider logs life time after the file being deleted on
+    // the file thread.
+    stats::LogFileLifeTime(base::Time::Now() - entry->completion_time);
   }
 
   file_thread_task_runner_->PostTaskAndReply(
diff --git a/components/download/internal/model_impl.cc b/components/download/internal/model_impl.cc
index 2a7a2cd1..1eee678 100644
--- a/components/download/internal/model_impl.cc
+++ b/components/download/internal/model_impl.cc
@@ -4,6 +4,8 @@
 
 #include "components/download/internal/model_impl.h"
 
+#include <map>
+
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "components/download/internal/entry.h"
@@ -96,10 +98,13 @@
     return;
   }
 
+  std::map<Entry::State, uint32_t> entries_count;
   for (const auto& entry : *entries) {
+    entries_count[entry.state]++;
     entries_.emplace(entry.guid, base::MakeUnique<Entry>(entry));
   }
 
+  stats::LogEntries(entries_count);
   client_->OnModelReady(true);
 }
 
diff --git a/components/download/internal/model_impl_unittest.cc b/components/download/internal/model_impl_unittest.cc
index 4e036bf..2367ac27 100644
--- a/components/download/internal/model_impl_unittest.cc
+++ b/components/download/internal/model_impl_unittest.cc
@@ -11,7 +11,9 @@
 #include "base/guid.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
+#include "base/test/histogram_tester.h"
 #include "components/download/internal/entry.h"
+#include "components/download/internal/stats.h"
 #include "components/download/internal/test/entry_utils.h"
 #include "components/download/internal/test/mock_model_client.h"
 #include "components/download/internal/test/test_store.h"
@@ -63,6 +65,7 @@
   Entry entry2 = test::BuildBasicEntry();
   std::vector<Entry> entries = {entry1, entry2};
 
+  base::HistogramTester histogram_tester;
   InSequence sequence;
   EXPECT_CALL(client_, OnModelReady(true)).Times(1);
 
@@ -72,6 +75,18 @@
 
   EXPECT_TRUE(test::CompareEntry(&entry1, model_->Get(entry1.guid)));
   EXPECT_TRUE(test::CompareEntry(&entry2, model_->Get(entry2.guid)));
+
+  // Verify histograms.
+  histogram_tester.ExpectBucketCount("Download.Service.Db.Records", 2, 1);
+  histogram_tester.ExpectBucketCount("Download.Service.Db.Records.New", 2, 1);
+  histogram_tester.ExpectBucketCount("Download.Service.Db.Records.Available", 0,
+                                     1);
+  histogram_tester.ExpectBucketCount("Download.Service.Db.Records.Active", 0,
+                                     1);
+  histogram_tester.ExpectBucketCount("Download.Service.Db.Records.Paused", 0,
+                                     1);
+  histogram_tester.ExpectBucketCount("Download.Service.Db.Records.Complete", 0,
+                                     1);
 }
 
 TEST_F(DownloadServiceModelImplTest, BadInit) {
diff --git a/components/download/internal/proto_conversions.cc b/components/download/internal/proto_conversions.cc
index bbb745a6..f78f521 100644
--- a/components/download/internal/proto_conversions.cc
+++ b/components/download/internal/proto_conversions.cc
@@ -23,6 +23,8 @@
       return protodb::Entry_State_PAUSED;
     case Entry::State::COMPLETE:
       return protodb::Entry_State_COMPLETE;
+    case Entry::State::COUNT:
+      break;
   }
 
   NOTREACHED();
@@ -116,6 +118,8 @@
       return protodb::SchedulingParams_NetworkRequirements_OPTIMISTIC;
     case SchedulingParams::NetworkRequirements::UNMETERED:
       return protodb::SchedulingParams_NetworkRequirements_UNMETERED;
+    case SchedulingParams::NetworkRequirements::COUNT:
+      break;
   }
 
   NOTREACHED();
@@ -144,6 +148,8 @@
       return protodb::SchedulingParams_BatteryRequirements_BATTERY_INSENSITIVE;
     case SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE:
       return protodb::SchedulingParams_BatteryRequirements_BATTERY_SENSITIVE;
+    case SchedulingParams::BatteryRequirements::COUNT:
+      break;
   }
 
   NOTREACHED();
@@ -178,6 +184,8 @@
       return protodb::SchedulingParams_Priority_HIGH;
     case SchedulingParams::Priority::UI:
       return protodb::SchedulingParams_Priority_UI;
+    case SchedulingParams::Priority::COUNT:
+      break;
   }
 
   NOTREACHED();
diff --git a/components/download/internal/stats.cc b/components/download/internal/stats.cc
index 8fe85e9c..96d33b5 100644
--- a/components/download/internal/stats.cc
+++ b/components/download/internal/stats.cc
@@ -4,58 +4,300 @@
 
 #include "components/download/internal/stats.h"
 
+#include <map>
+
+#include "base/files/file_enumerator.h"
+#include "base/files/file_util.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
 #include "components/download/internal/startup_status.h"
 
 namespace download {
 namespace stats {
+namespace {
+
+// The maximum tracked file size in KB, larger files will fall into overflow
+// bucket.
+const int64_t kMaxFileSizeKB = 4 * 1024 * 1024; /* 4GB */
+
+// Converts DownloadTaskType to histogram suffix.
+// Should maps to suffix string in histograms.xml.
+std::string TaskTypeToHistogramSuffix(DownloadTaskType task_type) {
+  switch (task_type) {
+    case DownloadTaskType::DOWNLOAD_TASK:
+      return "DownloadTask";
+    case DownloadTaskType::CLEANUP_TASK:
+      return "CleanUpTask";
+  }
+  NOTREACHED();
+  return std::string();
+}
+
+// Converts Entry::State to histogram suffix.
+// Should maps to suffix string in histograms.xml.
+std::string EntryStateToHistogramSuffix(Entry::State state) {
+  std::string suffix;
+  switch (state) {
+    case Entry::State::NEW:
+      return "New";
+    case Entry::State::AVAILABLE:
+      return "Available";
+    case Entry::State::ACTIVE:
+      return "Active";
+    case Entry::State::PAUSED:
+      return "Paused";
+    case Entry::State::COMPLETE:
+      return "Complete";
+    case Entry::State::COUNT:
+      break;
+  }
+  NOTREACHED();
+  return std::string();
+}
+
+// Converts DownloadClient to histogram suffix.
+// Should maps to suffix string in histograms.xml.
+std::string ClientToHistogramSuffix(DownloadClient client) {
+  switch (client) {
+    case DownloadClient::TEST:
+    case DownloadClient::TEST_2:
+    case DownloadClient::TEST_3:
+    case DownloadClient::INVALID:
+      return "__Test__";
+    case DownloadClient::OFFLINE_PAGE_PREFETCH:
+      return "OfflinePage";
+    case DownloadClient::BOUNDARY:
+      NOTREACHED();
+      break;
+  }
+  NOTREACHED();
+  return std::string();
+}
+
+// Converts CompletionType to histogram suffix.
+// Should maps to suffix string in histograms.xml.
+std::string CompletionTypeToHistogramSuffix(CompletionType type) {
+  switch (type) {
+    case CompletionType::SUCCEED:
+      return "Succeed";
+    case CompletionType::FAIL:
+      return "Fail";
+    case CompletionType::ABORT:
+      return "Abort";
+    case CompletionType::TIMEOUT:
+      return "Timeout";
+    case CompletionType::UNKNOWN:
+      return "Unknown";
+    case CompletionType::CANCEL:
+      return "Cancel";
+    case CompletionType::COUNT:
+      NOTREACHED();
+  }
+  NOTREACHED();
+  return std::string();
+}
+
+// Converts FileCleanupReason to histogram suffix.
+// Should maps to suffix string in histograms.xml.
+std::string FileCleanupReasonToHistogramSuffix(FileCleanupReason reason) {
+  switch (reason) {
+    case FileCleanupReason::TIMEOUT:
+      return "Timeout";
+    case FileCleanupReason::ORPHANED:
+      return "Orphaned";
+    case FileCleanupReason::UNKNOWN:
+      return "Unknown";
+    case FileCleanupReason::HARD_RECOVERY:
+      return "HardRecovery";
+    case FileCleanupReason::COUNT:
+      NOTREACHED();
+  }
+  NOTREACHED();
+  return std::string();
+}
+
+// Helper method to log StartUpResult.
+void LogStartUpResult(StartUpResult result) {
+  base::UmaHistogramEnumeration("Download.Service.StartUpStatus", result,
+                                StartUpResult::COUNT);
+}
+
+// Helper method to log the number of entries under a particular state.
+void LogDatabaseRecords(Entry::State state, uint32_t record_count) {
+  std::string name("Download.Service.Db.Records");
+  name.append(".").append(EntryStateToHistogramSuffix(state));
+  base::UmaHistogramCustomCounts(name, record_count, 1, 500, 50);
+}
+
+}  // namespace
 
 void LogControllerStartupStatus(const StartupStatus& status) {
   DCHECK(status.Complete());
 
-  // TODO(dtrainor): Log each failure reason.
-  // TODO(dtrainor): Finally, log SUCCESS or FAILURE based on status.Ok().
+  // Total counts for general success/failure rate.
+  LogStartUpResult(status.Ok() ? StartUpResult::SUCCESS
+                               : StartUpResult::FAILURE);
+
+  // Failure reasons.
+  if (!status.driver_ok.value())
+    LogStartUpResult(StartUpResult::FAILURE_REASON_DRIVER);
+  if (!status.model_ok.value())
+    LogStartUpResult(StartUpResult::FAILURE_REASON_MODEL);
+  if (!status.file_monitor_ok.value())
+    LogStartUpResult(StartUpResult::FAILURE_REASON_FILE_MONITOR);
 }
 
 void LogServiceApiAction(DownloadClient client, ServiceApiAction action) {
-  // TODO(dtrainor): Log |action| for |client|.
+  // Total count for each action.
+  std::string name("Download.Service.Request.ClientAction");
+  base::UmaHistogramEnumeration(name, action, ServiceApiAction::COUNT);
+
+  // Total count for each action with client suffix.
+  name.append(".").append(ClientToHistogramSuffix(client));
+  base::UmaHistogramEnumeration(name, action, ServiceApiAction::COUNT);
 }
 
 void LogStartDownloadResult(DownloadClient client,
                             DownloadParams::StartResult result) {
-  // TODO(dtrainor): Log |result| for |client|.
+  // Total count for each start result.
+  std::string name("Download.Service.Request.StartResult");
+  base::UmaHistogramEnumeration(name, result,
+                                DownloadParams::StartResult::COUNT);
+
+  // Total count for each client result with client suffix.
+  name.append(".").append(ClientToHistogramSuffix(client));
+  base::UmaHistogramEnumeration(name, result,
+                                DownloadParams::StartResult::COUNT);
+}
+
+void LogStartDownloadResponse(DownloadClient client,
+                              Client::ShouldDownload should_download) {
+  // Total count for each start response.
+  std::string name("Download.Service.Request.StartResponse");
+  base::UmaHistogramEnumeration(name, should_download,
+                                Client::ShouldDownload::COUNT);
+
+  // Total count for each client response with client suffix.
+  name.append(".").append(ClientToHistogramSuffix(client));
+  base::UmaHistogramEnumeration(name, should_download,
+                                Client::ShouldDownload::COUNT);
+}
+
+void LogDownloadParams(const DownloadParams& params) {
+  UMA_HISTOGRAM_ENUMERATION("Download.Service.Request.BatteryRequirement",
+                            params.scheduling_params.battery_requirements,
+                            SchedulingParams::BatteryRequirements::COUNT);
+  UMA_HISTOGRAM_ENUMERATION("Download.Service.Request.NetworkRequirement",
+                            params.scheduling_params.network_requirements,
+                            SchedulingParams::NetworkRequirements::COUNT);
+  UMA_HISTOGRAM_ENUMERATION("Download.Service.Request.Priority",
+                            params.scheduling_params.priority,
+                            SchedulingParams::Priority::COUNT);
+}
+
+void LogRecoveryOperation(Entry::State to_state) {
+  UMA_HISTOGRAM_ENUMERATION("Download.Service.Recovery", to_state,
+                            Entry::State::COUNT);
+}
+
+void LogDownloadCompletion(CompletionType type,
+                           const base::TimeDelta& time_span,
+                           uint64_t file_size_bytes) {
+  // Records completion type.
+  UMA_HISTOGRAM_ENUMERATION("Download.Service.Finish.Type", type,
+                            CompletionType::COUNT);
+
+  // TODO(xingliu): Use DownloadItem::GetStartTime and DownloadItem::GetEndTime
+  // to record the completion time to histogram "Download.Service.Finish.Time".
+  // Also propagates and records the mime type here.
+
+  // Records the file size.
+  std::string name("Download.Service.Finish.FileSize");
+  uint64_t file_size_kb = file_size_bytes / 1024;
+  base::UmaHistogramCustomCounts(name, file_size_kb, 1, kMaxFileSizeKB, 50);
+
+  name.append(".").append(CompletionTypeToHistogramSuffix(type));
+  base::UmaHistogramCustomCounts(name, file_size_kb, 1, kMaxFileSizeKB, 50);
 }
 
 void LogModelOperationResult(ModelAction action, bool success) {
-  // TODO(dtrainor): Log |action|.
+  if (success) {
+    UMA_HISTOGRAM_ENUMERATION("Download.Service.Db.Operation.Success", action,
+                              ModelAction::COUNT);
+  } else {
+    UMA_HISTOGRAM_ENUMERATION("Download.Service.Db.Operation.Failure", action,
+                              ModelAction::COUNT);
+  }
+}
+
+void LogEntries(std::map<Entry::State, uint32_t>& entries_count) {
+  uint32_t total_records = 0;
+  for (const auto& entry_count : entries_count)
+    total_records += entry_count.second;
+
+  // Total number of records in database.
+  base::UmaHistogramCustomCounts("Download.Service.Db.Records", total_records,
+                                 1, 500, 50);
+
+  // Number of records for each Entry::State.
+  for (Entry::State state = Entry::State::NEW; state != Entry::State::COUNT;
+       state = (Entry::State)((int)(state) + 1)) {
+    LogDatabaseRecords(state, entries_count[state]);
+  }
 }
 
 void LogScheduledTaskStatus(DownloadTaskType task_type,
                             ScheduledTaskStatus status) {
-  // TODO(shaktisahu): Log |task_type| and |status|.
+  std::string name("Download.Service.TaskScheduler.Status");
+  base::UmaHistogramEnumeration(name, status, ScheduledTaskStatus::COUNT);
+
+  name.append(".").append(TaskTypeToHistogramSuffix(task_type));
+  base::UmaHistogramEnumeration(name, status, ScheduledTaskStatus::COUNT);
 }
 
-void LogDownloadCompletion(CompletionType type, unsigned int attempt_count) {
-  // TODO(xingliu): Log completion.
-}
-
-void LogRecoveryOperation(Entry::State to_state) {
-  // TODO(dtrainor): Log |to_state|.
+void LogsFileDirectoryCreationError(base::File::Error error) {
+  // Maps to histogram enum PlatformFileError.
+  UMA_HISTOGRAM_ENUMERATION("Download.Service.Files.DirCreationError", -error,
+                            -base::File::Error::FILE_ERROR_MAX);
 }
 
 void LogFileCleanupStatus(FileCleanupReason reason,
-                          int attempted_cleanups,
+                          int succeeded_cleanups,
                           int failed_cleanups,
                           int external_cleanups) {
-  DCHECK_NE(FileCleanupReason::EXTERNAL, reason);
-  // TODO(shaktisahu): Log |status| and |count|.
+  std::string name("Download.Service.Files.CleanUp.Success");
+  base::UmaHistogramCounts100(name, succeeded_cleanups);
+  name.append(".").append(FileCleanupReasonToHistogramSuffix(reason));
+  base::UmaHistogramCounts100(name, succeeded_cleanups);
+
+  name = "Download.Service.Files.CleanUp.Failure";
+  base::UmaHistogramCounts100(name, failed_cleanups);
+  name.append(".").append(FileCleanupReasonToHistogramSuffix(reason));
+  base::UmaHistogramCounts100(name, failed_cleanups);
+
+  name = "Download.Service.Files.CleanUp.External";
+  base::UmaHistogramCounts100(name, external_cleanups);
+  name.append(".").append(FileCleanupReasonToHistogramSuffix(reason));
+  base::UmaHistogramCounts100(name, external_cleanups);
 }
 
-void LogFileDeletionFailed(int count) {
-  // TODO(shaktisahu): Log |count|.
+void LogFileLifeTime(const base::TimeDelta& file_life_time) {
+  UMA_HISTOGRAM_CUSTOM_TIMES("Download.Service.Files.LifeTime", file_life_time,
+                             base::TimeDelta::FromSeconds(1),
+                             base::TimeDelta::FromDays(8), 100);
 }
 
-void LogFilePathsAreStrangelyDifferent() {
-  // TODO(shaktisahu): Log this occurrence.
+void LogFileDirDiskUtilization(int64_t total_disk_space,
+                               int64_t free_disk_space,
+                               int64_t files_size) {
+  UMA_HISTOGRAM_PERCENTAGE("Download.Service.Files.FreeDiskSpace",
+                           (free_disk_space * 100) / total_disk_space);
+  UMA_HISTOGRAM_PERCENTAGE("Download.Service.Files.DiskUsed",
+                           (files_size * 100) / total_disk_space);
+}
+
+void LogFilePathRenamed(bool renamed) {
+  UMA_HISTOGRAM_BOOLEAN("Download.Service.Files.PathRenamed", renamed);
 }
 
 }  // namespace stats
diff --git a/components/download/internal/stats.h b/components/download/internal/stats.h
index 332b2936..c3bad31e 100644
--- a/components/download/internal/stats.h
+++ b/components/download/internal/stats.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_DOWNLOAD_INTERNAL_STATS_H_
 #define COMPONENTS_DOWNLOAD_INTERNAL_STATS_H_
 
+#include "base/files/file.h"
 #include "components/download/internal/controller.h"
 #include "components/download/internal/entry.h"
 #include "components/download/public/clients.h"
@@ -22,6 +23,29 @@
 // 2. Treat them as append only.
 // 3. Do not remove any enums.  Only mark them as deprecated.
 
+// Enum used to track download service start up result and failure reasons.
+// Most of the fields should map to StartupStatus.
+// Failure reasons are not mutually exclusive.
+enum class StartUpResult {
+  // Download service successfully started.
+  SUCCESS = 0,
+
+  // Download service start up failed.
+  FAILURE = 1,
+
+  // Download driver is not ready.
+  FAILURE_REASON_DRIVER = 2,
+
+  // Database layer failed to initialized.
+  FAILURE_REASON_MODEL = 3,
+
+  // File monitor failed to start.
+  FAILURE_REASON_FILE_MONITOR = 4,
+
+  // The count of entries for the enum.
+  COUNT = 5,
+};
+
 // Enum used by UMA metrics to track which actions a Client is taking on the
 // service.
 enum class ServiceApiAction {
@@ -40,7 +64,7 @@
   // Represents a call to DownloadService::ChangeCriteria.
   CHANGE_CRITERIA = 4,
 
-  // The last entry for the enum.
+  // The count of entries for the enum.
   COUNT = 5,
 };
 
@@ -59,7 +83,7 @@
   // Represents an attempt to remove an Entry from the Model.
   REMOVE = 3,
 
-  // The last entry for the enum.
+  // The count of entries for the enum.
   COUNT = 4,
 };
 
@@ -73,6 +97,9 @@
 
   // Callback was run successfully after completion of the task.
   COMPLETED_NORMALLY = 2,
+
+  // The count of entries for the enum.
+  COUNT = 3,
 };
 
 // Enum used by UMA metrics to track various types of cleanup actions taken by
@@ -89,12 +116,11 @@
   // driver entry.
   UNKNOWN = 2,
 
-  // The file was cleaned up externally. Shouldn't be used by callers to log as
-  // it will be used only internally by the Stats class.
-  EXTERNAL = 3,
-
   // We're trying to remove all files as part of a hard recovery attempt.
-  HARD_RECOVERY = 4,
+  HARD_RECOVERY = 3,
+
+  // The count of entries for the enum.
+  COUNT = 4,
 };
 
 // Logs the results of starting up the Controller.  Will log each failure reason
@@ -108,30 +134,56 @@
 void LogStartDownloadResult(DownloadClient client,
                             DownloadParams::StartResult result);
 
-// Logs statistics about the result of a Model operation.  Used to track failure
-// cases.
-void LogModelOperationResult(ModelAction action, bool success);
+// Logs the client response to StartDownload() attempt on the service.
+void LogStartDownloadResponse(DownloadClient client,
+                              download::Client::ShouldDownload should_download);
 
-// Log statistics about the status of a TaskFinishedCallback.
-void LogScheduledTaskStatus(DownloadTaskType task_type,
-                            ScheduledTaskStatus status);
-
-// Logs download completion event.
-void LogDownloadCompletion(CompletionType type, unsigned int attempt_count);
+// Logs the download parameters when StartDownload() is called.
+void LogDownloadParams(const DownloadParams& params);
 
 // Logs recovery operations that happened when we had to move from one state
 // to another on startup.
 void LogRecoveryOperation(Entry::State to_state);
 
+// Logs download completion event, download time, and the file size.
+void LogDownloadCompletion(CompletionType type,
+                           const base::TimeDelta& time_span,
+                           uint64_t file_size_bytes);
+
+// Logs statistics about the result of a model operation.  Used to track failure
+// cases.
+void LogModelOperationResult(ModelAction action, bool success);
+
+// Logs the total number of all entries, and the number of entries in each
+// state after the model is initialized.
+void LogEntries(std::map<Entry::State, uint32_t>& entries_count);
+
+// Log statistics about the status of a TaskFinishedCallback.
+void LogScheduledTaskStatus(DownloadTaskType task_type,
+                            ScheduledTaskStatus status);
+
+// Logs download files directory creation error.
+void LogsFileDirectoryCreationError(base::File::Error error);
+
 // Logs statistics about the reasons of a file cleanup.
 void LogFileCleanupStatus(FileCleanupReason reason,
-                          int attempted_cleanups,
+                          int succeeded_cleanups,
                           int failed_cleanups,
                           int external_cleanups);
 
-// Logs the case where the final downloaded file path turned out different from
-// the file path set at the beginning.
-void LogFilePathsAreStrangelyDifferent();
+// Logs the file life time for successfully completed download.
+void LogFileLifeTime(const base::TimeDelta& file_life_time);
+
+// Logs the total disk space utilized by download files.
+// This includes the total size of all the files in |file_dir|.
+// This function is costly and should be called only once.
+void LogFileDirDiskUtilization(int64_t total_disk_space,
+                               int64_t free_disk_space,
+                               int64_t files_size);
+
+// Logs if the final download file path is different from the requested file
+// path.
+void LogFilePathRenamed(bool renamed);
 
 }  // namespace stats
 }  // namespace download
diff --git a/components/download/public/client.h b/components/download/public/client.h
index ad5de8a..46d5cfb 100644
--- a/components/download/public/client.h
+++ b/components/download/public/client.h
@@ -22,8 +22,14 @@
   // Used by OnDownloadStarted to determine whether or not the DownloadService
   // should continue downloading the file or abort the attempt.
   enum class ShouldDownload {
+    // Continue to download the file.
     CONTINUE,
+
+    // Abort the download.
     ABORT,
+
+    // The count of entries for the enum.
+    COUNT,
   };
 
   // Used by OnDownloadFailed to determine the reason of the abort.
diff --git a/components/download/public/download_params.h b/components/download/public/download_params.h
index 96245ba0..217718ef 100644
--- a/components/download/public/download_params.h
+++ b/components/download/public/download_params.h
@@ -30,6 +30,9 @@
 
     // The download can occur only if the network isn't metered.
     UNMETERED = 2,
+
+    // Last value of the enum.
+    COUNT = 3,
   };
 
   enum class BatteryRequirements {
@@ -41,6 +44,9 @@
     // The download can only occur when charging or in optimal battery
     // conditions.
     BATTERY_SENSITIVE = 1,
+
+    // Last value of the enum.
+    COUNT = 2,
   };
 
   enum class Priority {
@@ -61,6 +67,9 @@
 
     // The default priority for all tasks unless overridden.
     DEFAULT = NORMAL,
+
+    // Last value of the enum.
+    COUNT = 4,
   };
 
   SchedulingParams();
@@ -120,6 +129,8 @@
     INTERNAL_ERROR,
 
     // TODO(dtrainor): Add more error codes.
+    // The count of entries for the enum.
+    COUNT,
   };
 
   using StartCallback = base::Callback<void(const std::string&, StartResult)>;
diff --git a/components/exo/buffer.cc b/components/exo/buffer.cc
index b74684a..8b574a5 100644
--- a/components/exo/buffer.cc
+++ b/components/exo/buffer.cc
@@ -411,6 +411,7 @@
 
 bool Buffer::ProduceTransferableResource(
     LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder,
+    cc::ResourceId resource_id,
     bool secure_output_only,
     bool client_usage,
     cc::TransferableResource* resource) {
@@ -438,7 +439,7 @@
     return false;
   }
 
-  resource->id = layer_tree_frame_sink_holder->AllocateResourceId();
+  resource->id = resource_id;
   resource->format = viz::RGBA_8888;
   resource->filter = GL_LINEAR;
   resource->size = gpu_memory_buffer_->GetSize();
@@ -472,7 +473,7 @@
     // The contents texture will be released when no longer used by the
     // compositor.
     layer_tree_frame_sink_holder->SetResourceReleaseCallback(
-        resource->id,
+        resource_id,
         base::Bind(&Buffer::Texture::ReleaseTexImage,
                    base::Unretained(contents_texture),
                    base::Bind(&Buffer::ReleaseContentsTexture, AsWeakPtr(),
@@ -502,7 +503,7 @@
   // The mailbox texture will be released when no longer used by the
   // compositor.
   layer_tree_frame_sink_holder->SetResourceReleaseCallback(
-      resource->id,
+      resource_id,
       base::Bind(&Buffer::Texture::Release, base::Unretained(texture),
                  base::Bind(&Buffer::ReleaseTexture, AsWeakPtr(),
                             base::Passed(&texture_))));
diff --git a/components/exo/buffer.h b/components/exo/buffer.h
index f347582..890edf4 100644
--- a/components/exo/buffer.h
+++ b/components/exo/buffer.h
@@ -54,6 +54,7 @@
   // |non_client_usage| is true.
   bool ProduceTransferableResource(
       LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder,
+      cc::ResourceId resource_id,
       bool secure_output_only,
       bool client_usage,
       cc::TransferableResource* resource);
diff --git a/components/exo/buffer_unittest.cc b/components/exo/buffer_unittest.cc
index bf562f98..be934522b 100644
--- a/components/exo/buffer_unittest.cc
+++ b/components/exo/buffer_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/bind.h"
 #include "cc/resources/single_release_callback.h"
 #include "components/exo/buffer.h"
-#include "components/exo/surface_tree_host.h"
+#include "components/exo/surface.h"
 #include "components/exo/test/exo_test_base.h"
 #include "components/exo/test/exo_test_helper.h"
 #include "components/viz/common/gpu/context_provider.h"
@@ -29,12 +29,12 @@
 
 TEST_F(BufferTest, ReleaseCallback) {
   gfx::Size buffer_size(256, 256);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
-  auto surface_tree_host =
-      base::MakeUnique<SurfaceTreeHost>("BufferTest", nullptr);
-  LayerTreeFrameSinkHolder* frame_sink_holder =
-      surface_tree_host->layer_tree_frame_sink_holder();
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface(new Surface);
+  const viz::FrameSinkId arbitrary_frame_sink_id(1, 1);
+  LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder =
+      surface->layer_tree_frame_sink_holder();
 
   // Set the release callback.
   int release_call_count = 0;
@@ -44,8 +44,8 @@
   buffer->OnAttach();
   cc::TransferableResource resource;
   // Produce a transferable resource for the contents of the buffer.
-  bool rv = buffer->ProduceTransferableResource(frame_sink_holder, false, true,
-                                                &resource);
+  bool rv = buffer->ProduceTransferableResource(layer_tree_frame_sink_holder, 0,
+                                                false, true, &resource);
   ASSERT_TRUE(rv);
 
   // Release buffer.
@@ -54,7 +54,7 @@
   returned_resource.sync_token = resource.mailbox_holder.sync_token;
   returned_resource.lost = false;
   std::vector<cc::ReturnedResource> resources = {returned_resource};
-  frame_sink_holder->ReclaimResources(resources);
+  layer_tree_frame_sink_holder->ReclaimResources(resources);
 
   RunAllPendingInMessageLoop();
   ASSERT_EQ(release_call_count, 0);
@@ -67,18 +67,19 @@
 
 TEST_F(BufferTest, IsLost) {
   gfx::Size buffer_size(256, 256);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
-  auto surface_tree_host =
-      base::MakeUnique<SurfaceTreeHost>("BufferTest", nullptr);
-  LayerTreeFrameSinkHolder* frame_sink_holder =
-      surface_tree_host->layer_tree_frame_sink_holder();
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  const viz::FrameSinkId arbitrary_frame_sink_id(1, 1);
+  std::unique_ptr<Surface> surface(new Surface);
+  LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder =
+      surface->layer_tree_frame_sink_holder();
+  cc::ResourceId resource_id = 0;
 
   buffer->OnAttach();
   // Acquire a texture transferable resource for the contents of the buffer.
   cc::TransferableResource resource;
-  bool rv = buffer->ProduceTransferableResource(frame_sink_holder, false, true,
-                                                &resource);
+  bool rv = buffer->ProduceTransferableResource(
+      layer_tree_frame_sink_holder, resource_id, false, true, &resource);
   ASSERT_TRUE(rv);
 
   scoped_refptr<viz::ContextProvider> context_provider =
@@ -94,27 +95,28 @@
   // Release buffer.
   bool is_lost = true;
   cc::ReturnedResource returned_resource;
-  returned_resource.id = resource.id;
+  returned_resource.id = resource_id;
   returned_resource.sync_token = gpu::SyncToken();
   returned_resource.lost = is_lost;
   std::vector<cc::ReturnedResource> resources = {returned_resource};
-  frame_sink_holder->ReclaimResources(resources);
+  layer_tree_frame_sink_holder->ReclaimResources(resources);
   RunAllPendingInMessageLoop();
 
   // Producing a new texture transferable resource for the contents of the
   // buffer.
+  ++resource_id;
   cc::TransferableResource new_resource;
-  rv = buffer->ProduceTransferableResource(frame_sink_holder, false, false,
-                                           &new_resource);
+  rv = buffer->ProduceTransferableResource(
+      layer_tree_frame_sink_holder, resource_id, false, false, &new_resource);
   ASSERT_TRUE(rv);
   buffer->OnDetach();
 
   cc::ReturnedResource returned_resource2;
-  returned_resource2.id = new_resource.id;
+  returned_resource2.id = resource_id;
   returned_resource2.sync_token = gpu::SyncToken();
   returned_resource2.lost = false;
   std::vector<cc::ReturnedResource> resources2 = {returned_resource2};
-  frame_sink_holder->ReclaimResources(resources2);
+  layer_tree_frame_sink_holder->ReclaimResources(resources2);
   RunAllPendingInMessageLoop();
 }
 
diff --git a/components/exo/layer_tree_frame_sink_holder.cc b/components/exo/layer_tree_frame_sink_holder.cc
index fa4b2cf..a750192d 100644
--- a/components/exo/layer_tree_frame_sink_holder.cc
+++ b/components/exo/layer_tree_frame_sink_holder.cc
@@ -6,7 +6,7 @@
 
 #include "cc/output/layer_tree_frame_sink.h"
 #include "cc/resources/returned_resource.h"
-#include "components/exo/surface_tree_host.h"
+#include "components/exo/surface.h"
 
 namespace exo {
 
@@ -14,16 +14,19 @@
 // LayerTreeFrameSinkHolder, public:
 
 LayerTreeFrameSinkHolder::LayerTreeFrameSinkHolder(
-    SurfaceTreeHost* surface_tree_host,
+    Surface* surface,
     std::unique_ptr<cc::LayerTreeFrameSink> frame_sink)
-    : surface_tree_host_(surface_tree_host),
+    : surface_(surface),
       frame_sink_(std::move(frame_sink)),
       weak_factory_(this) {
+  surface_->AddSurfaceObserver(this);
   frame_sink_->BindToClient(this);
 }
 
 LayerTreeFrameSinkHolder::~LayerTreeFrameSinkHolder() {
   frame_sink_->DetachFromClient();
+  if (surface_)
+    surface_->RemoveSurfaceObserver(this);
 
   // Release all resources which aren't returned from LayerTreeFrameSink.
   for (auto& callback : release_callbacks_)
@@ -55,7 +58,8 @@
 
 void LayerTreeFrameSinkHolder::SetBeginFrameSource(
     cc::BeginFrameSource* source) {
-  surface_tree_host_->SetBeginFrameSource(source);
+  if (surface_)
+    surface_->SetBeginFrameSource(source);
 }
 
 void LayerTreeFrameSinkHolder::ReclaimResources(
@@ -71,7 +75,16 @@
 }
 
 void LayerTreeFrameSinkHolder::DidReceiveCompositorFrameAck() {
-  surface_tree_host_->DidReceiveCompositorFrameAck();
+  if (surface_)
+    surface_->DidReceiveCompositorFrameAck();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// SurfaceObserver overrides:
+
+void LayerTreeFrameSinkHolder::OnSurfaceDestroying(Surface* surface) {
+  surface_->RemoveSurfaceObserver(this);
+  surface_ = nullptr;
 }
 
 }  // namespace exo
diff --git a/components/exo/layer_tree_frame_sink_holder.h b/components/exo/layer_tree_frame_sink_holder.h
index 2fb9b9a..12b0c45 100644
--- a/components/exo/layer_tree_frame_sink_holder.h
+++ b/components/exo/layer_tree_frame_sink_holder.h
@@ -10,19 +10,23 @@
 #include "base/containers/flat_map.h"
 #include "cc/output/layer_tree_frame_sink_client.h"
 #include "cc/resources/release_callback.h"
+#include "components/exo/surface_observer.h"
 
 namespace cc {
 class LayerTreeFrameSink;
 }
 
 namespace exo {
-class SurfaceTreeHost;
+class Surface;
 
 // This class talks to CompositorFrameSink and keeps track of references to
-// the contents of Buffers.
-class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient {
+// the contents of Buffers. It's keeped alive by references from
+// release_callbacks_. It's destroyed when its owning Surface is destroyed and
+// the last outstanding release callback is called.
+class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient,
+                                 public SurfaceObserver {
  public:
-  LayerTreeFrameSinkHolder(SurfaceTreeHost* surface_tree_host,
+  LayerTreeFrameSinkHolder(Surface* surface,
                            std::unique_ptr<cc::LayerTreeFrameSink> frame_sink);
   ~LayerTreeFrameSinkHolder() override;
 
@@ -49,12 +53,15 @@
       const gfx::Rect& viewport_rect,
       const gfx::Transform& transform) override {}
 
+  // Overridden from SurfaceObserver:
+  void OnSurfaceDestroying(Surface* surface) override;
+
  private:
   // A collection of callbacks used to release resources.
   using ResourceReleaseCallbackMap = base::flat_map<int, cc::ReleaseCallback>;
   ResourceReleaseCallbackMap release_callbacks_;
 
-  SurfaceTreeHost* surface_tree_host_;
+  Surface* surface_;
   std::unique_ptr<cc::LayerTreeFrameSink> frame_sink_;
 
   // The next resource id the buffer is attached to.
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index c44cf39..3b32f0b 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -956,9 +956,6 @@
 void ShellSurface::OnWindowBoundsChanged(aura::Window* window,
                                          const gfx::Rect& old_bounds,
                                          const gfx::Rect& new_bounds) {
-  if (window == host_window())
-    return;
-
   // TODO(domlaskowski): For BoundsMode::CLIENT, the configure callback does not
   // yet support resizing. See crbug.com/699746.
   if (bounds_mode_ == BoundsMode::CLIENT)
@@ -990,23 +987,7 @@
   }
 }
 
-void ShellSurface::OnWindowAddedToRootWindow(aura::Window* window) {
-  if (window == host_window())
-    SurfaceTreeHost::OnWindowAddedToRootWindow(window);
-}
-
-void ShellSurface::OnWindowRemovingFromRootWindow(aura::Window* window,
-                                                  aura::Window* new_root) {
-  if (window == host_window())
-    SurfaceTreeHost::OnWindowRemovingFromRootWindow(window, new_root);
-}
-
 void ShellSurface::OnWindowDestroying(aura::Window* window) {
-  if (window == host_window()) {
-    SurfaceTreeHost::OnWindowDestroying(window);
-    return;
-  }
-
   if (window == parent_) {
     parent_ = nullptr;
     // |parent_| being set to null effects the ability to maximize the window.
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h
index fc96631d..ab05c116 100644
--- a/components/exo/shell_surface.h
+++ b/components/exo/shell_surface.h
@@ -16,6 +16,7 @@
 #include "components/exo/surface_observer.h"
 #include "components/exo/surface_tree_host.h"
 #include "components/exo/wm_helper.h"
+#include "ui/aura/window_observer.h"
 #include "ui/base/hit_test.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
@@ -46,6 +47,7 @@
                      public views::WidgetDelegate,
                      public views::View,
                      public ash::wm::WindowStateObserver,
+                     public aura::WindowObserver,
                      public WMHelper::ActivationObserver,
                      public WMHelper::DisplayConfigurationObserver {
  public:
@@ -256,9 +258,6 @@
   void OnWindowBoundsChanged(aura::Window* window,
                              const gfx::Rect& old_bounds,
                              const gfx::Rect& new_bounds) override;
-  void OnWindowAddedToRootWindow(aura::Window* window) override;
-  void OnWindowRemovingFromRootWindow(aura::Window* window,
-                                      aura::Window* new_root) override;
   void OnWindowDestroying(aura::Window* window) override;
 
   // Overridden from WMHelper::ActivationObserver:
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc
index ec9bbf7..537699e 100644
--- a/components/exo/shell_surface_unittest.cc
+++ b/components/exo/shell_surface_unittest.cc
@@ -891,8 +891,8 @@
 
 TEST_F(ShellSurfaceTest, MaximizedAndImmersiveFullscreenBackdrop) {
   ash::WorkspaceController* wc =
-      ash::test::ShellTestApi(ash::Shell::Get()).workspace_controller();
-  ash::test::WorkspaceControllerTestApi test_helper(wc);
+      ash::ShellTestApi(ash::Shell::Get()).workspace_controller();
+  ash::WorkspaceControllerTestApi test_helper(wc);
 
   const gfx::Size display_size =
       display::Screen::GetScreen()->GetPrimaryDisplay().size();
diff --git a/components/exo/sub_surface.cc b/components/exo/sub_surface.cc
index f170dae..1f8e2f30 100644
--- a/components/exo/sub_surface.cc
+++ b/components/exo/sub_surface.cc
@@ -96,8 +96,7 @@
   if (IsSurfaceSynchronized())
     return;
 
-  // TODO(penghuang): http://crbug.com/740110 Support async mode.
-  NOTIMPLEMENTED() << "Async subsurface is not supported!";
+  surface_->CommitSurfaceHierarchy();
 }
 
 bool SubSurface::IsSurfaceSynchronized() const {
diff --git a/components/exo/sub_surface_unittest.cc b/components/exo/sub_surface_unittest.cc
index c569753..1132dec 100644
--- a/components/exo/sub_surface_unittest.cc
+++ b/components/exo/sub_surface_unittest.cc
@@ -5,7 +5,6 @@
 #include "components/exo/sub_surface.h"
 
 #include "base/memory/ptr_util.h"
-#include "components/exo/shell_surface.h"
 #include "components/exo/surface.h"
 #include "components/exo/test/exo_test_base.h"
 #include "components/exo/test/exo_test_helper.h"
@@ -17,10 +16,10 @@
 using SubSurfaceTest = test::ExoTestBase;
 
 TEST_F(SubSurfaceTest, SetPosition) {
-  auto parent = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(parent.get());
-  auto surface = base::MakeUnique<Surface>();
-  auto sub_surface = base::MakeUnique<SubSurface>(surface.get(), parent.get());
+  std::unique_ptr<Surface> parent(new Surface);
+  std::unique_ptr<Surface> surface(new Surface);
+  std::unique_ptr<SubSurface> sub_surface(
+      new SubSurface(surface.get(), parent.get()));
 
   // Initial position is at the origin.
   EXPECT_EQ(gfx::Point().ToString(),
@@ -50,15 +49,14 @@
 }
 
 TEST_F(SubSurfaceTest, PlaceAbove) {
-  auto parent = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(parent.get());
-  auto surface1 = base::MakeUnique<Surface>();
-  auto surface2 = base::MakeUnique<Surface>();
-  auto non_sibling_surface = base::MakeUnique<Surface>();
-  auto sub_surface1 =
-      base::MakeUnique<SubSurface>(surface1.get(), parent.get());
-  auto sub_surface2 =
-      base::MakeUnique<SubSurface>(surface2.get(), parent.get());
+  std::unique_ptr<Surface> parent(new Surface);
+  std::unique_ptr<Surface> surface1(new Surface);
+  std::unique_ptr<Surface> surface2(new Surface);
+  std::unique_ptr<Surface> non_sibling_surface(new Surface);
+  std::unique_ptr<SubSurface> sub_surface1(
+      new SubSurface(surface1.get(), parent.get()));
+  std::unique_ptr<SubSurface> sub_surface2(
+      new SubSurface(surface2.get(), parent.get()));
 
   ASSERT_EQ(2u, parent->window()->children().size());
   EXPECT_EQ(surface1->window(), parent->window()->children()[0]);
@@ -82,15 +80,14 @@
 }
 
 TEST_F(SubSurfaceTest, PlaceBelow) {
-  auto parent = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(parent.get());
-  auto surface1 = base::MakeUnique<Surface>();
-  auto surface2 = base::MakeUnique<Surface>();
-  auto non_sibling_surface = base::MakeUnique<Surface>();
-  auto sub_surface1 =
-      base::MakeUnique<SubSurface>(surface1.get(), parent.get());
-  auto sub_surface2 =
-      base::MakeUnique<SubSurface>(surface2.get(), parent.get());
+  std::unique_ptr<Surface> parent(new Surface);
+  std::unique_ptr<Surface> surface1(new Surface);
+  std::unique_ptr<Surface> surface2(new Surface);
+  std::unique_ptr<Surface> non_sibling_surface(new Surface);
+  std::unique_ptr<SubSurface> sub_surface1(
+      new SubSurface(surface1.get(), parent.get()));
+  std::unique_ptr<SubSurface> sub_surface2(
+      new SubSurface(surface2.get(), parent.get()));
 
   ASSERT_EQ(2u, parent->window()->children().size());
   EXPECT_EQ(surface1->window(), parent->window()->children()[0]);
@@ -114,14 +111,13 @@
 }
 
 TEST_F(SubSurfaceTest, SetCommitBehavior) {
-  auto parent = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(parent.get());
-  auto child = base::MakeUnique<Surface>();
-  auto grandchild = base::MakeUnique<Surface>();
-  auto child_sub_surface =
-      base::MakeUnique<SubSurface>(child.get(), parent.get());
-  auto grandchild_sub_surface =
-      base::MakeUnique<SubSurface>(grandchild.get(), child.get());
+  std::unique_ptr<Surface> parent(new Surface);
+  std::unique_ptr<Surface> child(new Surface);
+  std::unique_ptr<Surface> grandchild(new Surface);
+  std::unique_ptr<SubSurface> child_sub_surface(
+      new SubSurface(child.get(), parent.get()));
+  std::unique_ptr<SubSurface> grandchild_sub_surface(
+      new SubSurface(grandchild.get(), child.get()));
 
   // Initial position is at the origin.
   EXPECT_EQ(gfx::Point().ToString(),
@@ -145,20 +141,19 @@
   EXPECT_EQ(position1.ToString(),
             grandchild->window()->bounds().origin().ToString());
 
-  // TODO(penghuang): http://crbug.com/740110 Support async mode.
   // Disable synchronous commit behavior.
-  // bool synchronized = false;
-  // child_sub_surface->SetCommitBehavior(synchronized);
+  bool synchronized = false;
+  child_sub_surface->SetCommitBehavior(synchronized);
 
   // Set position to 20, 20.
-  // gfx::Point position2(20, 20);
-  // grandchild_sub_surface->SetPosition(position2);
-  // child->Commit();
+  gfx::Point position2(20, 20);
+  grandchild_sub_surface->SetPosition(position2);
+  child->Commit();
 
   // A Commit() call on child should be sufficient for the position of
   // grandchild to take effect when synchronous is disabled.
-  // EXPECT_EQ(position2.ToString(),
-  //           grandchild->window()->bounds().origin().ToString());
+  EXPECT_EQ(position2.ToString(),
+            grandchild->window()->bounds().origin().ToString());
 }
 
 }  // namespace
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 9e711ab1..40a23ab 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/callback_helpers.h"
-#include "base/containers/adapters.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
@@ -28,6 +27,7 @@
 #include "components/viz/common/surfaces/sequence_surface_reference_factory.h"
 #include "third_party/khronos/GLES2/gl2.h"
 #include "ui/aura/client/aura_constants.h"
+#include "ui/aura/env.h"
 #include "ui/aura/window_delegate.h"
 #include "ui/aura/window_targeter.h"
 #include "ui/base/class_property.h"
@@ -189,23 +189,42 @@
   window_->SetType(aura::client::WINDOW_TYPE_CONTROL);
   window_->SetName("ExoSurface");
   window_->SetProperty(kSurfaceKey, this);
-  window_->Init(ui::LAYER_NOT_DRAWN);
+  window_->Init(ui::LAYER_SOLID_COLOR);
   window_->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter));
   window_->set_owned_by_parent(false);
+  window_->AddObserver(this);
+  aura::Env::GetInstance()->context_factory()->AddObserver(this);
+  layer_tree_frame_sink_holder_ = base::MakeUnique<LayerTreeFrameSinkHolder>(
+      this, window_->CreateLayerTreeFrameSink());
 }
 
 Surface::~Surface() {
+  aura::Env::GetInstance()->context_factory()->RemoveObserver(this);
   for (SurfaceObserver& observer : observers_)
     observer.OnSurfaceDestroying(this);
 
+  window_->RemoveObserver(this);
+  if (window_->layer()->GetCompositor())
+    window_->layer()->GetCompositor()->vsync_manager()->RemoveObserver(this);
+  window_->layer()->SetShowSolidColorContent();
+
+  frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
+  active_frame_callbacks_.splice(active_frame_callbacks_.end(),
+                                 frame_callbacks_);
   // Call all frame callbacks with a null frame time to indicate that they
   // have been cancelled.
-  for (const auto& frame_callback : pending_frame_callbacks_)
+  for (const auto& frame_callback : active_frame_callbacks_)
     frame_callback.Run(base::TimeTicks());
 
+  presentation_callbacks_.splice(presentation_callbacks_.end(),
+                                 pending_presentation_callbacks_);
+  swapping_presentation_callbacks_.splice(
+      swapping_presentation_callbacks_.end(), presentation_callbacks_);
+  swapped_presentation_callbacks_.splice(swapped_presentation_callbacks_.end(),
+                                         swapping_presentation_callbacks_);
   // Call all presentation callbacks with a null presentation time to indicate
   // that they have been cancelled.
-  for (const auto& presentation_callback : pending_presentation_callbacks_)
+  for (const auto& presentation_callback : swapped_presentation_callbacks_)
     presentation_callback.Run(base::TimeTicks(), base::TimeDelta());
 }
 
@@ -214,6 +233,10 @@
   return window->GetProperty(kSurfaceKey);
 }
 
+viz::SurfaceId Surface::GetSurfaceId() const {
+  return window_->GetSurfaceId();
+}
+
 void Surface::Attach(Buffer* buffer) {
   TRACE_EVENT1("exo", "Surface::Attach", "buffer",
                buffer ? buffer->GetSize().ToString() : "null");
@@ -267,13 +290,11 @@
 
   DCHECK(!sub_surface->window()->parent());
   DCHECK(!sub_surface->window()->IsVisible());
-  sub_surface->window()->SetBounds(
-      gfx::Rect(sub_surface->window()->bounds().size()));
   window_->AddChild(sub_surface->window());
 
   DCHECK(!ListContainsEntry(pending_sub_surfaces_, sub_surface));
   pending_sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point()));
-  sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point()));
+  has_pending_layer_changes_ = true;
 }
 
 void Surface::RemoveSubSurface(Surface* sub_surface) {
@@ -287,8 +308,7 @@
   DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface));
   pending_sub_surfaces_.erase(
       FindListEntry(pending_sub_surfaces_, sub_surface));
-  DCHECK(ListContainsEntry(sub_surfaces_, sub_surface));
-  sub_surfaces_.erase(FindListEntry(sub_surfaces_, sub_surface));
+  has_pending_layer_changes_ = true;
 }
 
 void Surface::SetSubSurfacePosition(Surface* sub_surface,
@@ -301,7 +321,7 @@
   if (it->second == position)
     return;
   it->second = position;
-  sub_surfaces_changed_ = true;
+  has_pending_layer_changes_ = true;
 }
 
 void Surface::PlaceSubSurfaceAbove(Surface* sub_surface, Surface* reference) {
@@ -333,7 +353,7 @@
   if (it == position_it)
     return;
   pending_sub_surfaces_.splice(position_it, pending_sub_surfaces_, it);
-  sub_surfaces_changed_ = true;
+  has_pending_layer_changes_ = true;
 }
 
 void Surface::PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling) {
@@ -358,7 +378,7 @@
   if (it == sibling_it)
     return;
   pending_sub_surfaces_.splice(sibling_it, pending_sub_surfaces_, it);
-  sub_surfaces_changed_ = true;
+  has_pending_layer_changes_ = true;
 }
 
 void Surface::SetViewport(const gfx::Size& viewport) {
@@ -401,87 +421,108 @@
   TRACE_EVENT0("exo", "Surface::Commit");
 
   needs_commit_surface_hierarchy_ = true;
-  if (delegate_)
+
+  if (state_ != pending_state_)
+    has_pending_layer_changes_ = true;
+
+  if (has_pending_contents_) {
+    if (pending_buffer_.buffer()) {
+      if (current_resource_.size != pending_buffer_.buffer()->GetSize())
+        has_pending_layer_changes_ = true;
+      // Whether layer fills bounds opaquely or not might have changed.
+      if (current_resource_has_alpha_ !=
+          FormatHasAlpha(pending_buffer_.buffer()->GetFormat()))
+        has_pending_layer_changes_ = true;
+    } else if (!current_resource_.size.IsEmpty()) {
+      has_pending_layer_changes_ = true;
+    }
+  }
+
+  if (delegate_) {
     delegate_->OnSurfaceCommit();
+  } else {
+    CommitSurfaceHierarchy();
+  }
+
+  if (current_begin_frame_ack_.sequence_number !=
+      cc::BeginFrameArgs::kInvalidFrameNumber) {
+    if (!current_begin_frame_ack_.has_damage) {
+      layer_tree_frame_sink_holder_->frame_sink()->DidNotProduceFrame(
+          current_begin_frame_ack_);
+    }
+    current_begin_frame_ack_.sequence_number =
+        cc::BeginFrameArgs::kInvalidFrameNumber;
+    if (begin_frame_source_)
+      begin_frame_source_->DidFinishFrame(this);
+  }
 }
 
-void Surface::CommitSurfaceHierarchy(
-    const gfx::Point& origin,
-    FrameType frame_type,
-    LayerTreeFrameSinkHolder* frame_sink_holder,
-    cc::CompositorFrame* frame,
-    std::list<FrameCallback>* frame_callbacks,
-    std::list<PresentationCallback>* presentation_callbacks) {
-  bool needs_commit =
-      frame_type == FRAME_TYPE_COMMIT && needs_commit_surface_hierarchy_;
-  if (needs_commit) {
-    needs_commit_surface_hierarchy_ = false;
+void Surface::CommitSurfaceHierarchy() {
+  DCHECK(needs_commit_surface_hierarchy_);
+  needs_commit_surface_hierarchy_ = false;
+  has_pending_layer_changes_ = false;
 
-    state_ = pending_state_;
-    pending_state_.only_visible_on_secure_output = false;
+  state_ = pending_state_;
+  pending_state_.only_visible_on_secure_output = false;
 
-    // We update contents if Attach() has been called since last commit.
-    if (has_pending_contents_) {
-      has_pending_contents_ = false;
+  // We update contents if Attach() has been called since last commit.
+  if (has_pending_contents_) {
+    has_pending_contents_ = false;
 
-      current_buffer_ = std::move(pending_buffer_);
+    current_buffer_ = std::move(pending_buffer_);
 
-      UpdateResource(frame_sink_holder, true);
-    }
-
-    // Move pending frame callbacks to the end of frame_callbacks.
-    frame_callbacks->splice(frame_callbacks->end(), pending_frame_callbacks_);
-
-    // Move pending presentation callbacks to the end of presentation_callbacks.
-    presentation_callbacks->splice(presentation_callbacks->end(),
-                                   pending_presentation_callbacks_);
-
-    UpdateContentSize();
-
-    // Synchronize window hierarchy. This will position and update the stacking
-    // order of all sub-surfaces after committing all pending state of
-    // sub-surface descendants.
-    if (sub_surfaces_changed_) {
-      sub_surfaces_.clear();
-      aura::Window* stacking_target = nullptr;
-      for (const auto& sub_surface_entry : pending_sub_surfaces_) {
-        Surface* sub_surface = sub_surface_entry.first;
-        sub_surfaces_.push_back(sub_surface_entry);
-        // Move sub-surface to its new position in the stack.
-        if (stacking_target)
-          window_->StackChildAbove(sub_surface->window(), stacking_target);
-
-        // Stack next sub-surface above this sub-surface.
-        stacking_target = sub_surface->window();
-
-        // Update sub-surface position relative to surface origin.
-        sub_surface->window()->SetBounds(gfx::Rect(
-            sub_surface_entry.second, sub_surface->window()->bounds().size()));
-      }
-      sub_surfaces_changed_ = false;
-    }
+    UpdateResource(true);
   }
 
-  // The top most sub-surface is at the front of the RenderPass's quad_list,
-  // so we need composite sub-surface in reversed order.
-  for (const auto& sub_surface_entry : base::Reversed(sub_surfaces_)) {
-    auto* sub_surface = sub_surface_entry.first;
-    // Synchronsouly commit all pending state of the sub-surface and its
-    // decendents.
-    sub_surface->CommitSurfaceHierarchy(
-        origin + sub_surface_entry.second.OffsetFromOrigin(), frame_type,
-        frame_sink_holder, frame, frame_callbacks, presentation_callbacks);
-  }
+  // Move pending frame callbacks to the end of frame_callbacks_.
+  frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
 
-  AppendContentsToFrame(origin, frame_type, frame);
+  // Move pending presentation callbacks to the end of presentation_callbacks_.
+  presentation_callbacks_.splice(presentation_callbacks_.end(),
+                                 pending_presentation_callbacks_);
+
+  UpdateSurface(false);
+
+  window_->layer()->SetFillsBoundsOpaquely(
+      !current_resource_has_alpha_ || state_.blend_mode == SkBlendMode::kSrc ||
+      state_.opaque_region.contains(
+          gfx::RectToSkIRect(gfx::Rect(content_size_))));
 
   // Reset damage.
-  if (needs_commit)
-    pending_damage_.setEmpty();
+  pending_damage_.setEmpty();
+  DCHECK(!current_resource_.id ||
+         layer_tree_frame_sink_holder_->HasReleaseCallbackForResource(
+             current_resource_.id));
 
-  DCHECK(
-      !current_resource_.id ||
-      frame_sink_holder->HasReleaseCallbackForResource(current_resource_.id));
+  // Synchronize window hierarchy. This will position and update the stacking
+  // order of all sub-surfaces after committing all pending state of sub-surface
+  // descendants.
+  aura::Window* stacking_target = nullptr;
+  for (auto& sub_surface_entry : pending_sub_surfaces_) {
+    Surface* sub_surface = sub_surface_entry.first;
+
+    // Synchronsouly commit all pending state of the sub-surface and its
+    // decendents.
+    if (sub_surface->needs_commit_surface_hierarchy())
+      sub_surface->CommitSurfaceHierarchy();
+
+    // Enable/disable sub-surface based on if it has contents.
+    if (sub_surface->has_contents())
+      sub_surface->window()->Show();
+    else
+      sub_surface->window()->Hide();
+
+    // Move sub-surface to its new position in the stack.
+    if (stacking_target)
+      window_->StackChildAbove(sub_surface->window(), stacking_target);
+
+    // Stack next sub-surface above this sub-surface.
+    stacking_target = sub_surface->window();
+
+    // Update sub-surface position relative to surface origin.
+    sub_surface->window()->SetBounds(
+        gfx::Rect(sub_surface_entry.second, sub_surface->content_size_));
+  }
 }
 
 bool Surface::IsSynchronized() const {
@@ -558,6 +599,49 @@
   return value;
 }
 
+void Surface::DidReceiveCompositorFrameAck() {
+  active_frame_callbacks_.splice(active_frame_callbacks_.end(),
+                                 frame_callbacks_);
+  swapping_presentation_callbacks_.splice(
+      swapping_presentation_callbacks_.end(), presentation_callbacks_);
+  UpdateNeedsBeginFrame();
+}
+
+void Surface::SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) {
+  if (needs_begin_frame_) {
+    DCHECK(begin_frame_source_);
+    begin_frame_source_->RemoveObserver(this);
+    needs_begin_frame_ = false;
+  }
+  begin_frame_source_ = begin_frame_source;
+  UpdateNeedsBeginFrame();
+}
+
+void Surface::UpdateNeedsBeginFrame() {
+  if (!begin_frame_source_)
+    return;
+
+  bool needs_begin_frame = !active_frame_callbacks_.empty();
+  if (needs_begin_frame == needs_begin_frame_)
+    return;
+
+  needs_begin_frame_ = needs_begin_frame;
+  if (needs_begin_frame_)
+    begin_frame_source_->AddObserver(this);
+  else
+    begin_frame_source_->RemoveObserver(this);
+}
+
+bool Surface::OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) {
+  current_begin_frame_ack_ =
+      cc::BeginFrameAck(args.source_id, args.sequence_number, false);
+  while (!active_frame_callbacks_.empty()) {
+    active_frame_callbacks_.front().Run(args.frame_time);
+    active_frame_callbacks_.pop_front();
+  }
+  return true;
+}
+
 bool Surface::IsStylusOnly() {
   return window_->GetProperty(kStylusOnlyKey);
 }
@@ -566,17 +650,48 @@
   window_->SetProperty(kStylusOnlyKey, true);
 }
 
-void Surface::RecreateResources(LayerTreeFrameSinkHolder* frame_sink_holder) {
-  UpdateResource(frame_sink_holder, false);
-  for (const auto& sub_surface : sub_surfaces_)
-    sub_surface.first->RecreateResources(frame_sink_holder);
+////////////////////////////////////////////////////////////////////////////////
+// ui::ContextFactoryObserver overrides:
+
+void Surface::OnLostResources() {
+  if (!window_->GetSurfaceId().is_valid())
+    return;
+  UpdateResource(false);
+  UpdateSurface(true);
 }
 
-bool Surface::FillsBoundsOpaquely() const {
-  return !current_resource_has_alpha_ ||
-         state_.blend_mode == SkBlendMode::kSrc ||
-         state_.opaque_region.contains(
-             gfx::RectToSkIRect(gfx::Rect(content_size_)));
+////////////////////////////////////////////////////////////////////////////////
+// aura::WindowObserver overrides:
+
+void Surface::OnWindowAddedToRootWindow(aura::Window* window) {
+  window->layer()->GetCompositor()->vsync_manager()->AddObserver(this);
+}
+
+void Surface::OnWindowRemovingFromRootWindow(aura::Window* window,
+                                             aura::Window* new_root) {
+  window->layer()->GetCompositor()->vsync_manager()->RemoveObserver(this);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ui::CompositorVSyncManager::Observer overrides:
+
+void Surface::OnUpdateVSyncParameters(base::TimeTicks timebase,
+                                      base::TimeDelta interval) {
+  // Use current time if platform doesn't provide an accurate timebase.
+  if (timebase.is_null())
+    timebase = base::TimeTicks::Now();
+
+  while (!swapped_presentation_callbacks_.empty()) {
+    swapped_presentation_callbacks_.front().Run(timebase, interval);
+    swapped_presentation_callbacks_.pop_front();
+  }
+
+  // VSync parameters updates are generated at the start of a new swap. Move
+  // the swapping presentation callbacks to swapped callbacks so they fire
+  // at the next VSync parameters update as that will contain the presentation
+  // time for the previous frame.
+  swapped_presentation_callbacks_.splice(swapped_presentation_callbacks_.end(),
+                                         swapping_presentation_callbacks_);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -626,11 +741,12 @@
   buffer_ = buffer;
 }
 
-void Surface::UpdateResource(LayerTreeFrameSinkHolder* frame_sink_holder,
-                             bool client_usage) {
+void Surface::UpdateResource(bool client_usage) {
   if (current_buffer_.buffer() &&
       current_buffer_.buffer()->ProduceTransferableResource(
-          frame_sink_holder, state_.only_visible_on_secure_output, client_usage,
+          layer_tree_frame_sink_holder_.get(),
+          layer_tree_frame_sink_holder_->AllocateResourceId(),
+          state_.only_visible_on_secure_output, client_usage,
           &current_resource_)) {
     current_resource_has_alpha_ =
         FormatHasAlpha(current_buffer_.buffer()->GetFormat());
@@ -641,47 +757,80 @@
   }
 }
 
-void Surface::AppendContentsToFrame(const gfx::Point& origin,
-                                    FrameType frame_type,
-                                    cc::CompositorFrame* frame) {
-  const std::unique_ptr<cc::RenderPass>& render_pass =
-      frame->render_pass_list.back();
-  gfx::Rect output_rect = gfx::Rect(origin, content_size_);
-  gfx::Rect quad_rect = output_rect;
-  gfx::Rect damage_rect;
-  switch (frame_type) {
-    case FRAME_TYPE_COMMIT:
-      // pending_damage_ is in Surface coordinates.
-      damage_rect = gfx::SkIRectToRect(pending_damage_.getBounds());
-      damage_rect.set_origin(origin);
-      damage_rect.Intersect(output_rect);
-      break;
-    case FRAME_TYPE_RECREATED_RESOURCES:
-      damage_rect = output_rect;
-      break;
+void Surface::UpdateSurface(bool full_damage) {
+  gfx::Size buffer_size = current_resource_.size;
+  gfx::SizeF scaled_buffer_size(
+      gfx::ScaleSize(gfx::SizeF(buffer_size), 1.0f / state_.buffer_scale));
+
+  gfx::Size layer_size;  // Size of the output layer, in DIP.
+  if (!state_.viewport.IsEmpty()) {
+    layer_size = state_.viewport;
+  } else if (!state_.crop.IsEmpty()) {
+    DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(state_.crop.width()) ||
+                         !gfx::IsExpressibleAsInt(state_.crop.height()))
+        << "Crop rectangle size (" << state_.crop.size().ToString()
+        << ") most be expressible using integers when viewport is not set";
+    layer_size = gfx::ToCeiledSize(state_.crop.size());
+  } else {
+    layer_size = gfx::ToCeiledSize(scaled_buffer_size);
   }
 
-  render_pass->damage_rect.Union(damage_rect);
+  content_size_ = layer_size;
+  // We need update window_'s bounds with content size, because the
+  // LayerTreeFrameSink may not update the window's size base the size of
+  // the lastest submitted CompositorFrame.
+  window_->SetBounds(gfx::Rect(window_->bounds().origin(), content_size_));
+  // TODO(jbauman): Figure out how this interacts with the pixel size of
+  // CopyOutputRequests on the layer.
+  gfx::Size contents_surface_size = layer_size;
+
+  gfx::PointF uv_top_left(0.f, 0.f);
+  gfx::PointF uv_bottom_right(1.f, 1.f);
+  if (!state_.crop.IsEmpty()) {
+    uv_top_left = state_.crop.origin();
+
+    uv_top_left.Scale(1.f / scaled_buffer_size.width(),
+                      1.f / scaled_buffer_size.height());
+    uv_bottom_right = state_.crop.bottom_right();
+    uv_bottom_right.Scale(1.f / scaled_buffer_size.width(),
+                          1.f / scaled_buffer_size.height());
+  }
+
+  gfx::Rect damage_rect;
+  gfx::Rect output_rect = gfx::Rect(contents_surface_size);
+  if (full_damage) {
+    damage_rect = output_rect;
+  } else {
+    // pending_damage_ is in Surface coordinates.
+    damage_rect = gfx::SkIRectToRect(pending_damage_.getBounds());
+    damage_rect.Intersect(output_rect);
+  }
+
+  const int kRenderPassId = 1;
+  std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
+  render_pass->SetNew(kRenderPassId, output_rect, damage_rect,
+                      gfx::Transform());
+
+  gfx::Rect quad_rect = output_rect;
   cc::SharedQuadState* quad_state =
       render_pass->CreateAndAppendSharedQuadState();
-  quad_state->quad_layer_rect = gfx::Rect(content_size_);
+  quad_state->quad_layer_rect = gfx::Rect(contents_surface_size);
   quad_state->visible_quad_layer_rect = quad_rect;
   quad_state->opacity = state_.alpha;
 
-  if (current_resource_.id) {
-    gfx::PointF uv_top_left(0.f, 0.f);
-    gfx::PointF uv_bottom_right(1.f, 1.f);
-    if (!state_.crop.IsEmpty()) {
-      gfx::SizeF scaled_buffer_size(gfx::ScaleSize(
-          gfx::SizeF(current_resource_.size), 1.0f / state_.buffer_scale));
-      uv_top_left = state_.crop.origin();
+  cc::CompositorFrame frame;
+  // If we commit while we don't have an active BeginFrame, we acknowledge a
+  // manual one.
+  if (current_begin_frame_ack_.sequence_number ==
+      cc::BeginFrameArgs::kInvalidFrameNumber) {
+    current_begin_frame_ack_ = cc::BeginFrameAck::CreateManualAckWithDamage();
+  } else {
+    current_begin_frame_ack_.has_damage = true;
+  }
+  frame.metadata.begin_frame_ack = current_begin_frame_ack_;
+  frame.metadata.device_scale_factor = device_scale_factor_;
 
-      uv_top_left.Scale(1.f / scaled_buffer_size.width(),
-                        1.f / scaled_buffer_size.height());
-      uv_bottom_right = state_.crop.bottom_right();
-      uv_bottom_right.Scale(1.f / scaled_buffer_size.width(),
-                            1.f / scaled_buffer_size.height());
-    }
+  if (current_resource_.id) {
     // Texture quad is only needed if buffer is not fully transparent.
     if (state_.alpha) {
       cc::TextureDrawQuad* texture_quad =
@@ -696,46 +845,23 @@
         opaque_rect = gfx::SkIRectToRect(state_.opaque_region.getBounds());
       }
 
-      texture_quad->SetNew(
-          quad_state, quad_rect, opaque_rect, quad_rect, current_resource_.id,
-          true /* premultiplied_alpha */, uv_top_left, uv_bottom_right,
-          SK_ColorTRANSPARENT /* background_color */, vertex_opacity,
-          false /* y_flipped */, false /* nearest_neighbor */,
-          state_.only_visible_on_secure_output);
+      texture_quad->SetNew(quad_state, quad_rect, opaque_rect, quad_rect,
+                           current_resource_.id, true, uv_top_left,
+                           uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity,
+                           false, false, state_.only_visible_on_secure_output);
       if (current_resource_.is_overlay_candidate)
         texture_quad->set_resource_size_in_pixels(current_resource_.size);
-      frame->resource_list.push_back(current_resource_);
+      frame.resource_list.push_back(current_resource_);
     }
   } else {
     cc::SolidColorDrawQuad* solid_quad =
         render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
-    solid_quad->SetNew(quad_state, quad_rect, quad_rect, SK_ColorBLACK,
-                       false /* force_anti_aliasing_off */);
+    solid_quad->SetNew(quad_state, quad_rect, quad_rect, SK_ColorBLACK, false);
   }
-}
 
-void Surface::UpdateContentSize() {
-  gfx::Size buffer_size = current_resource_.size;
-  gfx::SizeF scaled_buffer_size(
-      gfx::ScaleSize(gfx::SizeF(buffer_size), 1.0f / state_.buffer_scale));
-  if (!state_.viewport.IsEmpty()) {
-    content_size_ = state_.viewport;
-  } else if (!state_.crop.IsEmpty()) {
-    DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(state_.crop.width()) ||
-                         !gfx::IsExpressibleAsInt(state_.crop.height()))
-        << "Crop rectangle size (" << state_.crop.size().ToString()
-        << ") most be expressible using integers when viewport is not set";
-    content_size_ = gfx::ToCeiledSize(state_.crop.size());
-  } else {
-    content_size_ = gfx::ToCeiledSize(scaled_buffer_size);
-  }
-  window_->SetBounds(gfx::Rect(window_->bounds().origin(), content_size_));
-
-  // Enable/disable sub-surface based on if it has contents.
-  if (has_contents())
-    window_->Show();
-  else
-    window_->Hide();
+  frame.render_pass_list.push_back(std::move(render_pass));
+  layer_tree_frame_sink_holder_->frame_sink()->SubmitCompositorFrame(
+      std::move(frame));
 }
 
 }  // namespace exo
diff --git a/components/exo/surface.h b/components/exo/surface.h
index 5047d16..ae168733 100644
--- a/components/exo/surface.h
+++ b/components/exo/surface.h
@@ -15,10 +15,13 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "cc/resources/transferable_resource.h"
+#include "cc/scheduler/begin_frame_source.h"
 #include "components/exo/layer_tree_frame_sink_holder.h"
 #include "third_party/skia/include/core/SkBlendMode.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/aura/window.h"
+#include "ui/aura/window_observer.h"
+#include "ui/compositor/compositor_vsync_manager.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/native_widget_types.h"
 
@@ -28,17 +31,12 @@
 }
 }
 
-namespace cc {
-class CompositorFrame;
-}
-
 namespace gfx {
 class Path;
 }
 
 namespace exo {
 class Buffer;
-class LayerTreeFrameSinkHolder;
 class Pointer;
 class SurfaceDelegate;
 class SurfaceObserver;
@@ -54,18 +52,28 @@
 
 // This class represents a rectangular area that is displayed on the screen.
 // It has a location, size and pixel contents.
-class Surface : public ui::PropertyHandler {
+class Surface : public ui::ContextFactoryObserver,
+                public aura::WindowObserver,
+                public ui::PropertyHandler,
+                public ui::CompositorVSyncManager::Observer,
+                public cc::BeginFrameObserverBase {
  public:
   using PropertyDeallocator = void (*)(int64_t value);
 
   Surface();
-  ~Surface();
+  ~Surface() override;
 
   // Type-checking downcast routine.
   static Surface* AsSurface(const aura::Window* window);
 
   aura::Window* window() { return window_.get(); }
 
+  viz::SurfaceId GetSurfaceId() const;
+
+  LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder() {
+    return layer_tree_frame_sink_holder_.get();
+  }
+
   // Set a buffer as the content of this surface. A buffer can only be attached
   // to one surface at a time.
   void Attach(Buffer* buffer);
@@ -136,17 +144,7 @@
   // This will synchronously commit all pending state of the surface and its
   // descendants by recursively calling CommitSurfaceHierarchy() for each
   // sub-surface with pending state.
-  enum FrameType {
-    FRAME_TYPE_COMMIT,
-    FRAME_TYPE_RECREATED_RESOURCES,
-  };
-  void CommitSurfaceHierarchy(
-      const gfx::Point& origin,
-      FrameType frame_type,
-      LayerTreeFrameSinkHolder* frame_sink_holder,
-      cc::CompositorFrame* frame,
-      std::list<FrameCallback>* frame_callbacks,
-      std::list<PresentationCallback>* presentation_callbacks);
+  void CommitSurfaceHierarchy();
 
   // Returns true if surface is in synchronized mode.
   bool IsSynchronized() const;
@@ -188,6 +186,10 @@
   // Returns a trace value representing the state of the surface.
   std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const;
 
+  // Call this to indicate that the previous CompositorFrame is processed and
+  // the surface is being scheduled for a draw.
+  void DidReceiveCompositorFrameAck();
+
   // Called when the begin frame source has changed.
   void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source);
 
@@ -200,16 +202,26 @@
   // Enables 'stylus-only' mode for the associated window.
   void SetStylusOnly();
 
-  // Recreates resources for the surface and sub surfaces.
-  void RecreateResources(LayerTreeFrameSinkHolder* frame_sink_holder);
+  // Overridden from ui::ContextFactoryObserver:
+  void OnLostResources() override;
 
-  // Returns true if the surface's bounds should be filled opaquely.
-  bool FillsBoundsOpaquely() const;
+  // Overridden from aura::WindowObserver:
+  void OnWindowAddedToRootWindow(aura::Window* window) override;
+  void OnWindowRemovingFromRootWindow(aura::Window* window,
+                                      aura::Window* new_root) override;
+
+  // Overridden from ui::CompositorVSyncManager::Observer:
+  void OnUpdateVSyncParameters(base::TimeTicks timebase,
+                               base::TimeDelta interval) override;
 
   bool HasPendingDamageForTesting(const gfx::Rect& damage) const {
     return pending_damage_.contains(gfx::RectToSkIRect(damage));
   }
 
+  // Overridden from cc::BeginFrameObserverBase:
+  bool OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) override;
+  void OnBeginFrameSourcePausedChanged(bool paused) override {}
+
  private:
   struct State {
     State();
@@ -257,16 +269,14 @@
   // contents of the attached buffer (or id 0, if no buffer is attached).
   // UpdateSurface must be called afterwards to ensure the release callback
   // will be called.
-  void UpdateResource(LayerTreeFrameSinkHolder* frame_sink_holder,
-                      bool client_usage);
+  void UpdateResource(bool client_usage);
 
-  // Puts the current surface into a draw quad, and appends the draw quads into
-  // the |frame|.
-  void AppendContentsToFrame(const gfx::Point& origin,
-                             FrameType frame_type,
-                             cc::CompositorFrame* frame);
+  // Updates the current Surface with a new frame referring to the resource in
+  // current_resource_.
+  void UpdateSurface(bool full_damage);
 
-  void UpdateContentSize();
+  // Adds/Removes begin frame observer based on state.
+  void UpdateNeedsBeginFrame();
 
   // This returns true when the surface has some contents assigned to it.
   bool has_contents() const { return !!current_buffer_.buffer(); }
@@ -274,8 +284,10 @@
   // This window has the layer which contains the Surface contents.
   std::unique_ptr<aura::Window> window_;
 
-  // This true, if sub_surfaces_ has changes (order, position, etc).
-  bool sub_surfaces_changed_ = false;
+  // This is true if it's possible that the layer properties (size, opacity,
+  // etc.) may have been modified since the last commit. Attaching a new
+  // buffer with the same size as the old shouldn't set this to true.
+  bool has_pending_layer_changes_ = true;
 
   // This is the size of the last committed contents.
   gfx::Size content_size_;
@@ -290,6 +302,8 @@
   // The device scale factor sent in CompositorFrames.
   float device_scale_factor_ = 1.0f;
 
+  std::unique_ptr<LayerTreeFrameSinkHolder> layer_tree_frame_sink_holder_;
+
   // The damage region to schedule paint for when Commit() is called.
   SkRegion pending_damage_;
 
@@ -299,6 +313,8 @@
   // |active_frame_callbacks_| when the effect of the Commit() is scheduled to
   // be drawn. They fire at the first begin frame notification after this.
   std::list<FrameCallback> pending_frame_callbacks_;
+  std::list<FrameCallback> frame_callbacks_;
+  std::list<FrameCallback> active_frame_callbacks_;
 
   // These lists contains the callbacks to notify the client when surface
   // contents have been presented. These callbacks move to
@@ -308,6 +324,9 @@
   // after receiving VSync parameters update for the previous frame. They fire
   // at the next VSync parameters update after that.
   std::list<PresentationCallback> pending_presentation_callbacks_;
+  std::list<PresentationCallback> presentation_callbacks_;
+  std::list<PresentationCallback> swapping_presentation_callbacks_;
+  std::list<PresentationCallback> swapped_presentation_callbacks_;
 
   // This is the state that has yet to be committed.
   State pending_state_;
@@ -321,7 +340,6 @@
   using SubSurfaceEntry = std::pair<Surface*, gfx::Point>;
   using SubSurfaceEntryList = std::list<SubSurfaceEntry>;
   SubSurfaceEntryList pending_sub_surfaces_;
-  SubSurfaceEntryList sub_surfaces_;
 
   // The buffer that is currently set as content of surface.
   BufferAttachment current_buffer_;
@@ -351,6 +369,11 @@
   // Surface observer list. Surface does not own the observers.
   base::ObserverList<SurfaceObserver, true> observers_;
 
+  // The begin frame source being observed.
+  cc::BeginFrameSource* begin_frame_source_ = nullptr;
+  bool needs_begin_frame_ = false;
+  cc::BeginFrameAck current_begin_frame_ack_;
+
   DISALLOW_COPY_AND_ASSIGN(Surface);
 };
 
diff --git a/components/exo/surface_tree_host.cc b/components/exo/surface_tree_host.cc
index 24dff7f..36442f58 100644
--- a/components/exo/surface_tree_host.cc
+++ b/components/exo/surface_tree_host.cc
@@ -8,11 +8,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/layer_tree_frame_sink.h"
-#include "components/exo/layer_tree_frame_sink_holder.h"
 #include "components/exo/surface.h"
-#include "ui/aura/env.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
 #include "ui/aura/window_event_dispatcher.h"
@@ -77,20 +73,15 @@
   host_window_ = base::MakeUnique<aura::Window>(window_delegate);
   host_window_->SetType(aura::client::WINDOW_TYPE_CONTROL);
   host_window_->SetName(window_name);
-  host_window_->Init(ui::LAYER_SOLID_COLOR);
+  host_window_->Init(ui::LAYER_NOT_DRAWN);
   host_window_->set_owned_by_parent(false);
   host_window_->SetEventTargeter(base::MakeUnique<CustomWindowTargeter>(this));
-  layer_tree_frame_sink_holder_ = base::MakeUnique<LayerTreeFrameSinkHolder>(
-      this, host_window_->CreateLayerTreeFrameSink());
-  aura::Env::GetInstance()->context_factory()->AddObserver(this);
 }
 
 SurfaceTreeHost::~SurfaceTreeHost() {
-  aura::Env::GetInstance()->context_factory()->RemoveObserver(this);
-  SetRootSurface(nullptr);
-  if (host_window_->layer()->GetCompositor()) {
-    host_window_->layer()->GetCompositor()->vsync_manager()->RemoveObserver(
-        this);
+  if (root_surface_) {
+    root_surface_->window()->Hide();
+    root_surface_->SetSurfaceDelegate(nullptr);
   }
 }
 
@@ -105,28 +96,6 @@
         gfx::Rect(host_window_->bounds().origin(), gfx::Size()));
     root_surface_->SetSurfaceDelegate(nullptr);
     root_surface_ = nullptr;
-
-    active_frame_callbacks_.splice(active_frame_callbacks_.end(),
-                                   frame_callbacks_);
-    // Call all frame callbacks with a null frame time to indicate that they
-    // have been cancelled.
-    while (!active_frame_callbacks_.empty()) {
-      active_frame_callbacks_.front().Run(base::TimeTicks());
-      active_frame_callbacks_.pop_front();
-    }
-
-    swapping_presentation_callbacks_.splice(
-        swapping_presentation_callbacks_.end(), presentation_callbacks_);
-    swapped_presentation_callbacks_.splice(
-        swapped_presentation_callbacks_.end(),
-        swapping_presentation_callbacks_);
-    // Call all presentation callbacks with a null presentation time to indicate
-    // that they have been cancelled.
-    while (!swapped_presentation_callbacks_.empty()) {
-      swapped_presentation_callbacks_.front().Run(base::TimeTicks(),
-                                                  base::TimeDelta());
-      swapped_presentation_callbacks_.pop_front();
-    }
   }
 
   if (root_surface) {
@@ -156,43 +125,14 @@
   return root_surface_ ? root_surface_->GetCursor() : ui::CursorType::kNull;
 }
 
-void SurfaceTreeHost::DidReceiveCompositorFrameAck() {
-  active_frame_callbacks_.splice(active_frame_callbacks_.end(),
-                                 frame_callbacks_);
-  swapping_presentation_callbacks_.splice(
-      swapping_presentation_callbacks_.end(), presentation_callbacks_);
-  UpdateNeedsBeginFrame();
-}
-
-void SurfaceTreeHost::SetBeginFrameSource(
-    cc::BeginFrameSource* begin_frame_source) {
-  if (needs_begin_frame_) {
-    DCHECK(begin_frame_source_);
-    begin_frame_source_->RemoveObserver(this);
-    needs_begin_frame_ = false;
-  }
-  begin_frame_source_ = begin_frame_source;
-  UpdateNeedsBeginFrame();
-}
-
-void SurfaceTreeHost::UpdateNeedsBeginFrame() {
-  if (!begin_frame_source_)
-    return;
-  bool needs_begin_frame = !active_frame_callbacks_.empty();
-  if (needs_begin_frame == needs_begin_frame_)
-    return;
-  needs_begin_frame_ = needs_begin_frame;
-  if (needs_begin_frame_)
-    begin_frame_source_->AddObserver(this);
-  else
-    begin_frame_source_->RemoveObserver(this);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // SurfaceDelegate overrides:
 
 void SurfaceTreeHost::OnSurfaceCommit() {
-  SubmitCompositorFrame(Surface::FRAME_TYPE_COMMIT);
+  DCHECK(root_surface_);
+  root_surface_->CommitSurfaceHierarchy();
+  host_window_->SetBounds(gfx::Rect(host_window_->bounds().origin(),
+                                    root_surface_->content_size()));
 }
 
 bool SurfaceTreeHost::IsSurfaceSynchronized() const {
@@ -201,111 +141,4 @@
   return false;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// aura::WindowObserver overrides:
-
-void SurfaceTreeHost::OnWindowAddedToRootWindow(aura::Window* window) {
-  DCHECK_EQ(window, host_window());
-  window->layer()->GetCompositor()->vsync_manager()->AddObserver(this);
-}
-
-void SurfaceTreeHost::OnWindowRemovingFromRootWindow(aura::Window* window,
-                                                     aura::Window* new_root) {
-  DCHECK_EQ(window, host_window());
-  window->layer()->GetCompositor()->vsync_manager()->RemoveObserver(this);
-}
-
-void SurfaceTreeHost::OnWindowDestroying(aura::Window* window) {
-  DCHECK_EQ(window, host_window());
-  window->RemoveObserver(this);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// cc::BeginFrameObserverBase overrides:
-
-bool SurfaceTreeHost::OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) {
-  current_begin_frame_ack_ =
-      cc::BeginFrameAck(args.source_id, args.sequence_number, false);
-  while (!active_frame_callbacks_.empty()) {
-    active_frame_callbacks_.front().Run(args.frame_time);
-    active_frame_callbacks_.pop_front();
-  }
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ui::CompositorVSyncManager::Observer overrides:
-
-void SurfaceTreeHost::OnUpdateVSyncParameters(base::TimeTicks timebase,
-                                              base::TimeDelta interval) {
-  // Use current time if platform doesn't provide an accurate timebase.
-  if (timebase.is_null())
-    timebase = base::TimeTicks::Now();
-  while (!swapped_presentation_callbacks_.empty()) {
-    swapped_presentation_callbacks_.front().Run(timebase, interval);
-    swapped_presentation_callbacks_.pop_front();
-  }
-  // VSync parameters updates are generated at the start of a new swap. Move
-  // the swapping presentation callbacks to swapped callbacks so they fire
-  // at the next VSync parameters update as that will contain the presentation
-  // time for the previous frame.
-  swapped_presentation_callbacks_.splice(swapped_presentation_callbacks_.end(),
-                                         swapping_presentation_callbacks_);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ui::ContextFactoryObserver overrides:
-
-void SurfaceTreeHost::OnLostResources() {
-  if (!host_window_->GetSurfaceId().is_valid())
-    return;
-  root_surface_->RecreateResources(layer_tree_frame_sink_holder_.get());
-  SubmitCompositorFrame(Surface::FRAME_TYPE_RECREATED_RESOURCES);
-}
-
-void SurfaceTreeHost::SubmitCompositorFrame(Surface::FrameType frame_type) {
-  DCHECK(root_surface_);
-  cc::CompositorFrame frame;
-  // If we commit while we don't have an active BeginFrame, we acknowledge a
-  // manual one.
-  if (current_begin_frame_ack_.sequence_number ==
-      cc::BeginFrameArgs::kInvalidFrameNumber) {
-    current_begin_frame_ack_ = cc::BeginFrameAck::CreateManualAckWithDamage();
-  } else {
-    current_begin_frame_ack_.has_damage = true;
-  }
-
-  frame.metadata.begin_frame_ack = current_begin_frame_ack_;
-  frame.metadata.device_scale_factor =
-      host_window_->layer()->device_scale_factor();
-  const int kRenderPassId = 1;
-  std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
-  render_pass->SetNew(kRenderPassId, gfx::Rect(), gfx::Rect(),
-                      gfx::Transform());
-  frame.render_pass_list.push_back(std::move(render_pass));
-  root_surface_->CommitSurfaceHierarchy(
-      gfx::Point(), frame_type, layer_tree_frame_sink_holder_.get(), &frame,
-      &frame_callbacks_, &presentation_callbacks_);
-  frame.render_pass_list.back()->output_rect =
-      gfx::Rect(root_surface_->content_size());
-  layer_tree_frame_sink_holder_->frame_sink()->SubmitCompositorFrame(
-      std::move(frame));
-  host_window_->SetBounds(gfx::Rect(host_window_->bounds().origin(),
-                                    root_surface_->content_size()));
-  host_window_->layer()->SetFillsBoundsOpaquely(
-      root_surface_->FillsBoundsOpaquely());
-
-  if (current_begin_frame_ack_.sequence_number !=
-      cc::BeginFrameArgs::kInvalidFrameNumber) {
-    if (!current_begin_frame_ack_.has_damage) {
-      layer_tree_frame_sink_holder_->frame_sink()->DidNotProduceFrame(
-          current_begin_frame_ack_);
-    }
-    current_begin_frame_ack_.sequence_number =
-        cc::BeginFrameArgs::kInvalidFrameNumber;
-    if (begin_frame_source_)
-      begin_frame_source_->DidFinishFrame(this);
-  }
-}
-
 }  // namespace exo
diff --git a/components/exo/surface_tree_host.h b/components/exo/surface_tree_host.h
index e102766a..c92a434 100644
--- a/components/exo/surface_tree_host.h
+++ b/components/exo/surface_tree_host.h
@@ -8,12 +8,8 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "components/exo/layer_tree_frame_sink_holder.h"
 #include "components/exo/surface.h"
 #include "components/exo/surface_delegate.h"
-#include "ui/aura/window_observer.h"
-#include "ui/compositor/compositor_vsync_manager.h"
 #include "ui/gfx/geometry/rect.h"
 
 namespace aura {
@@ -21,24 +17,15 @@
 class WindowDelegate;
 }  // namespace aura
 
-namespace cc {
-class BeginFrameSource;
-}  // namespace cc
-
 namespace gfx {
 class Path;
 }  // namespace gfx
 
 namespace exo {
-class LayerTreeFrameSinkHolder;
 
 // This class provides functionality for hosting a surface tree. The surface
 // tree is hosted in the |host_window_|.
-class SurfaceTreeHost : public SurfaceDelegate,
-                        public aura::WindowObserver,
-                        public cc::BeginFrameObserverBase,
-                        public ui::CompositorVSyncManager::Observer,
-                        public ui::ContextFactoryObserver {
+class SurfaceTreeHost : public SurfaceDelegate {
  public:
   SurfaceTreeHost(const std::string& window_name,
                   aura::WindowDelegate* window_delegate);
@@ -61,77 +48,19 @@
   // registered then CursorType::kNull is returned.
   gfx::NativeCursor GetCursor(const gfx::Point& point) const;
 
-  // Call this to indicate that the previous CompositorFrame is processed and
-  // the surface is being scheduled for a draw.
-  void DidReceiveCompositorFrameAck();
-
-  // Called when the begin frame source has changed.
-  void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source);
-
-  // Adds/Removes begin frame observer based on state.
-  void UpdateNeedsBeginFrame();
-
   aura::Window* host_window() { return host_window_.get(); }
   const aura::Window* host_window() const { return host_window_.get(); }
 
   Surface* root_surface() { return root_surface_; }
   const Surface* root_surface() const { return root_surface_; }
 
-  LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder() {
-    return layer_tree_frame_sink_holder_.get();
-  }
-
   // Overridden from SurfaceDelegate:
   void OnSurfaceCommit() override;
   bool IsSurfaceSynchronized() const override;
 
-  // Overridden from aura::WindowObserver:
-  void OnWindowAddedToRootWindow(aura::Window* window) override;
-  void OnWindowRemovingFromRootWindow(aura::Window* window,
-                                      aura::Window* new_root) override;
-  void OnWindowDestroying(aura::Window* window) override;
-
-  // Overridden from cc::BeginFrameObserverBase:
-  bool OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) override;
-  void OnBeginFrameSourcePausedChanged(bool paused) override {}
-
-  // Overridden from ui::CompositorVSyncManager::Observer:
-  void OnUpdateVSyncParameters(base::TimeTicks timebase,
-                               base::TimeDelta interval) override;
-
-  // Overridden from ui::ContextFactoryObserver:
-  void OnLostResources() override;
-
  private:
-  void SubmitCompositorFrame(Surface::FrameType frame_type);
-
   Surface* root_surface_ = nullptr;
   std::unique_ptr<aura::Window> host_window_;
-  std::unique_ptr<LayerTreeFrameSinkHolder> layer_tree_frame_sink_holder_;
-
-  // The begin frame source being observed.
-  cc::BeginFrameSource* begin_frame_source_ = nullptr;
-  bool needs_begin_frame_ = false;
-  cc::BeginFrameAck current_begin_frame_ack_;
-
-  // These lists contain the callbacks to notify the client when it is a good
-  // time to start producing a new frame. These callbacks move to
-  // |frame_callbacks_| when Commit() is called. Later they are moved to
-  // |active_frame_callbacks_| when the effect of the Commit() is scheduled to
-  // be drawn. They fire at the first begin frame notification after this.
-  std::list<Surface::FrameCallback> frame_callbacks_;
-  std::list<Surface::FrameCallback> active_frame_callbacks_;
-
-  // These lists contains the callbacks to notify the client when surface
-  // contents have been presented. These callbacks move to
-  // |presentation_callbacks_| when Commit() is called. Later they are moved to
-  // |swapping_presentation_callbacks_| when the effect of the Commit() is
-  // scheduled to be drawn and then moved to |swapped_presentation_callbacks_|
-  // after receiving VSync parameters update for the previous frame. They fire
-  // at the next VSync parameters update after that.
-  std::list<Surface::PresentationCallback> presentation_callbacks_;
-  std::list<Surface::PresentationCallback> swapping_presentation_callbacks_;
-  std::list<Surface::PresentationCallback> swapped_presentation_callbacks_;
 
   DISALLOW_COPY_AND_ASSIGN(SurfaceTreeHost);
 };
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc
index d8f7f63..d638abc 100644
--- a/components/exo/surface_unittest.cc
+++ b/components/exo/surface_unittest.cc
@@ -9,13 +9,11 @@
 #include "cc/test/begin_frame_args_test.h"
 #include "cc/test/fake_external_begin_frame_source.h"
 #include "components/exo/buffer.h"
-#include "components/exo/shell_surface.h"
 #include "components/exo/surface.h"
 #include "components/exo/test/exo_test_base.h"
 #include "components/exo/test/exo_test_helper.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/khronos/GLES2/gl2.h"
 #include "ui/aura/env.h"
 #include "ui/compositor/layer_tree_owner.h"
 #include "ui/gfx/gpu_memory_buffer.h"
@@ -101,8 +99,8 @@
   EXPECT_TRUE(frame_time.is_null());
 }
 
-const cc::CompositorFrame& GetFrameFromSurface(ShellSurface* shell_surface) {
-  viz::SurfaceId surface_id = shell_surface->host_window()->GetSurfaceId();
+const cc::CompositorFrame& GetFrameFromSurface(Surface* surface) {
+  viz::SurfaceId surface_id = surface->GetSurfaceId();
   cc::SurfaceManager* surface_manager = aura::Env::GetInstance()
                                             ->context_factory_private()
                                             ->GetFrameSinkManager()
@@ -114,10 +112,9 @@
 
 TEST_F(SurfaceTest, SetOpaqueRegion) {
   gfx::Size buffer_size(1, 1);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
-  auto surface = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(surface.get());
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface(new Surface);
 
   // Attaching a buffer with alpha channel.
   surface->Attach(buffer.get());
@@ -129,7 +126,7 @@
   RunAllPendingInMessageLoop();
 
   {
-    const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
+    const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get());
     ASSERT_EQ(1u, frame.render_pass_list.size());
     ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
     EXPECT_FALSE(frame.render_pass_list.back()
@@ -143,7 +140,7 @@
   RunAllPendingInMessageLoop();
 
   {
-    const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
+    const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get());
     ASSERT_EQ(1u, frame.render_pass_list.size());
     ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
     EXPECT_TRUE(frame.render_pass_list.back()
@@ -162,7 +159,7 @@
   RunAllPendingInMessageLoop();
 
   {
-    const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
+    const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get());
     ASSERT_EQ(1u, frame.render_pass_list.size());
     ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
     EXPECT_FALSE(frame.render_pass_list.back()
@@ -183,10 +180,9 @@
 
 TEST_F(SurfaceTest, SetBufferScale) {
   gfx::Size buffer_size(512, 512);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
-  auto surface = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(surface.get());
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface(new Surface);
 
   // This will update the bounds of the surface and take the buffer scale into
   // account.
@@ -204,10 +200,9 @@
 
 TEST_F(SurfaceTest, MirrorLayers) {
   gfx::Size buffer_size(512, 512);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
-  auto surface = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(surface.get());
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface(new Surface);
 
   surface->Attach(buffer.get());
   surface->Commit();
@@ -215,20 +210,19 @@
   EXPECT_EQ(buffer_size, surface->window()->bounds().size());
   EXPECT_EQ(buffer_size, surface->window()->layer()->bounds().size());
   std::unique_ptr<ui::LayerTreeOwner> old_layer_owner =
-      ::wm::MirrorLayers(shell_surface->host_window(), false /* sync_bounds */);
+      ::wm::MirrorLayers(surface->window(), false /* sync_bounds */);
   EXPECT_EQ(buffer_size, surface->window()->bounds().size());
   EXPECT_EQ(buffer_size, surface->window()->layer()->bounds().size());
   EXPECT_EQ(buffer_size, old_layer_owner->root()->bounds().size());
-  EXPECT_TRUE(shell_surface->host_window()->layer()->has_external_content());
+  EXPECT_TRUE(surface->window()->layer()->has_external_content());
   EXPECT_TRUE(old_layer_owner->root()->has_external_content());
 }
 
 TEST_F(SurfaceTest, SetViewport) {
   gfx::Size buffer_size(1, 1);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
-  auto surface = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(surface.get());
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface(new Surface);
 
   // This will update the bounds of the surface and take the viewport into
   // account.
@@ -250,10 +244,9 @@
 
 TEST_F(SurfaceTest, SetCrop) {
   gfx::Size buffer_size(16, 16);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
-  auto surface = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(surface.get());
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface(new Surface);
 
   surface->Attach(buffer.get());
   gfx::Size crop_size(12, 12);
@@ -266,17 +259,16 @@
 
 TEST_F(SurfaceTest, SetBlendMode) {
   gfx::Size buffer_size(1, 1);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
-  auto surface = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(surface.get());
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface(new Surface);
 
   surface->Attach(buffer.get());
   surface->SetBlendMode(SkBlendMode::kSrc);
   surface->Commit();
   RunAllPendingInMessageLoop();
 
-  const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
+  const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get());
   ASSERT_EQ(1u, frame.render_pass_list.size());
   ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
   EXPECT_FALSE(frame.render_pass_list.back()
@@ -286,17 +278,15 @@
 
 TEST_F(SurfaceTest, OverlayCandidate) {
   gfx::Size buffer_size(1, 1);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D, 0,
-      true, true);
-  auto surface = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(surface.get());
+  std::unique_ptr<Buffer> buffer(new Buffer(
+      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), 0, 0, true, true));
+  std::unique_ptr<Surface> surface(new Surface);
 
   surface->Attach(buffer.get());
   surface->Commit();
   RunAllPendingInMessageLoop();
 
-  const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
+  const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get());
   ASSERT_EQ(1u, frame.render_pass_list.size());
   ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
   cc::DrawQuad* draw_quad = frame.render_pass_list.back()->quad_list.back();
@@ -309,11 +299,9 @@
 
 TEST_F(SurfaceTest, SetAlpha) {
   gfx::Size buffer_size(1, 1);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D, 0,
-      true, true);
-  auto surface = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(surface.get());
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface(new Surface);
 
   surface->Attach(buffer.get());
   surface->SetAlpha(0.5f);
@@ -330,12 +318,10 @@
 TEST_F(SurfaceTest, SendsBeginFrameAcks) {
   cc::FakeExternalBeginFrameSource source(0.f, false);
   gfx::Size buffer_size(1, 1);
-  auto buffer = base::MakeUnique<Buffer>(
-      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D, 0,
-      true, true);
-  auto surface = base::MakeUnique<Surface>();
-  auto shell_surface = base::MakeUnique<ShellSurface>(surface.get());
-  shell_surface->SetBeginFrameSource(&source);
+  std::unique_ptr<Buffer> buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface(new Surface);
+  surface->SetBeginFrameSource(&source);
   surface->Attach(buffer.get());
 
   // Request a frame callback so that Surface now needs BeginFrames.
@@ -347,7 +333,7 @@
 
   // Surface should add itself as observer during
   // DidReceiveCompositorFrameAck().
-  shell_surface->DidReceiveCompositorFrameAck();
+  surface->DidReceiveCompositorFrameAck();
   EXPECT_EQ(1u, source.num_observers());
 
   cc::BeginFrameArgs args(source.CreateBeginFrameArgs(BEGINFRAME_FROM_HERE));
@@ -358,7 +344,7 @@
   surface->Commit();  // Acknowledges the BeginFrame via CompositorFrame.
   RunAllPendingInMessageLoop();
 
-  const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
+  const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get());
   cc::BeginFrameAck expected_ack(args.source_id, args.sequence_number, true);
   EXPECT_EQ(expected_ack, frame.metadata.begin_frame_ack);
 
diff --git a/components/exo/test/exo_test_base.h b/components/exo/test/exo_test_base.h
index df5de17..c1b391ae 100644
--- a/components/exo/test/exo_test_base.h
+++ b/components/exo/test/exo_test_base.h
@@ -16,7 +16,7 @@
 namespace test {
 class ExoTestHelper;
 
-class ExoTestBase : public ash::test::AshTestBase {
+class ExoTestBase : public ash::AshTestBase {
  public:
   ExoTestBase();
   ~ExoTestBase() override;
diff --git a/components/exo/test/run_all_unittests.cc b/components/exo/test/run_all_unittests.cc
index 5423a8e9..ffa9439 100644
--- a/components/exo/test/run_all_unittests.cc
+++ b/components/exo/test/run_all_unittests.cc
@@ -11,7 +11,7 @@
 #endif
 
 int main(int argc, char** argv) {
-  ash::test::AshTestSuite test_suite(argc, argv);
+  ash::AshTestSuite test_suite(argc, argv);
 
 #if !defined(OS_IOS)
   mojo::edk::Init();
@@ -19,5 +19,5 @@
 
   return base::LaunchUnitTestsSerially(
       argc, argv,
-      base::Bind(&ash::test::AshTestSuite::Run, base::Unretained(&test_suite)));
+      base::Bind(&ash::AshTestSuite::Run, base::Unretained(&test_suite)));
 }
diff --git a/components/filesystem/file_impl.cc b/components/filesystem/file_impl.cc
index 12ddb8a8b..e853a91 100644
--- a/components/filesystem/file_impl.cc
+++ b/components/filesystem/file_impl.cc
@@ -62,6 +62,7 @@
   return file_.IsValid();
 }
 
+#if !defined(OS_FUCHSIA)
 base::File::Error FileImpl::RawLockFile() {
   return file_.Lock();
 }
@@ -69,6 +70,7 @@
 base::File::Error FileImpl::RawUnlockFile() {
   return file_.Unlock();
 }
+#endif  // !OS_FUCHSIA
 
 void FileImpl::Close(CloseCallback callback) {
   if (!file_.IsValid()) {
diff --git a/components/filesystem/file_impl.h b/components/filesystem/file_impl.h
index 550f43b2..3b7db2ea2 100644
--- a/components/filesystem/file_impl.h
+++ b/components/filesystem/file_impl.h
@@ -10,6 +10,7 @@
 #include "base/files/file.h"
 #include "base/files/scoped_file.h"
 #include "base/macros.h"
+#include "build/build_config.h"
 #include "components/filesystem/public/interfaces/directory.mojom.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 
@@ -37,10 +38,12 @@
   // Returns whether the underlying file handle is valid.
   bool IsValid() const;
 
+#if !defined(OS_FUCHSIA)
   // Attempts to perform the native operating system's locking operations on
-  // the internal mojom::File handle
+  // the internal mojom::File handle. Not supported on Fuchsia.
   base::File::Error RawLockFile();
   base::File::Error RawUnlockFile();
+#endif  // !OS_FUCHSIA
 
   const base::FilePath& path() const { return path_; }
 
diff --git a/components/filesystem/lock_table.cc b/components/filesystem/lock_table.cc
index 4f43672..badbbad 100644
--- a/components/filesystem/lock_table.cc
+++ b/components/filesystem/lock_table.cc
@@ -4,6 +4,7 @@
 
 #include "components/filesystem/lock_table.h"
 
+#include "build/build_config.h"
 #include "components/filesystem/file_impl.h"
 
 namespace filesystem {
@@ -22,11 +23,20 @@
     return base::File::FILE_ERROR_FAILED;
   }
 
+#if !defined(OS_FUCHSIA)
+  // Fuchsia doesn't provide a file locking mechanism, so file locks work only
+  // within a single process. File locking is used only by LevelDB which stores
+  // all files in the profile directory and normally there shouldn't be more
+  // than a single chrome process per profile. So in-process locks should be
+  // sufficient.
+  // TODO(fuchsia): Investigate if it's necessary to implement cross-process
+  // file locks. crbug.com/744893 .
   base::File::Error lock_err = file->RawLockFile();
   if (lock_err != base::File::FILE_OK) {
     // Locking failed for some reason.
     return lock_err;
   }
+#endif  // !OS_FUCHSIA
 
   locked_files_.insert(file->path());
   return base::File::FILE_OK;
@@ -35,12 +45,14 @@
 base::File::Error LockTable::UnlockFile(FileImpl* file) {
   auto it = locked_files_.find(file->path());
   if (it != locked_files_.end()) {
+#if !defined(OS_FUCHSIA)
     base::File::Error lock_err = file->RawUnlockFile();
     if (lock_err != base::File::FILE_OK) {
       // TODO(erg): When can we fail to release a lock?
       NOTREACHED();
       return lock_err;
     }
+#endif  // !OS_FUCHSIA
 
     locked_files_.erase(it);
   }
diff --git a/components/nacl/renderer/manifest_downloader.cc b/components/nacl/renderer/manifest_downloader.cc
index bd508cb..8248021 100644
--- a/components/nacl/renderer/manifest_downloader.cc
+++ b/components/nacl/renderer/manifest_downloader.cc
@@ -78,11 +78,11 @@
         pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_NOACCESS_URL;
         break;
     }
-  } else {
-    // It's a WebKit error.
-    pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_NOACCESS_URL;
   }
 
+  if (error.is_web_security_violation)
+    pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_NOACCESS_URL;
+
   Close();
 }
 
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index e6677737..9b30e37 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -457,6 +457,13 @@
                       old_primary_key ? &old_primary_key.value() : nullptr);
 }
 
+void PasswordFormManager::UpdateUsername(const base::string16& new_username) {
+  pending_credentials_.username_value = new_username;
+  // Check if the username already exists.
+  const PasswordForm* match = FindBestSavedMatch(&pending_credentials_);
+  is_new_login_ = !match || match->is_public_suffix_match;
+}
+
 void PasswordFormManager::PresaveGeneratedPassword(
     const autofill::PasswordForm& form) {
   form_saver()->PresaveGeneratedPassword(form);
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h
index 2cf48e7..0d0317c 100644
--- a/components/password_manager/core/browser/password_form_manager.h
+++ b/components/password_manager/core/browser/password_form_manager.h
@@ -155,6 +155,11 @@
   // |pending_credentials_|.
   void Update(const autofill::PasswordForm& credentials_to_update);
 
+  // Updates the username value. Called when user edits the username and clicks
+  // the save button. Updates the username and modifies internal state
+  // accordingly. This function should be called after ProvisionallySave().
+  void UpdateUsername(const base::string16& new_username);
+
   // Call these if/when we know the form submission worked or failed.
   // These routines are used to update internal statistics ("ActionsTaken").
   void LogSubmitPassed();
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index de82490..ba7573e2 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -53,9 +53,11 @@
 using autofill::PossibleUsernamePair;
 using base::ASCIIToUTF16;
 using ::testing::_;
+using ::testing::ElementsAre;
 using ::testing::IsEmpty;
 using ::testing::Mock;
 using ::testing::NiceMock;
+using ::testing::Pair;
 using ::testing::Pointee;
 using ::testing::Return;
 using ::testing::SaveArg;
@@ -2287,6 +2289,104 @@
   EXPECT_EQ(saved_match()->submit_element, new_credentials.submit_element);
 }
 
+// Test that when user updates username, the pending credentials is updated
+// accordingly.
+TEST_F(PasswordFormManagerTest, TestUpdateUsernameMethod) {
+  fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
+
+  // User logs in, edits username.
+  PasswordForm credential(*observed_form());
+  credential.username_value = ASCIIToUTF16("oldusername");
+  credential.password_value = ASCIIToUTF16("password");
+  form_manager()->ProvisionallySave(
+      credential, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
+  form_manager()->UpdateUsername(ASCIIToUTF16("newusername"));
+  EXPECT_EQ(form_manager()->pending_credentials().username_value,
+            ASCIIToUTF16("newusername"));
+  EXPECT_EQ(form_manager()->pending_credentials().password_value,
+            ASCIIToUTF16("password"));
+  EXPECT_EQ(form_manager()->IsNewLogin(), true);
+
+  // User clicks save, edited username is saved.
+  PasswordForm saved_result;
+  EXPECT_CALL(MockFormSaver::Get(form_manager()), Save(_, IsEmpty(), nullptr))
+      .WillOnce(SaveArg<0>(&saved_result));
+  form_manager()->Save();
+  EXPECT_EQ(ASCIIToUTF16("newusername"), saved_result.username_value);
+  EXPECT_EQ(ASCIIToUTF16("password"), saved_result.password_value);
+}
+
+// Test that when user updates username to an already existing one, is_new_login
+// status is false.
+TEST_F(PasswordFormManagerTest, TestUpdateUsernameToExisting) {
+  // We have an already existing credential.
+  fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
+
+  // User submits credential to the observed form.
+  PasswordForm credential(*observed_form());
+  credential.username_value = ASCIIToUTF16("different_username");
+  credential.password_value = ASCIIToUTF16("different_pass");
+  credential.preferred = true;
+  form_manager()->ProvisionallySave(
+      credential, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
+
+  // User edits the username to the already existing one.
+  form_manager()->UpdateUsername(saved_match()->username_value);
+
+  // The username in credentials is expected to be updated.
+  EXPECT_EQ(saved_match()->username_value,
+            form_manager()->pending_credentials().username_value);
+  EXPECT_EQ(ASCIIToUTF16("different_pass"),
+            form_manager()->pending_credentials().password_value);
+  EXPECT_EQ(form_manager()->IsNewLogin(), false);
+
+  // Create the expected variables for the test.
+  PasswordForm expected_pending(credential);
+  expected_pending.times_used = 1;
+  expected_pending.username_value = saved_match()->username_value;
+
+  // User clicks save, edited username is saved, password updated.
+  PasswordForm saved_result;
+  EXPECT_CALL(MockFormSaver::Get(form_manager()),
+              Update(expected_pending,
+                     ElementsAre(Pair(saved_match()->username_value,
+                                      Pointee(*saved_match()))),
+                     Pointee(IsEmpty()), nullptr));
+  form_manager()->Save();
+}
+
+// Test that when user updates username to a PSL matching credential, we should
+// handle it as a new login.
+TEST_F(PasswordFormManagerTest, TestUpdatePSLUsername) {
+  fake_form_fetcher()->SetNonFederated({psl_saved_match()}, 0u);
+  // User submits credential to the observed form.
+  PasswordForm credential(*observed_form());
+  credential.username_value = ASCIIToUTF16("some_username");
+  credential.password_value = ASCIIToUTF16("some_pass");
+  form_manager()->ProvisionallySave(
+      credential, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
+
+  // User edits username to match the PSL.
+  form_manager()->UpdateUsername(psl_saved_match()->username_value);
+  EXPECT_EQ(psl_saved_match()->username_value,
+            form_manager()->pending_credentials().username_value);
+  EXPECT_EQ(true, form_manager()->IsNewLogin());
+  EXPECT_EQ(ASCIIToUTF16("some_pass"),
+            form_manager()->pending_credentials().password_value);
+
+  // User clicks save, edited username is saved.
+  PasswordForm saved_result;
+  EXPECT_CALL(MockFormSaver::Get(form_manager()),
+              Save(_,
+                   ElementsAre(Pair(psl_saved_match()->username_value,
+                                    Pointee(*psl_saved_match()))),
+                   nullptr))
+      .WillOnce(SaveArg<0>(&saved_result));
+  form_manager()->Save();
+  EXPECT_EQ(psl_saved_match()->username_value, saved_result.username_value);
+  EXPECT_EQ(ASCIIToUTF16("some_pass"), saved_result.password_value);
+}
+
 // Test that if WipeStoreCopyIfOutdated is called before password store
 // callback, the UMA is signalled accordingly.
 TEST_F(PasswordFormManagerTest, WipeStoreCopyIfOutdated_BeforeStoreCallback) {
diff --git a/components/printing/renderer/print_web_view_helper.cc b/components/printing/renderer/print_web_view_helper.cc
index ca63359..3c9dfc0 100644
--- a/components/printing/renderer/print_web_view_helper.cc
+++ b/components/printing/renderer/print_web_view_helper.cc
@@ -1572,11 +1572,13 @@
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
     case FAIL_PREVIEW:
-      if (notify_browser_of_print_failure_) {
-        LOG(ERROR) << "CreatePreviewDocument failed";
-        Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie));
-      } else {
-        Send(new PrintHostMsg_PrintPreviewCancelled(routing_id(), cookie));
+      if (!is_print_ready_metafile_sent_) {
+        if (notify_browser_of_print_failure_) {
+          LOG(ERROR) << "CreatePreviewDocument failed";
+          Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie));
+        } else {
+          Send(new PrintHostMsg_PrintPreviewCancelled(routing_id(), cookie));
+        }
       }
       print_preview_context_.Failed(notify_browser_of_print_failure_);
       break;
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AuthException.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AuthException.java
index 7b42c9b..1101f23e 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AuthException.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AuthException.java
@@ -9,15 +9,31 @@
  * It is used for passing information that is useful for better handling of errors.
  */
 public class AuthException extends Exception {
+    public static final boolean TRANSIENT = true;
+    public static final boolean NONTRANSIENT = false;
+
     private final boolean mIsTransientError;
 
     /**
-     * A simple constructor that stores all the error handling information and makes it available to
-     * the handler.
+     * Wraps exception that caused auth failure along with transience flag.
      * @param isTransientError Whether the error is transient and we can retry.
+     *         Use {@link #TRANSIENT} and {@link #NONTRANSIENT} for readability.
+     * @param cause Exception that caused auth failure.
      */
-    public AuthException(boolean isTransientError, Exception exception) {
-        super(exception);
+    public AuthException(boolean isTransientError, Exception cause) {
+        super(cause);
+        mIsTransientError = isTransientError;
+    }
+
+    /**
+     * Wraps exception that caused auth failure along with transience flag and message.
+     * @param isTransientError Whether the error is transient and we can retry.
+     *         Use {@link #TRANSIENT} and {@link #NONTRANSIENT} for readability.
+     * @param message Message describing context in which auth failure happened.
+     * @param cause Exception that caused auth failure.
+     */
+    public AuthException(boolean isTransientError, String message, Exception cause) {
+        super(message, cause);
         mIsTransientError = isTransientError;
     }
 
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
index 784ec7c..437861b 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
@@ -102,10 +102,10 @@
         } catch (GoogleAuthException ex) {
             // This case includes a UserRecoverableNotifiedException, but most clients will have
             // their own retry mechanism anyway.
-            // TODO(bauerb): Investigate integrating the callback with ConnectionRetry.
-            throw new AuthException(false /* isTransientError */, ex);
+            throw new AuthException(AuthException.NONTRANSIENT,
+                    "Error while getting token for scope '" + authTokenScope + "'", ex);
         } catch (IOException ex) {
-            throw new AuthException(true /* isTransientError */, ex);
+            throw new AuthException(AuthException.TRANSIENT, ex);
         }
     }
 
@@ -114,11 +114,11 @@
         try {
             GoogleAuthUtil.clearToken(ContextUtils.getApplicationContext(), authToken);
         } catch (GooglePlayServicesAvailabilityException ex) {
-            throw new AuthException(false /* isTransientError */, ex);
+            throw new AuthException(AuthException.NONTRANSIENT, ex);
         } catch (GoogleAuthException ex) {
-            throw new AuthException(false /* isTransientError */, ex);
+            throw new AuthException(AuthException.NONTRANSIENT, ex);
         } catch (IOException ex) {
-            throw new AuthException(true /* isTransientError */, ex);
+            throw new AuthException(AuthException.TRANSIENT, ex);
         }
     }
 
diff --git a/components/translate/core/browser/mock_translate_driver.cc b/components/translate/core/browser/mock_translate_driver.cc
index 22de90a..2e064e56 100644
--- a/components/translate/core/browser/mock_translate_driver.cc
+++ b/components/translate/core/browser/mock_translate_driver.cc
@@ -14,7 +14,8 @@
     : on_is_page_translated_changed_called_(false),
       on_translate_enabled_changed_called_(false),
       translate_page_is_called_(false),
-      language_state_(this) {}
+      language_state_(this),
+      last_committed_url_(GURL::EmptyGURL()) {}
 
 void MockTranslateDriver::TranslatePage(int page_seq_no,
                                         const std::string& translate_script,
@@ -50,7 +51,7 @@
 }
 
 const GURL&  MockTranslateDriver::GetLastCommittedURL() {
-  return GURL::EmptyGURL();
+  return last_committed_url_;
 }
 
 const GURL& MockTranslateDriver::GetVisibleURL() {
@@ -61,6 +62,10 @@
   return true;
 }
 
+void MockTranslateDriver::SetLastCommittedURL(const GURL& url) {
+  last_committed_url_ = url;
+}
+
 }  // namespace testing
 
 }  // namespace translate
diff --git a/components/translate/core/browser/mock_translate_driver.h b/components/translate/core/browser/mock_translate_driver.h
index 3164bdb..cf6957f 100644
--- a/components/translate/core/browser/mock_translate_driver.h
+++ b/components/translate/core/browser/mock_translate_driver.h
@@ -60,11 +60,14 @@
 
   bool TranslatePage_is_called() const { return translate_page_is_called_; }
 
+  void SetLastCommittedURL(const GURL& url);
+
  private:
   bool on_is_page_translated_changed_called_;
   bool on_translate_enabled_changed_called_;
   bool translate_page_is_called_;
   LanguageState language_state_;
+  GURL last_committed_url_;
 
   DISALLOW_COPY_AND_ASSIGN(MockTranslateDriver);
 };
diff --git a/components/translate/core/browser/translate_ui_delegate.h b/components/translate/core/browser/translate_ui_delegate.h
index 230a68c..0811da7 100644
--- a/components/translate/core/browser/translate_ui_delegate.h
+++ b/components/translate/core/browser/translate_ui_delegate.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include "base/gtest_prod_util.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -122,6 +123,8 @@
   bool ShouldAlwaysTranslateBeCheckedByDefault();
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(TranslateUIDelegateTest, GetPageHost);
+
   // Gets the host of the page being translated, or an empty string if no URL is
   // associated with the current page.
   std::string GetPageHost();
diff --git a/components/translate/core/browser/translate_ui_delegate_unittest.cc b/components/translate/core/browser/translate_ui_delegate_unittest.cc
index 679ee011..96b2805 100644
--- a/components/translate/core/browser/translate_ui_delegate_unittest.cc
+++ b/components/translate/core/browser/translate_ui_delegate_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "components/infobars/core/infobar.h"
 #include "components/metrics/proto/translate_event.pb.h"
@@ -26,6 +27,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
+using testing::_;
 using testing::Return;
 using testing::Test;
 using translate::testing::MockTranslateClient;
@@ -70,6 +72,11 @@
 };
 
 TEST_F(TranslateUIDelegateTest, CheckDeclinedFalse) {
+  EXPECT_CALL(*ranker_, RecordTranslateEvent(
+                            metrics::TranslateEventProto::USER_IGNORE, _, _))
+      .Times(1);
+  EXPECT_CALL(*client_, RecordTranslateEvent(_)).Times(1);
+
   std::unique_ptr<TranslatePrefs> prefs(client_->GetTranslatePrefs());
   for (int i = 0; i < 10; i++) {
     prefs->IncrementTranslationAcceptedCount("ar");
@@ -89,6 +96,11 @@
 }
 
 TEST_F(TranslateUIDelegateTest, CheckDeclinedTrue) {
+  EXPECT_CALL(*ranker_, RecordTranslateEvent(
+                            metrics::TranslateEventProto::USER_DECLINE, _, _))
+      .Times(1);
+  EXPECT_CALL(*client_, RecordTranslateEvent(_)).Times(1);
+
   std::unique_ptr<TranslatePrefs> prefs(client_->GetTranslatePrefs());
   for (int i = 0; i < 10; i++) {
     prefs->IncrementTranslationAcceptedCount("ar");
@@ -106,6 +118,13 @@
 }
 
 TEST_F(TranslateUIDelegateTest, SetLanguageBlocked) {
+  EXPECT_CALL(
+      *ranker_,
+      RecordTranslateEvent(
+          metrics::TranslateEventProto::USER_NEVER_TRANSLATE_LANGUAGE, _, _))
+      .Times(1);
+  EXPECT_CALL(*client_, RecordTranslateEvent(_)).Times(1);
+
   std::unique_ptr<TranslatePrefs> prefs(client_->GetTranslatePrefs());
   manager_->GetLanguageState().SetTranslateEnabled(true);
   EXPECT_TRUE(manager_->GetLanguageState().translate_enabled());
@@ -162,8 +181,35 @@
   EXPECT_FALSE(delegate_->ShouldAlwaysTranslateBeCheckedByDefault());
 }
 
-// TODO(ftang) Currently this file only test TranslationDeclined(), we
-// need to add the test for other functions soon to increase the test
-// coverage.
+TEST_F(TranslateUIDelegateTest, LanguageCodes) {
+  // Test language codes.
+  EXPECT_EQ("ar", delegate_->GetOriginalLanguageCode());
+  EXPECT_EQ("fr", delegate_->GetTargetLanguageCode());
+
+  // Test language indicies.
+  const size_t ar_index = delegate_->GetOriginalLanguageIndex();
+  EXPECT_EQ("ar", delegate_->GetLanguageCodeAt(ar_index));
+  const size_t fr_index = delegate_->GetTargetLanguageIndex();
+  EXPECT_EQ("fr", delegate_->GetLanguageCodeAt(fr_index));
+
+  // Test updating original / target codes.
+  delegate_->UpdateOriginalLanguage("es");
+  EXPECT_EQ("es", delegate_->GetOriginalLanguageCode());
+  delegate_->UpdateTargetLanguage("de");
+  EXPECT_EQ("de", delegate_->GetTargetLanguageCode());
+
+  // Test updating original / target indicies. Note that this also returns
+  // the delegate to the starting state.
+  delegate_->UpdateOriginalLanguageIndex(ar_index);
+  EXPECT_EQ("ar", delegate_->GetOriginalLanguageCode());
+  delegate_->UpdateTargetLanguageIndex(fr_index);
+  EXPECT_EQ("fr", delegate_->GetTargetLanguageCode());
+}
+
+TEST_F(TranslateUIDelegateTest, GetPageHost) {
+  const GURL url("https://www.example.com/hello/world?fg=1");
+  driver_.SetLastCommittedURL(url);
+  EXPECT_EQ("www.example.com", delegate_->GetPageHost());
+}
 
 }  // namespace translate
diff --git a/content/browser/image_capture/image_capture_impl.cc b/content/browser/image_capture/image_capture_impl.cc
index cf174a9d..30ff2ff 100644
--- a/content/browser/image_capture/image_capture_impl.cc
+++ b/content/browser/image_capture/image_capture_impl.cc
@@ -37,17 +37,17 @@
   empty_capabilities->contrast = media::mojom::Range::New();
   empty_capabilities->saturation = media::mojom::Range::New();
   empty_capabilities->sharpness = media::mojom::Range::New();
-  cb.Run(std::move(empty_capabilities));
+  std::move(cb).Run(std::move(empty_capabilities));
 }
 
 void RunFailedSetOptionsCallback(ImageCaptureImpl::SetOptionsCallback cb) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  cb.Run(false);
+  std::move(cb).Run(false);
 }
 
 void RunFailedTakePhotoCallback(ImageCaptureImpl::TakePhotoCallback cb) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  cb.Run(media::mojom::Blob::New());
+  std::move(cb).Run(media::mojom::Blob::New());
 }
 
 void GetPhotoStateOnIOThread(
@@ -120,12 +120,13 @@
 }
 
 void ImageCaptureImpl::GetPhotoState(const std::string& source_id,
-                                     const GetPhotoStateCallback& callback) {
+                                     GetPhotoStateCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   media::ScopedResultCallback<GetPhotoStateCallback> scoped_callback(
-      media::BindToCurrentLoop(callback),
-      media::BindToCurrentLoop(base::Bind(&RunFailedGetPhotoStateCallback)));
+      media::BindToCurrentLoop(std::move(callback)),
+      media::BindToCurrentLoop(
+          base::BindOnce(&RunFailedGetPhotoStateCallback)));
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
@@ -136,11 +137,11 @@
 
 void ImageCaptureImpl::SetOptions(const std::string& source_id,
                                   media::mojom::PhotoSettingsPtr settings,
-                                  const SetOptionsCallback& callback) {
+                                  SetOptionsCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   media::ScopedResultCallback<SetOptionsCallback> scoped_callback(
-      media::BindToCurrentLoop(callback),
+      media::BindToCurrentLoop(std::move(callback)),
       media::BindToCurrentLoop(base::Bind(&RunFailedSetOptionsCallback)));
 
   BrowserThread::PostTask(
@@ -151,12 +152,12 @@
 }
 
 void ImageCaptureImpl::TakePhoto(const std::string& source_id,
-                                 const TakePhotoCallback& callback) {
+                                 TakePhotoCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   media::ScopedResultCallback<TakePhotoCallback> scoped_callback(
-      media::BindToCurrentLoop(callback),
-      media::BindToCurrentLoop(base::Bind(&RunFailedTakePhotoCallback)));
+      media::BindToCurrentLoop(std::move(callback)),
+      media::BindToCurrentLoop(base::BindOnce(&RunFailedTakePhotoCallback)));
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
diff --git a/content/browser/image_capture/image_capture_impl.h b/content/browser/image_capture/image_capture_impl.h
index b67e8ba..c77c3e2 100644
--- a/content/browser/image_capture/image_capture_impl.h
+++ b/content/browser/image_capture/image_capture_impl.h
@@ -22,14 +22,14 @@
                      media::mojom::ImageCaptureRequest request);
 
   void GetPhotoState(const std::string& source_id,
-                     const GetPhotoStateCallback& callback) override;
+                     GetPhotoStateCallback callback) override;
 
   void SetOptions(const std::string& source_id,
                   media::mojom::PhotoSettingsPtr settings,
-                  const SetOptionsCallback& callback) override;
+                  SetOptionsCallback callback) override;
 
   void TakePhoto(const std::string& source_id,
-                 const TakePhotoCallback& callback) override;
+                 TakePhotoCallback callback) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ImageCaptureImpl);
diff --git a/content/browser/manifest/manifest_browsertest.cc b/content/browser/manifest/manifest_browsertest.cc
index 2ff4299c..f5e684e4 100644
--- a/content/browser/manifest/manifest_browsertest.cc
+++ b/content/browser/manifest/manifest_browsertest.cc
@@ -325,7 +325,8 @@
   GetManifestAndWait();
   EXPECT_TRUE(manifest().IsEmpty());
   EXPECT_FALSE(manifest_url().is_empty());
-  EXPECT_EQ(0u, console_error_count());
+  // 1 error for CORS violation
+  EXPECT_EQ(1u, console_error_count());
   expected_manifest_urls.push_back(manifest_url());
   EXPECT_EQ(expected_manifest_urls, reported_manifest_urls());
 
@@ -392,7 +393,8 @@
   GetManifestAndWait();
   EXPECT_TRUE(manifest().IsEmpty());
   EXPECT_FALSE(manifest_url().is_empty());
-  EXPECT_EQ(0u, console_error_count());
+  // 1 error for mixed-content check violation
+  EXPECT_EQ(1u, console_error_count());
   ASSERT_EQ(1u, reported_manifest_urls().size());
   EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
   ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 4f18ae6..1728928c 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -764,8 +764,6 @@
 
   constexpr bool support_locking = false;
   constexpr bool automatic_flushes = false;
-  // TODO(ccameron): Update the display color space based on isWideColorGamut.
-  // https://crbug.com/735658
   display_color_space_ = display::Screen::GetScreen()
                              ->GetDisplayNearestWindow(root_window_)
                              .color_space();
diff --git a/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc b/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
index 866eb75d..6296b8a 100644
--- a/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
+++ b/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
@@ -28,15 +28,19 @@
  public:
   void CreateDevice(const std::string& device_id,
                     video_capture::mojom::DeviceRequest device_request,
-                    const CreateDeviceCallback& callback) override {
+                    CreateDeviceCallback callback) override {
     DoCreateDevice(device_id, &device_request, callback);
   }
 
-  MOCK_METHOD1(GetDeviceInfos, void(const GetDeviceInfosCallback& callback));
+  void GetDeviceInfos(GetDeviceInfosCallback callback) override {
+    DoGetDeviceInfos(callback);
+  }
+
+  MOCK_METHOD1(DoGetDeviceInfos, void(GetDeviceInfosCallback& callback));
   MOCK_METHOD3(DoCreateDevice,
                void(const std::string& device_id,
                     video_capture::mojom::DeviceRequest* device_request,
-                    const CreateDeviceCallback& callback));
+                    CreateDeviceCallback& callback));
 };
 
 class MockVideoCaptureDeviceLauncherCallbacks
@@ -92,21 +96,21 @@
   EXPECT_CALL(mock_device_factory_, DoCreateDevice(kStubDeviceId, _, _))
       .WillOnce(Invoke([](const std::string& device_id,
                           video_capture::mojom::DeviceRequest* device_request,
-                          const video_capture::mojom::DeviceFactory::
+                          video_capture::mojom::DeviceFactory::
                               CreateDeviceCallback& callback) {
         // Note: We must keep |device_request| alive at least until we have
         // sent out the callback. Otherwise, |launcher_| may interpret this
         // as the connection having been lost before receiving the callback.
         base::ThreadTaskRunnerHandle::Get()->PostTask(
             FROM_HERE,
-            base::Bind(
+            base::BindOnce(
                 [](video_capture::mojom::DeviceRequest device_request,
-                   const video_capture::mojom::DeviceFactory::
-                       CreateDeviceCallback& callback) {
-                  callback.Run(
+                   video_capture::mojom::DeviceFactory::CreateDeviceCallback
+                       callback) {
+                  std::move(callback).Run(
                       video_capture::mojom::DeviceAccessResultCode::SUCCESS);
                 },
-                base::Passed(device_request), callback));
+                std::move(*device_request), std::move(callback)));
       }));
   EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_)).Times(1);
   EXPECT_CALL(mock_callbacks_, OnDeviceLaunchAborted()).Times(0);
@@ -148,24 +152,28 @@
   base::RunLoop step_1_run_loop;
   base::RunLoop step_2_run_loop;
 
-  base::Closure create_device_success_answer_cb;
+  base::OnceClosure create_device_success_answer_cb;
   EXPECT_CALL(mock_device_factory_, DoCreateDevice(kStubDeviceId, _, _))
-      .WillOnce(Invoke([&create_device_success_answer_cb, &step_1_run_loop,
-                        service_result_code](
-                           const std::string& device_id,
-                           video_capture::mojom::DeviceRequest* device_request,
-                           const video_capture::mojom::DeviceFactory::
-                               CreateDeviceCallback& callback) {
-        // Prepare the callback, but save it for now instead of invoking it.
-        create_device_success_answer_cb = base::Bind(
-            [](video_capture::mojom::DeviceRequest device_request,
-               const video_capture::mojom::DeviceFactory::CreateDeviceCallback&
-                   callback,
-               video_capture::mojom::DeviceAccessResultCode
-                   service_result_code) { callback.Run(service_result_code); },
-            base::Passed(device_request), callback, service_result_code);
-        step_1_run_loop.Quit();
-      }));
+      .WillOnce(
+          Invoke([&create_device_success_answer_cb, &step_1_run_loop,
+                  service_result_code](
+                     const std::string& device_id,
+                     video_capture::mojom::DeviceRequest* device_request,
+                     video_capture::mojom::DeviceFactory::CreateDeviceCallback&
+                         callback) {
+            // Prepare the callback, but save it for now instead of invoking it.
+            create_device_success_answer_cb = base::BindOnce(
+                [](video_capture::mojom::DeviceRequest device_request,
+                   video_capture::mojom::DeviceFactory::CreateDeviceCallback
+                       callback,
+                   video_capture::mojom::DeviceAccessResultCode
+                       service_result_code) {
+                  std::move(callback).Run(service_result_code);
+                },
+                std::move(*device_request), std::move(callback),
+                service_result_code);
+            step_1_run_loop.Quit();
+          }));
   EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_)).Times(0);
   EXPECT_CALL(mock_callbacks_, OnDeviceLaunchAborted()).Times(1);
   EXPECT_CALL(mock_callbacks_, OnDeviceLaunchFailed()).Times(0);
@@ -182,7 +190,7 @@
   step_1_run_loop.Run();
   launcher_->AbortLaunch();
 
-  create_device_success_answer_cb.Run();
+  std::move(create_device_success_answer_cb).Run();
   step_2_run_loop.Run();
 }
 
@@ -191,25 +199,25 @@
   base::RunLoop run_loop;
 
   EXPECT_CALL(mock_device_factory_, DoCreateDevice(kStubDeviceId, _, _))
-      .WillOnce(Invoke(
-          [](const std::string& device_id,
-             video_capture::mojom::DeviceRequest* device_request,
-             const video_capture::mojom::DeviceFactory::CreateDeviceCallback&
-                 callback) {
+      .WillOnce(
+          Invoke([](const std::string& device_id,
+                    video_capture::mojom::DeviceRequest* device_request,
+                    video_capture::mojom::DeviceFactory::CreateDeviceCallback&
+                        callback) {
             // Note: We must keep |device_request| alive at least until we have
             // sent out the callback. Otherwise, |launcher_| may interpret this
             // as the connection having been lost before receiving the callback.
             base::ThreadTaskRunnerHandle::Get()->PostTask(
                 FROM_HERE,
-                base::Bind(
+                base::BindOnce(
                     [](video_capture::mojom::DeviceRequest device_request,
-                       const video_capture::mojom::DeviceFactory::
-                           CreateDeviceCallback& callback) {
-                      callback.Run(
+                       video_capture::mojom::DeviceFactory::CreateDeviceCallback
+                           callback) {
+                      std::move(callback).Run(
                           video_capture::mojom::DeviceAccessResultCode::
                               ERROR_DEVICE_NOT_FOUND);
                     },
-                    base::Passed(device_request), callback));
+                    std::move(*device_request), std::move(callback)));
           }));
   EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_)).Times(0);
   EXPECT_CALL(mock_callbacks_, OnDeviceLaunchAborted()).Times(0);
@@ -256,16 +264,16 @@
 
   video_capture::mojom::DeviceFactory::CreateDeviceCallback create_device_cb;
   EXPECT_CALL(mock_device_factory_, DoCreateDevice(kStubDeviceId, _, _))
-      .WillOnce(Invoke(
-          [&create_device_cb](
-              const std::string& device_id,
-              video_capture::mojom::DeviceRequest* device_request,
-              const video_capture::mojom::DeviceFactory::CreateDeviceCallback&
-                  callback) {
+      .WillOnce(
+          Invoke([&create_device_cb](
+                     const std::string& device_id,
+                     video_capture::mojom::DeviceRequest* device_request,
+                     video_capture::mojom::DeviceFactory::CreateDeviceCallback&
+                         callback) {
             // Simulate connection lost by not invoking |callback| and releasing
             // |device_request|. We have to save |callback| and invoke it later
             // to avoid hitting a DCHECK.
-            create_device_cb = callback;
+            create_device_cb = std::move(callback);
           }));
   EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_)).Times(0);
   EXPECT_CALL(mock_callbacks_, OnDeviceLaunchAborted()).Times(0);
@@ -291,7 +299,7 @@
   // We have to invoke the callback, because not doing so triggers a DCHECK.
   const video_capture::mojom::DeviceAccessResultCode arbitrary_result_code =
       video_capture::mojom::DeviceAccessResultCode::SUCCESS;
-  create_device_cb.Run(arbitrary_result_code);
+  std::move(create_device_cb).Run(arbitrary_result_code);
 }
 
 TEST_F(ServiceVideoCaptureDeviceLauncherTest,
@@ -301,19 +309,19 @@
       .WillOnce(Invoke([&device_request_owned_by_service](
                            const std::string& device_id,
                            video_capture::mojom::DeviceRequest* device_request,
-                           const video_capture::mojom::DeviceFactory::
+                           video_capture::mojom::DeviceFactory::
                                CreateDeviceCallback& callback) {
         // The service holds on to the |device_request|.
         device_request_owned_by_service = std::move(*device_request);
         base::ThreadTaskRunnerHandle::Get()->PostTask(
             FROM_HERE,
-            base::Bind(
-                [](const video_capture::mojom::DeviceFactory::
-                       CreateDeviceCallback& callback) {
-                  callback.Run(
+            base::BindOnce(
+                [](video_capture::mojom::DeviceFactory::CreateDeviceCallback
+                       callback) {
+                  std::move(callback).Run(
                       video_capture::mojom::DeviceAccessResultCode::SUCCESS);
                 },
-                callback));
+                std::move(callback)));
       }));
   std::unique_ptr<LaunchedVideoCaptureDevice> launched_device;
   EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_))
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc
index b0b1349..fe8716b 100644
--- a/content/browser/web_contents/web_contents_view_android.cc
+++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -172,6 +172,8 @@
           ? display::Screen::GetScreen()->GetDisplayNearestView(native_view)
           : display::Screen::GetScreen()->GetPrimaryDisplay();
   DisplayToScreenInfo(display, result);
+  if (delegate_)
+    delegate_->OverrideDisplayColorSpace(&result->color_space);
 }
 
 void WebContentsViewAndroid::GetContainerBounds(gfx::Rect* out) const {
diff --git a/content/browser/web_contents/web_drag_source_mac.mm b/content/browser/web_contents/web_drag_source_mac.mm
index 301fd88..60d0b1a 100644
--- a/content/browser/web_contents/web_drag_source_mac.mm
+++ b/content/browser/web_contents/web_drag_source_mac.mm
@@ -16,9 +16,9 @@
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/task_scheduler/post_task.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
-#include "content/browser/browser_thread_impl.h"
 #include "content/browser/download/drag_download_file.h"
 #include "content/browser/download/drag_download_util.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
@@ -318,11 +318,9 @@
         dragFileDownloader.get()));
   } else {
     // The writer will take care of closing and deletion.
-    BrowserThread::PostTask(BrowserThread::FILE,
-                            FROM_HERE,
-                            base::Bind(&PromiseWriterHelper,
-                                       *dropData_,
-                                       base::Passed(&file)));
+    base::PostTaskWithTraits(
+        FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
+        base::Bind(&PromiseWriterHelper, *dropData_, base::Passed(&file)));
   }
 
   // The DragDownloadFile constructor may have altered the value of |filePath|
diff --git a/content/browser/websockets/README.md b/content/browser/websockets/README.md
new file mode 100644
index 0000000..6f77941
--- /dev/null
+++ b/content/browser/websockets/README.md
@@ -0,0 +1,5 @@
+# WebSocket service
+
+This directory contains the blink::mojom::WebSocket implementation. It hosts
+the WebSocket API implementations in Blink over Mojo, and exports the WebSocket
+protocol implementation in net/websockets/ as a service.
diff --git a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
index 9ae62317..fe2f298a 100644
--- a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
+++ b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
@@ -237,10 +237,7 @@
 
 }  // namespace
 
-GpuProcessPolicy::GpuProcessPolicy() : GpuProcessPolicy(false) {}
-
-GpuProcessPolicy::GpuProcessPolicy(bool allow_mincore)
-    : broker_process_(NULL), allow_mincore_(allow_mincore) {}
+GpuProcessPolicy::GpuProcessPolicy() : broker_process_(NULL) {}
 
 GpuProcessPolicy::~GpuProcessPolicy() {}
 
@@ -253,11 +250,7 @@
     case __NR_ioctl:
       return Allow();
     case __NR_mincore:
-      if (allow_mincore_) {
-        return Allow();
-      } else {
-        return SandboxBPFBasePolicy::EvaluateSyscall(sysno);
-      }
+      return Allow();
 #if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
     // The Nvidia driver uses flags not in the baseline policy
     // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT)
diff --git a/content/common/sandbox_linux/bpf_gpu_policy_linux.h b/content/common/sandbox_linux/bpf_gpu_policy_linux.h
index e7f4008..23b7c9d8 100644
--- a/content/common/sandbox_linux/bpf_gpu_policy_linux.h
+++ b/content/common/sandbox_linux/bpf_gpu_policy_linux.h
@@ -24,7 +24,6 @@
 class GpuProcessPolicy : public SandboxBPFBasePolicy {
  public:
   GpuProcessPolicy();
-  explicit GpuProcessPolicy(bool allow_mincore);
   ~GpuProcessPolicy() override;
 
   sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
@@ -58,9 +57,6 @@
   // which executes iff the sandbox is going to be enabled afterwards.
   sandbox::syscall_broker::BrokerProcess* broker_process_;
 
-  // eglCreateWindowSurface() needs mincore().
-  bool allow_mincore_;
-
   DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy);
 };
 
diff --git a/content/common/sandbox_linux/bpf_renderer_policy_linux.cc b/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
index 67c1301..da189088 100644
--- a/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
+++ b/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
@@ -73,6 +73,7 @@
 #if defined(__i386__) || defined(__arm__)
     case __NR_ugetrlimit:
 #endif
+    case __NR_mincore:  // See crbug.com/741984.
     case __NR_mremap:  // See crbug.com/149834.
     case __NR_pread64:
     case __NR_pwrite64:
diff --git a/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc b/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
index 67b1d057..9b27f94 100644
--- a/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
+++ b/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
@@ -37,10 +37,6 @@
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
 #include "sandbox/linux/system_headers/linux_syscalls.h"
 
-#if !defined(IN_NACL_HELPER)
-#include "ui/gl/gl_switches.h"
-#endif  // !defined(IN_NACL_HELPER)
-
 using sandbox::BaselinePolicy;
 using sandbox::SandboxBPF;
 using sandbox::SyscallSets;
@@ -171,11 +167,7 @@
     return std::unique_ptr<SandboxBPFBasePolicy>(
         new CrosArmGpuProcessPolicy(allow_sysv_shm));
   } else {
-    bool allow_mincore = command_line.HasSwitch(switches::kUseGL) &&
-                         command_line.GetSwitchValueASCII(switches::kUseGL) ==
-                             gl::kGLImplementationEGLName;
-    return std::unique_ptr<SandboxBPFBasePolicy>(
-        new GpuProcessPolicy(allow_mincore));
+    return std::unique_ptr<SandboxBPFBasePolicy>(new GpuProcessPolicy());
   }
 }
 
diff --git a/content/public/browser/web_contents_view_delegate.cc b/content/public/browser/web_contents_view_delegate.cc
index 2b6385e..caf45ddd 100644
--- a/content/public/browser/web_contents_view_delegate.cc
+++ b/content/public/browser/web_contents_view_delegate.cc
@@ -40,6 +40,9 @@
 void WebContentsViewDelegate::SizeChanged(const gfx::Size& size) {
 }
 
+void WebContentsViewDelegate::OverrideDisplayColorSpace(
+    gfx::ColorSpace* color_space) {}
+
 void* WebContentsViewDelegate::CreateRenderWidgetHostViewDelegate(
     RenderWidgetHost* render_widget_host) {
   return nullptr;
diff --git a/content/public/browser/web_contents_view_delegate.h b/content/public/browser/web_contents_view_delegate.h
index 6b96eb9..f9168bb 100644
--- a/content/public/browser/web_contents_view_delegate.h
+++ b/content/public/browser/web_contents_view_delegate.h
@@ -18,6 +18,7 @@
 #endif
 
 namespace gfx {
+class ColorSpace;
 class Size;
 }
 
@@ -53,6 +54,11 @@
   virtual void TakeFocus(bool reverse);
   virtual void SizeChanged(const gfx::Size& size);
 
+  // This method allows the embedder to specify the display color space (instead
+  // of using the color space specified by display::Display) and write it in
+  // |*color_space|. The default behavior is to leave |*color_space| unchanged.
+  virtual void OverrideDisplayColorSpace(gfx::ColorSpace* color_space);
+
   // Returns a newly-created delegate for the RenderWidgetHostViewMac, to handle
   // events on the responder chain.
 #if defined(__OBJC__)
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index fd27299..476888c 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -534,7 +534,7 @@
     settings.max_staging_buffer_usage_in_bytes /= 4;
 
   cc::ManagedMemoryPolicy defaults = settings.gpu_memory_policy;
-  settings.gpu_memory_policy = GetGpuMemoryPolicy(defaults);
+  settings.gpu_memory_policy = GetGpuMemoryPolicy(defaults, screen_info);
   settings.software_memory_policy.num_resources_limit =
       base::SharedMemory::GetHandleLimit() / 3;
 
@@ -546,7 +546,8 @@
 
 // static
 cc::ManagedMemoryPolicy RenderWidgetCompositor::GetGpuMemoryPolicy(
-    const cc::ManagedMemoryPolicy& default_policy) {
+    const cc::ManagedMemoryPolicy& default_policy,
+    const ScreenInfo& screen_info) {
   cc::ManagedMemoryPolicy actual = default_policy;
   actual.bytes_limit_when_visible = 0;
 
@@ -628,6 +629,16 @@
   actual.bytes_limit_when_visible = 512 * 1024 * 1024;
   actual.priority_cutoff_when_visible =
       gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
+
+  // For large monitors (4k), double the tile memory to avoid frequent out of
+  // memory problems. 4k could mean a screen width of anywhere from 3840 to 4096
+  // (see https://en.wikipedia.org/wiki/4K_resolution). We use 3500 as a proxy
+  // for "large enough".
+  static const int kLargeDisplayThreshold = 3500;
+  int display_width =
+      std::round(screen_info.rect.width() * screen_info.device_scale_factor);
+  if (display_width >= kLargeDisplayThreshold)
+    actual.bytes_limit_when_visible *= 2;
 #endif
   return actual;
 }
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h
index bf36242d..719c56d 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -83,7 +83,8 @@
                   std::unique_ptr<cc::AnimationHost> animation_host);
 
   static cc::ManagedMemoryPolicy GetGpuMemoryPolicy(
-      const cc::ManagedMemoryPolicy& policy);
+      const cc::ManagedMemoryPolicy& policy,
+      const ScreenInfo& screen_info);
 
   void SetNeverVisible();
   const base::WeakPtr<cc::InputHandler>& GetInputHandler();
diff --git a/content/renderer/gpu/render_widget_compositor_unittest.cc b/content/renderer/gpu/render_widget_compositor_unittest.cc
index 05192682..b7c0b63 100644
--- a/content/renderer/gpu/render_widget_compositor_unittest.cc
+++ b/content/renderer/gpu/render_widget_compositor_unittest.cc
@@ -315,5 +315,36 @@
 }
 #endif
 
+// Verify desktop memory limit calculations.
+#if !defined(OS_ANDROID)
+TEST(RenderWidgetCompositorTest, IgnoreGivenMemoryPolicy) {
+  auto policy = RenderWidgetCompositor::GetGpuMemoryPolicy(
+      cc::ManagedMemoryPolicy(256), ScreenInfo());
+  EXPECT_EQ(512u * 1024u * 1024u, policy.bytes_limit_when_visible);
+  EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
+            policy.priority_cutoff_when_visible);
+}
+
+TEST(RenderWidgetCompositorTest, LargeScreensUseMoreMemory) {
+  ScreenInfo screen_info;
+
+  screen_info.rect = gfx::Rect(4096, 2160);
+  screen_info.device_scale_factor = 1.f;
+  auto policy = RenderWidgetCompositor::GetGpuMemoryPolicy(
+      cc::ManagedMemoryPolicy(256), screen_info);
+  EXPECT_EQ(2u * 512u * 1024u * 1024u, policy.bytes_limit_when_visible);
+  EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
+            policy.priority_cutoff_when_visible);
+
+  screen_info.rect = gfx::Rect(2048, 1080);
+  screen_info.device_scale_factor = 2.f;
+  policy = RenderWidgetCompositor::GetGpuMemoryPolicy(
+      cc::ManagedMemoryPolicy(256), screen_info);
+  EXPECT_EQ(2u * 512u * 1024u * 1024u, policy.bytes_limit_when_visible);
+  EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
+            policy.priority_cutoff_when_visible);
+}
+#endif  // !defined(OS_ANDROID)
+
 }  // namespace
 }  // namespace content
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index 99cc0ef5..7bab4f0 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -689,9 +689,6 @@
 }
 
 void ServiceWorkerContextClient::WorkerScriptLoaded() {
-  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(!proxy_);
-
   (*instance_host_)->OnScriptLoaded();
 }
 
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h
index 1f4834d6..0fe8351 100644
--- a/content/renderer/service_worker/service_worker_context_client.h
+++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -128,9 +128,8 @@
 
   // Called on the main thread.
   void WorkerContextFailedToStart() override;
-  void WorkerScriptLoaded() override;
   bool HasAssociatedRegistration() override;
-
+  void WorkerScriptLoaded() override;
   void WorkerContextStarted(
       blink::WebServiceWorkerContextProxy* proxy) override;
   void DidEvaluateWorkerScript(bool success) override;
diff --git a/content/shell/browser/layout_test/layout_test_devtools_bindings.cc b/content/shell/browser/layout_test/layout_test_devtools_bindings.cc
index 2ec94572f..49b2df7 100644
--- a/content/shell/browser/layout_test/layout_test_devtools_bindings.cc
+++ b/content/shell/browser/layout_test/layout_test_devtools_bindings.cc
@@ -61,7 +61,7 @@
 GURL LayoutTestDevToolsBindings::MapTestURLIfNeeded(const GURL& test_url,
                                                     bool* is_devtools_js_test) {
   std::string spec = test_url.spec();
-  *is_devtools_js_test = spec.find("/devtools-js/") != std::string::npos;
+  *is_devtools_js_test = spec.find("/devtools/") != std::string::npos;
   bool is_unit_test = spec.find("/inspector-unit/") != std::string::npos;
   if (!*is_devtools_js_test && !is_unit_test)
     return test_url;
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json
index 0fdc249..fd9fff23 100644
--- a/extensions/common/api/_api_features.json
+++ b/extensions/common/api/_api_features.json
@@ -173,6 +173,10 @@
     "contexts": "all",
     "matches": ["<all_urls>"]
   },
+  "fileSystem": {
+    "dependencies": ["permission:fileSystem"],
+    "contexts": ["blessed_extension"]
+  },
   "guestViewInternal": [
     {
       "internal": true,
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json
index 0489bc4e..75a87881 100644
--- a/extensions/common/api/_permission_features.json
+++ b/extensions/common/api/_permission_features.json
@@ -226,6 +226,54 @@
       "A28C9619C4C41306FA5236FB4D94DA812F504DE8"   // http://crbug.com/429886
     ]
   },
+  "fileSystem": [{
+    "channel": "stable",
+    "extension_types": ["platform_app"],
+    "default_parent": true
+  },{
+    "channel": "stable",
+    "extension_types": ["extension"],
+    "whitelist": [
+      "2FC374607C2DF285634B67C64A2E356C607091C3",  // Quickoffice
+      "3727DD3E564B6055387425027AD74C58784ACC15",  // Quickoffice internal
+      "12E618C3C6E97495AAECF2AC12DEB082353241C6",  // QO component extension
+      "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2",  // http://crbug.com/312900
+      "D57DE394F36DC1C3220E7604C575D29C51A6C495",  // http://crbug.com/319444
+      "3F65507A3B39259B38C8173C6FFA3D12DF64CCE9",  // http://crbug.com/371562
+      "2B6C6A4A5940017146F3E58B7F90116206E84685",  // http://crbug.com/642141
+      "B6C2EFAB3EC3BF6EF03701408B6B09A67B2D0069",  // http://crbug.com/642141
+      "96FF2FFA5C9173C76D47184B3E86D267B37781DE",  // http://crbug.com/642141
+      "0136FCB13DB29FD5CD442F56E59E53B61F1DF96F"   // http://crbug.com/642141
+    ]
+  }],
+  "fileSystem.directory": {
+    "channel": "stable",
+    "extension_types": ["platform_app"]
+  },
+  "fileSystem.retainEntries": {
+    "channel": "stable",
+    "extension_types": ["platform_app"]
+  },
+  "fileSystem.write": [{
+    "channel": "stable",
+    "extension_types": ["platform_app"]
+  },{
+    "channel": "stable",
+    "extension_types": ["extension"],
+    "whitelist": [
+      "2FC374607C2DF285634B67C64A2E356C607091C3",  // Quickoffice
+      "3727DD3E564B6055387425027AD74C58784ACC15",  // Quickoffice internal
+      "12E618C3C6E97495AAECF2AC12DEB082353241C6",  // QO component extension
+      "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2",  // http://crbug.com/312900
+      "D57DE394F36DC1C3220E7604C575D29C51A6C495",  // http://crbug.com/319444
+      "3F65507A3B39259B38C8173C6FFA3D12DF64CCE9"   // http://crbug.com/371562
+    ]
+  }],
+  "fileSystem.requestFileSystem": {
+    "channel": "stable",
+    "extension_types": ["platform_app"],
+    "platforms": ["chromeos"]
+  },
   "hid": [
     {
       "channel": "stable",
diff --git a/extensions/common/permissions/extensions_api_permissions.cc b/extensions/common/permissions/extensions_api_permissions.cc
index e9eba198..c180c43 100644
--- a/extensions/common/permissions/extensions_api_permissions.cc
+++ b/extensions/common/permissions/extensions_api_permissions.cc
@@ -58,6 +58,19 @@
       {APIPermission::kExternallyConnectableAllUrls,
        "externally_connectable.all_urls"},
       {APIPermission::kFullscreen, "app.window.fullscreen"},
+
+      // The permission string for "fileSystem" is only shown when
+      // "write" or "directory" is present. Read-only access is only
+      // granted after the user has been shown a file or directory
+      // chooser dialog and selected a file or directory. Selecting
+      // the file or directory is considered consent to read it.
+      {APIPermission::kFileSystem, "fileSystem"},
+      {APIPermission::kFileSystemDirectory, "fileSystem.directory"},
+      {APIPermission::kFileSystemRequestFileSystem,
+       "fileSystem.requestFileSystem"},
+      {APIPermission::kFileSystemRetainEntries, "fileSystem.retainEntries"},
+      {APIPermission::kFileSystemWrite, "fileSystem.write"},
+
       {APIPermission::kHid, "hid"},
       {APIPermission::kImeWindowEnabled, "app.window.ime"},
       {APIPermission::kOverrideEscFullscreen,
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn
index 5ee097c..edc12f8 100644
--- a/extensions/renderer/BUILD.gn
+++ b/extensions/renderer/BUILD.gn
@@ -162,6 +162,8 @@
     "resources/extension.css",
     "resources/extension_custom_bindings.js",
     "resources/extension_fonts.css",
+    "resources/file_entry_binding_util.js",
+    "resources/file_system_custom_bindings.js",
     "resources/greasemonkey_api.js",
     "resources/guest_view/app_view/app_view.js",
     "resources/guest_view/extension_options/extension_options.js",
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index 0632fc0a..661997a 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -704,6 +704,7 @@
       {"extensionViewEvents", IDR_EXTENSION_VIEW_EVENTS_JS},
       {"extensionViewInternal", IDR_EXTENSION_VIEW_INTERNAL_CUSTOM_BINDINGS_JS},
       {"fileEntryBindingUtil", IDR_FILE_ENTRY_BINDING_UTIL_JS},
+      {"fileSystem", IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS},
       {"guestView", IDR_GUEST_VIEW_JS},
       {"guestViewAttributes", IDR_GUEST_VIEW_ATTRIBUTES_JS},
       {"guestViewContainer", IDR_GUEST_VIEW_CONTAINER_JS},
diff --git a/extensions/renderer/resources/extensions_renderer_resources.grd b/extensions/renderer/resources/extensions_renderer_resources.grd
index 4e4d2ca..f90acc6 100644
--- a/extensions/renderer/resources/extensions_renderer_resources.grd
+++ b/extensions/renderer/resources/extensions_renderer_resources.grd
@@ -64,6 +64,7 @@
       <include name="IDR_DISPLAY_SOURCE_CUSTOM_BINDINGS_JS" file="display_source_custom_bindings.js" type="BINDATA" />
       <include name="IDR_EXTENSION_CUSTOM_BINDINGS_JS" file="extension_custom_bindings.js" type="BINDATA" />
       <include name="IDR_FILE_ENTRY_BINDING_UTIL_JS" file="file_entry_binding_util.js" type="BINDATA" />
+      <include name="IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS" file="file_system_custom_bindings.js" type="BINDATA" />
       <include name="IDR_GREASEMONKEY_API_JS" file="greasemonkey_api.js" type="BINDATA" />
       <include name="IDR_I18N_CUSTOM_BINDINGS_JS" file="i18n_custom_bindings.js" type="BINDATA" />
       <include name="IDR_MOJO_PRIVATE_CUSTOM_BINDINGS_JS" file="mojo_private_custom_bindings.js" type="BINDATA" />
diff --git a/chrome/renderer/resources/extensions/file_system_custom_bindings.js b/extensions/renderer/resources/file_system_custom_bindings.js
similarity index 100%
rename from chrome/renderer/resources/extensions/file_system_custom_bindings.js
rename to extensions/renderer/resources/file_system_custom_bindings.js
diff --git a/extensions/renderer/resources/utils.js b/extensions/renderer/resources/utils.js
index 0ec387b..e0f81370 100644
--- a/extensions/renderer/resources/utils.js
+++ b/extensions/renderer/resources/utils.js
@@ -3,8 +3,6 @@
 // found in the LICENSE file.
 
 var nativeDeepCopy = requireNative('utils').deepCopy;
-var DCHECK = requireNative('logging').DCHECK;
-var WARNING = requireNative('logging').WARNING;
 var logActivity = requireNative('activityLogger');
 var exceptionHandler = require('uncaught_exception_handler');
 
@@ -190,38 +188,6 @@
   return nativeDeepCopy(value);
 }
 
-/**
- * Wrap an asynchronous API call to a function |func| in a promise. The
- * remaining arguments will be passed to |func|. Returns a promise that will be
- * resolved to the result passed to the callback or rejected if an error occurs
- * (if chrome.runtime.lastError is set). If there are multiple results, the
- * promise will be resolved with an array containing those results.
- *
- * For example,
- * promise(chrome.storage.get, 'a').then(function(result) {
- *   // Use result.
- * }).catch(function(error) {
- *   // Report error.message.
- * });
- */
-function promise(func) {
-  var args = $Array.slice(arguments, 1);
-  DCHECK(typeof func == 'function');
-  return new Promise(function(resolve, reject) {
-    args.push(function() {
-      if (chrome.runtime.lastError) {
-        reject(new Error(chrome.runtime.lastError));
-        return;
-      }
-      if (arguments.length <= 1)
-        resolve(arguments[0]);
-      else
-        resolve($Array.slice(arguments));
-    });
-    $Function.apply(func, null, args);
-  });
-}
-
 // DO NOT USE. This causes problems with safe builtins, and makes migration to
 // native bindings more difficult.
 function handleRequestWithPromiseDoNotUse(
@@ -259,6 +225,5 @@
 exports.$set('defineProperty', defineProperty);
 exports.$set('expose', expose);
 exports.$set('deepCopy', deepCopy);
-exports.$set('promise', promise);
 exports.$set('handleRequestWithPromiseDoNotUse',
              handleRequestWithPromiseDoNotUse);
diff --git a/extensions/renderer/utils_unittest.cc b/extensions/renderer/utils_unittest.cc
index 53f07faf..07a237a 100644
--- a/extensions/renderer/utils_unittest.cc
+++ b/extensions/renderer/utils_unittest.cc
@@ -59,21 +59,5 @@
   RunTest("testSuperClass");
 }
 
-TEST_F(UtilsUnittest, PromiseNoResult) {
-  RunTestWithPromises("testPromiseNoResult");
-}
-
-TEST_F(UtilsUnittest, PromiseOneResult) {
-  RunTestWithPromises("testPromiseOneResult");
-}
-
-TEST_F(UtilsUnittest, PromiseTwoResults) {
-  RunTestWithPromises("testPromiseTwoResults");
-}
-
-TEST_F(UtilsUnittest, PromiseError) {
-  RunTestWithPromises("testPromiseError");
-}
-
 }  // namespace
 }  // namespace extensions
diff --git a/extensions/shell/browser/default_shell_browser_main_delegate.cc b/extensions/shell/browser/default_shell_browser_main_delegate.cc
index 74a5473..1275f32 100644
--- a/extensions/shell/browser/default_shell_browser_main_delegate.cc
+++ b/extensions/shell/browser/default_shell_browser_main_delegate.cc
@@ -24,6 +24,64 @@
 
 namespace extensions {
 
+namespace {
+
+void LoadExtensionsFromCommandLine(ShellExtensionSystem* extension_system) {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (!command_line->HasSwitch(switches::kLoadExtension))
+    return;
+
+  base::CommandLine::StringType path_list =
+      command_line->GetSwitchValueNative(switches::kLoadExtension);
+
+  base::StringTokenizerT<base::CommandLine::StringType,
+                         base::CommandLine::StringType::const_iterator>
+      tokenizer(path_list, FILE_PATH_LITERAL(","));
+  while (tokenizer.GetNext()) {
+    extension_system->LoadExtension(
+        base::MakeAbsoluteFilePath(base::FilePath(tokenizer.token())));
+  }
+}
+
+void LoadAppsFromCommandLine(ShellExtensionSystem* extension_system,
+                             content::BrowserContext* browser_context) {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (!command_line->HasSwitch(switches::kLoadApps)) {
+    LOG(ERROR) << "No app specified. Use --" << switches::kLoadApps
+               << " to load and launch an app.";
+    return;
+  }
+
+  base::CommandLine::StringType path_list =
+      command_line->GetSwitchValueNative(switches::kLoadApps);
+
+  base::StringTokenizerT<base::CommandLine::StringType,
+                         base::CommandLine::StringType::const_iterator>
+      tokenizer(path_list, FILE_PATH_LITERAL(","));
+
+  const Extension* launch_app = nullptr;
+  while (tokenizer.GetNext()) {
+    base::FilePath app_absolute_dir =
+        base::MakeAbsoluteFilePath(base::FilePath(tokenizer.token()));
+
+    const Extension* extension = extension_system->LoadApp(app_absolute_dir);
+    if (extension && !launch_app)
+      launch_app = extension;
+  }
+
+  if (launch_app) {
+    base::FilePath current_directory;
+    base::PathService::Get(base::DIR_CURRENT, &current_directory);
+    apps::LaunchPlatformAppWithCommandLineAndLaunchId(
+        browser_context, launch_app, launch_app->id(), *command_line,
+        current_directory, SOURCE_COMMAND_LINE);
+  } else {
+    LOG(ERROR) << "Could not load any apps.";
+  }
+}
+
+}  // namespace
+
 DefaultShellBrowserMainDelegate::DefaultShellBrowserMainDelegate() {
 }
 
@@ -32,42 +90,12 @@
 
 void DefaultShellBrowserMainDelegate::Start(
     content::BrowserContext* browser_context) {
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kLoadApps)) {
-    ShellExtensionSystem* extension_system = static_cast<ShellExtensionSystem*>(
-        ExtensionSystem::Get(browser_context));
-    extension_system->Init();
+  ShellExtensionSystem* extension_system =
+      static_cast<ShellExtensionSystem*>(ExtensionSystem::Get(browser_context));
+  extension_system->Init();
 
-    base::CommandLine::StringType path_list =
-        command_line->GetSwitchValueNative(switches::kLoadApps);
-
-    base::StringTokenizerT<base::CommandLine::StringType,
-                           base::CommandLine::StringType::const_iterator>
-        tokenizer(path_list, FILE_PATH_LITERAL(","));
-
-    const Extension* launch_app = nullptr;
-    while (tokenizer.GetNext()) {
-      base::FilePath app_absolute_dir =
-          base::MakeAbsoluteFilePath(base::FilePath(tokenizer.token()));
-
-      const Extension* extension = extension_system->LoadApp(app_absolute_dir);
-      if (extension && !launch_app)
-        launch_app = extension;
-    }
-
-    if (launch_app) {
-      base::FilePath current_directory;
-      base::PathService::Get(base::DIR_CURRENT, &current_directory);
-      apps::LaunchPlatformAppWithCommandLineAndLaunchId(
-          browser_context, launch_app, launch_app->id(), *command_line,
-          current_directory, SOURCE_COMMAND_LINE);
-    } else {
-      LOG(ERROR) << "Could not load any apps.";
-    }
-  } else {
-    LOG(ERROR) << "--" << switches::kLoadApps
-               << " unset; boredom is in your future";
-  }
+  LoadExtensionsFromCommandLine(extension_system);
+  LoadAppsFromCommandLine(extension_system, browser_context);
 }
 
 void DefaultShellBrowserMainDelegate::Shutdown() {
diff --git a/extensions/shell/browser/shell_browser_main_parts.cc b/extensions/shell/browser/shell_browser_main_parts.cc
index 9043fd6..af9ee8d 100644
--- a/extensions/shell/browser/shell_browser_main_parts.cc
+++ b/extensions/shell/browser/shell_browser_main_parts.cc
@@ -23,7 +23,6 @@
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/updater/update_service.h"
 #include "extensions/common/constants.h"
-#include "extensions/common/switches.h"
 #include "extensions/shell/browser/shell_browser_context.h"
 #include "extensions/shell/browser/shell_browser_context_keyed_service_factories.h"
 #include "extensions/shell/browser/shell_browser_main_delegate.h"
diff --git a/extensions/shell/browser/shell_browsertest.cc b/extensions/shell/browser/shell_browsertest.cc
index 67c0b13..d8de659 100644
--- a/extensions/shell/browser/shell_browsertest.cc
+++ b/extensions/shell/browser/shell_browsertest.cc
@@ -17,8 +17,13 @@
 
 namespace extensions {
 
+// Test that we can load an extension.
+IN_PROC_BROWSER_TEST_F(ShellApiTest, LoadExtension) {
+  ASSERT_TRUE(RunExtensionTest("extension")) << message_;
+}
+
 // Test that we can open an app window and wait for it to load.
-IN_PROC_BROWSER_TEST_F(ShellApiTest, Basic) {
+IN_PROC_BROWSER_TEST_F(ShellApiTest, LoadApp) {
   ASSERT_TRUE(RunAppTest("platform_app")) << message_;
 
   // A window was created.
diff --git a/extensions/shell/browser/shell_extension_system.cc b/extensions/shell/browser/shell_extension_system.cc
index 19ce4fab..a797732 100644
--- a/extensions/shell/browser/shell_extension_system.cc
+++ b/extensions/shell/browser/shell_extension_system.cc
@@ -42,24 +42,26 @@
 ShellExtensionSystem::~ShellExtensionSystem() {
 }
 
-const Extension* ShellExtensionSystem::LoadApp(const base::FilePath& app_dir) {
+const Extension* ShellExtensionSystem::LoadExtension(
+    const base::FilePath& extension_dir) {
   // app_shell only supports unpacked extensions.
   // NOTE: If you add packed extension support consider removing the flag
   // FOLLOW_SYMLINKS_ANYWHERE below. Packed extensions should not have symlinks.
-  CHECK(base::DirectoryExists(app_dir)) << app_dir.AsUTF8Unsafe();
+  CHECK(base::DirectoryExists(extension_dir)) << extension_dir.AsUTF8Unsafe();
   int load_flags = Extension::FOLLOW_SYMLINKS_ANYWHERE;
   std::string load_error;
   scoped_refptr<Extension> extension = file_util::LoadExtension(
-      app_dir, Manifest::COMMAND_LINE, load_flags, &load_error);
+      extension_dir, Manifest::COMMAND_LINE, load_flags, &load_error);
   if (!extension.get()) {
-    LOG(ERROR) << "Loading extension at " << app_dir.value()
+    LOG(ERROR) << "Loading extension at " << extension_dir.value()
                << " failed with: " << load_error;
     return nullptr;
   }
 
   // Log warnings.
   if (extension->install_warnings().size()) {
-    LOG(WARNING) << "Warnings loading extension at " << app_dir.value() << ":";
+    LOG(WARNING) << "Warnings loading extension at " << extension_dir.value()
+                 << ":";
     for (const auto& warning : extension->install_warnings())
       LOG(WARNING) << warning.message;
   }
@@ -82,9 +84,15 @@
   RendererStartupHelperFactory::GetForBrowserContext(browser_context_)
       ->OnExtensionLoaded(*extension);
 
+  ExtensionRegistry::Get(browser_context_)->TriggerOnLoaded(extension.get());
+
   return extension.get();
 }
 
+const Extension* ShellExtensionSystem::LoadApp(const base::FilePath& app_dir) {
+  return LoadExtension(app_dir);
+}
+
 void ShellExtensionSystem::Init() {
   // Inform the rest of the extensions system to start.
   ready_.Signal();
diff --git a/extensions/shell/browser/shell_extension_system.h b/extensions/shell/browser/shell_extension_system.h
index 553a49db..15e8482 100644
--- a/extensions/shell/browser/shell_extension_system.h
+++ b/extensions/shell/browser/shell_extension_system.h
@@ -32,8 +32,14 @@
   explicit ShellExtensionSystem(content::BrowserContext* browser_context);
   ~ShellExtensionSystem() override;
 
-  // Loads an unpacked application from a directory. Returns the extension on
-  // success, or null otherwise.
+  // Loads an unpacked extension from a directory. Returns the extension on
+  // success, or nullptr otherwise.
+  const Extension* LoadExtension(const base::FilePath& extension_dir);
+
+  // Loads an unpacked platform app from a directory. Returns the extension on
+  // success, or nullptr otherwise.
+  // Currently this just calls LoadExtension, as apps are not loaded differently
+  // than other extensions. Use LaunchApp() to actually launch the loaded app.
   const Extension* LoadApp(const base::FilePath& app_dir);
 
   // Initializes the extension system.
diff --git a/extensions/shell/test/shell_apitest.cc b/extensions/shell/test/shell_apitest.cc
index 4018e9f..a52a1af 100644
--- a/extensions/shell/test/shell_apitest.cc
+++ b/extensions/shell/test/shell_apitest.cc
@@ -22,30 +22,43 @@
 ShellApiTest::~ShellApiTest() {
 }
 
+const Extension* ShellApiTest::LoadExtension(const std::string& extension_dir) {
+  base::ThreadRestrictions::ScopedAllowIO allow_io;
+  base::FilePath test_data_dir;
+  PathService::Get(extensions::DIR_TEST_DATA, &test_data_dir);
+  base::FilePath extension_path = test_data_dir.AppendASCII(extension_dir);
+
+  return extension_system_->LoadExtension(extension_path);
+}
+
 const Extension* ShellApiTest::LoadApp(const std::string& app_dir) {
   base::ThreadRestrictions::ScopedAllowIO allow_io;
   base::FilePath test_data_dir;
   PathService::Get(extensions::DIR_TEST_DATA, &test_data_dir);
-  test_data_dir = test_data_dir.AppendASCII(app_dir);
+  base::FilePath app_path = test_data_dir.AppendASCII(app_dir);
 
-  const Extension* extension = extension_system_->LoadApp(test_data_dir);
-  if (!extension)
-    return NULL;
-
-  extension_system_->LaunchApp(extension->id());
-
+  const Extension* extension = extension_system_->LoadApp(app_path);
+  if (extension)
+    extension_system_->LaunchApp(extension->id());
   return extension;
 }
 
+bool ShellApiTest::RunExtensionTest(const std::string& extension_dir) {
+  ResultCatcher catcher;
+  return RunTest(LoadExtension(extension_dir), &catcher);
+}
+
 bool ShellApiTest::RunAppTest(const std::string& app_dir) {
   ResultCatcher catcher;
+  return RunTest(LoadApp(app_dir), &catcher);
+}
 
-  const Extension* extension = LoadApp(app_dir);
+bool ShellApiTest::RunTest(const Extension* extension, ResultCatcher* catcher) {
   if (!extension)
     return false;
 
-  if (!catcher.GetNextResult()) {
-    message_ = catcher.message();
+  if (!catcher->GetNextResult()) {
+    message_ = catcher->message();
     return false;
   }
 
diff --git a/extensions/shell/test/shell_apitest.h b/extensions/shell/test/shell_apitest.h
index b3103e4e..11ed054 100644
--- a/extensions/shell/test/shell_apitest.h
+++ b/extensions/shell/test/shell_apitest.h
@@ -13,6 +13,7 @@
 namespace extensions {
 
 class Extension;
+class ResultCatcher;
 
 // Base class for app shell browser API tests that load an app/extension
 // and wait for a success message from the chrome.test API.
@@ -21,15 +22,22 @@
   ShellApiTest();
   ~ShellApiTest() override;
 
-  // Load and run an unpacked platform app from the |app_dir| directory. Unlike
-  // |RunAppTest|, it won't wait automatically for any kind of notification.
-  // Returns an instance of the extension that was just loaded.
+  // Loads an unpacked extension. Returns an instance of the extension that was
+  // just loaded.
+  // |extension_dir| should be a subpath under extensions/test/data.
+  const Extension* LoadExtension(const std::string& extension_dir);
+
+  // Loads and launches an unpacked platform app. Returns an instance of the
+  // extension that was just loaded.
+  // |app_dir| should be a subpath under extensions/test/data.
   const Extension* LoadApp(const std::string& app_dir);
 
-  // Loads an unpacked platform app from a directory using the current
-  // ExtensionSystem, launches it, and waits for a chrome.test success
-  // notification. Returns true if the test succeeds. |app_dir| is a
-  // subpath under extensions/test/data.
+  // Loads an unpacked extension and waits for a chrome.test success
+  // notification. Returns true if the test succeeds.
+  bool RunExtensionTest(const std::string& extension_dir);
+
+  // Loads and launches an unpacked platform app and waits for a chrome.test
+  // success notification. Returns true if the test succeeds.
   bool RunAppTest(const std::string& app_dir);
 
   // Removes the |app| from the ExtensionRegistry and dispatches
@@ -41,6 +49,8 @@
   std::string message_;
 
  private:
+  bool RunTest(const Extension* extension, ResultCatcher* catcher);
+
   DISALLOW_COPY_AND_ASSIGN(ShellApiTest);
 };
 
diff --git a/extensions/test/data/extension/background.js b/extensions/test/data/extension/background.js
new file mode 100644
index 0000000..b4ab5f1
--- /dev/null
+++ b/extensions/test/data/extension/background.js
@@ -0,0 +1,7 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+window.addEventListener('load', function() {
+  chrome.test.notifyPass();
+});
diff --git a/extensions/test/data/extension/manifest.json b/extensions/test/data/extension/manifest.json
new file mode 100644
index 0000000..9bef9dc
--- /dev/null
+++ b/extensions/test/data/extension/manifest.json
@@ -0,0 +1,9 @@
+{
+  "name": "Test Extension",
+  "description": "Simple testing extension. Succeeds when its background page runs.",
+  "manifest_version": 2,
+  "version": "1",
+  "background": {
+    "scripts": ["background.js"]
+  }
+}
diff --git a/extensions/test/data/keep_alive_client_unittest.js b/extensions/test/data/keep_alive_client_unittest.js
index 97ddba54..2997d5a 100644
--- a/extensions/test/data/keep_alive_client_unittest.js
+++ b/extensions/test/data/keep_alive_client_unittest.js
@@ -28,17 +28,27 @@
 });
 var apiFunction = binding.generate().getDevices;
 
+function runFunction() {
+  apiFunction(function() {
+    if (shouldSucceed)
+      test.assertNoLastError();
+    else
+      test.assertTrue(!!chrome.runtime.lastError);
+    test.succeed();
+  });
+}
+
 unittestBindings.exportTests([
   // Test that a keep alive is created and destroyed for a successful API call.
   function testKeepAliveWithSuccessfulCall() {
     shouldSucceed = true;
-    utils.promise(apiFunction).then(test.succeed, test.fail);
+    runFunction();
   },
 
   // Test that a keep alive is created and destroyed for an unsuccessful API
   // call.
   function testKeepAliveWithError() {
     shouldSucceed = false;
-    utils.promise(apiFunction).then(test.fail, test.succeed);
+    runFunction();
   },
 ], test.runTests, exports);
diff --git a/extensions/test/data/utils_unittest.js b/extensions/test/data/utils_unittest.js
index 64adec4..32b2616b 100644
--- a/extensions/test/data/utils_unittest.js
+++ b/extensions/test/data/utils_unittest.js
@@ -92,56 +92,4 @@
   AssertTrue(subsub instanceof SubSubClass);
 }
 
-function fakeApiFunction(shouldSucceed, numberOfResults, callback) {
-  if (shouldSucceed) {
-    var result = [];
-    for (var i = 0; i < numberOfResults; i++) {
-      result.push(i);
-    }
-    $Function.apply(callback, null, result);
-    return;
-  }
-  chrome.runtime.lastError = 'error message';
-  callback();
-  chrome.runtime.lastError = null;
-}
-
-function testPromiseNoResult() {
-  utils.promise(fakeApiFunction, true, 0).then(function(result) {
-    AssertTrue(result === undefined);
-  }).catch(function(e) {
-    AssertFalse(True);
-  });
-}
-
-function testPromiseOneResult() {
-  utils.promise(fakeApiFunction, true, 1).then(function(result) {
-    AssertTrue(result === 0);
-  }).catch(function(e) {
-    AssertFalse(True);
-  });
-}
-
-function testPromiseTwoResults() {
-  utils.promise(fakeApiFunction, true, 2).then(function(result) {
-    AssertTrue(result.length == 2);
-    AssertTrue(result[0] == 0);
-    AssertTrue(result[1] == 1);
-  }).catch(function(e) {
-    AssertFalse(True);
-  });
-}
-
-function testPromiseError() {
-  utils.promise(fakeApiFunction, false, 0).then(function(result) {
-    AssertFalse(True);
-  }).catch(function(e) {
-    AssertTrue(e.message == 'error message');
-  });
-}
-
 exports.testSuperClass = testSuperClass;
-exports.testPromiseNoResult = testPromiseNoResult;
-exports.testPromiseOneResult = testPromiseOneResult;
-exports.testPromiseTwoResults = testPromiseTwoResults;
-exports.testPromiseError = testPromiseError;
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn
index f7938545..91ce5d6 100644
--- a/ios/chrome/browser/ui/bookmarks/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -123,6 +123,7 @@
     "//ios/chrome/browser/ui/keyboard",
     "//ios/chrome/browser/ui/material_components",
     "//ios/chrome/browser/ui/ntp",
+    "//ios/chrome/browser/ui/sync",
     "//ios/chrome/browser/undo",
     "//ios/public/provider/chrome/browser",
     "//ios/public/provider/chrome/browser/ui",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm
index b1b08de..4e5c759 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm
@@ -32,9 +32,11 @@
 #import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_collection_view_background.h"
+#import "ios/chrome/browser/ui/bookmarks/bookmark_home_waiting_view.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_promo_cell.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_signin_promo_cell.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
+#import "ios/chrome/browser/ui/sync/synced_sessions_bridge.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -74,16 +76,11 @@
 CGFloat rowHeight = 48.0;
 // Minimal acceptable favicon size, in points.
 CGFloat minFaviconSizePt = 16;
-
-// Delay in seconds to which the empty background view will be shown when the
-// collection view is empty.
-// This delay should not be too small to let enough time to load bookmarks
-// from network.
-const NSTimeInterval kShowEmptyBookmarksBackgroundRefreshDelay = 1.0;
 }
 
 @interface BookmarkCollectionView ()<BookmarkPromoCellDelegate,
                                      SigninPromoViewConsumer,
+                                     SyncedSessionsObserver,
                                      UICollectionViewDataSource,
                                      UICollectionViewDelegateFlowLayout,
                                      UIGestureRecognizerDelegate> {
@@ -95,6 +92,9 @@
   // True if the promo is visible.
   BOOL _promoVisible;
 
+  // True if the loading spinner background is visible.
+  BOOL _spinnerVisible;
+
   // Mediator, helper for the sign-in promo view.
   SigninPromoViewMediator* _signinPromoViewMediator;
 
@@ -107,6 +107,9 @@
   std::map<IntegerPair, base::CancelableTaskTracker::TaskId> _faviconLoadTasks;
   // Task tracker used for async favicon loads.
   base::CancelableTaskTracker _faviconTaskTracker;
+  // Observer to keep track of the signin and syncing status.
+  std::unique_ptr<synced_sessions::SyncedSessionsObserverBridge>
+      _syncedSessionsObserver;
 }
 
 // Redefined to be readwrite.
@@ -222,6 +225,8 @@
 
     [self setupViews];
     [self updateCollectionView];
+    _syncedSessionsObserver.reset(
+        new synced_sessions::SyncedSessionsObserverBridge(self, _browserState));
   }
   return self;
 }
@@ -905,21 +910,6 @@
 
 #pragma mark - empty background
 
-// Schedules showing or hiding the empty bookmarks background view if the
-// collection view is empty by calling showEmptyBackgroundIfNeeded after
-// kShowEmptyBookmarksBackgroundRefreshDelay.
-// Multiple call to this method will cancel previous scheduled call to
-// showEmptyBackgroundIfNeeded before scheduling a new one.
-- (void)scheduleEmptyBackgroundVisibilityUpdate {
-  [NSObject cancelPreviousPerformRequestsWithTarget:self
-                                           selector:@selector
-                                           (updateEmptyBackgroundVisibility)
-                                             object:nil];
-  [self performSelector:@selector(updateEmptyBackgroundVisibility)
-             withObject:nil
-             afterDelay:kShowEmptyBookmarksBackgroundRefreshDelay];
-}
-
 - (BOOL)isCollectionViewEmpty {
   BOOL collectionViewIsEmpty = YES;
   const NSInteger numberOfSections = [self numberOfSections];
@@ -932,13 +922,6 @@
   return collectionViewIsEmpty;
 }
 
-// Shows/hides empty bookmarks background view if the collections view is empty.
-- (void)updateEmptyBackgroundVisibility {
-  const BOOL showEmptyBackground =
-      [self isCollectionViewEmpty] && ![self shouldShowPromoCell];
-  [self setEmptyBackgroundVisible:showEmptyBackground];
-}
-
 // Shows/hides empty bookmarks background view with an animation.
 - (void)setEmptyBackgroundVisible:(BOOL)emptyBackgroundVisible {
   [UIView beginAnimations:@"alpha" context:NULL];
@@ -946,6 +929,55 @@
   [UIView commitAnimations];
 }
 
+// If the collection view is not empty, hide the empty bookmarks and loading
+// spinner background. If the collection view is empty, shows the loading
+// spinner background (if syncing) or the empty bookmarks background (if not
+// syncing).
+- (void)showEmptyOrLoadingSpinnerBackgroundIfNeeded {
+  const BOOL isEmpty =
+      [self isCollectionViewEmpty] && ![self shouldShowPromoCell];
+  if (!isEmpty) {
+    [self hideLoadingSpinnerBackground];
+    [self hideEmptyBackground];
+    return;
+  }
+  if (_syncedSessionsObserver->IsSyncing()) {
+    [self showLoadingSpinnerBackground];
+    return;
+  }
+  [self showEmptyBackground];
+}
+
+// Shows loading spinner background view
+- (void)showLoadingSpinnerBackground {
+  if (!_spinnerVisible) {
+    BookmarkHomeWaitingView* spinnerView = [[BookmarkHomeWaitingView alloc]
+        initWithFrame:self.collectionView.bounds];
+    [spinnerView startWaiting];
+    self.collectionView.backgroundView = spinnerView;
+    [self setEmptyBackgroundVisible:NO];
+    _spinnerVisible = YES;
+  }
+}
+
+// Hides loading spinner background view
+- (void)hideLoadingSpinnerBackground {
+  if (_spinnerVisible) {
+    self.collectionView.backgroundView = self.emptyCollectionBackgroundView;
+    _spinnerVisible = NO;
+  }
+}
+
+- (void)showEmptyBackground {
+  [self hideLoadingSpinnerBackground];
+  [self setEmptyBackgroundVisible:YES];
+  self.collectionView.backgroundView = self.emptyCollectionBackgroundView;
+}
+
+- (void)hideEmptyBackground {
+  [self setEmptyBackgroundVisible:NO];
+}
+
 #pragma mark - UICollectionViewDataSource
 
 - (NSInteger)collectionView:(UICollectionView*)collectionView
@@ -954,12 +986,7 @@
       [self numberOfItemsInSection:section];
   const BOOL isCollectionViewEmpty = [self isCollectionViewEmpty];
   self.collectionView.scrollEnabled = !isCollectionViewEmpty;
-  if (isCollectionViewEmpty) {
-    [self scheduleEmptyBackgroundVisibilityUpdate];
-  } else {
-    // Hide empty bookmarks now.
-    [self setEmptyBackgroundVisible:NO];
-  }
+  [self showEmptyOrLoadingSpinnerBackgroundIfNeeded];
   return numberOfItemsInSection;
 }
 
@@ -968,12 +995,7 @@
   const NSInteger numberOfSections = [self numberOfSections];
   const BOOL collectionViewIsEmpty = 0 == numberOfSections;
   self.collectionView.scrollEnabled = !collectionViewIsEmpty;
-  if (collectionViewIsEmpty) {
-    [self scheduleEmptyBackgroundVisibilityUpdate];
-  } else {
-    // Hide empty bookmarks now.
-    [self setEmptyBackgroundVisible:NO];
-  }
+  [self showEmptyOrLoadingSpinnerBackgroundIfNeeded];
   return numberOfSections;
 }
 
@@ -1290,4 +1312,13 @@
   return NO;
 }
 
+#pragma mark - Exposed to the SyncedSessionsObserver
+
+- (void)reloadSessions {
+}
+
+- (void)onSyncStateChanged {
+  [self showEmptyOrLoadingSpinnerBackgroundIfNeeded];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
index b16dc7c..9d938fd 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
@@ -21,7 +21,6 @@
     "//base",
     "//components/browser_sync",
     "//components/sessions",
-    "//components/signin/core/browser",
     "//components/sync",
     "//ios/chrome/app/strings",
     "//ios/chrome/app/theme",
@@ -29,7 +28,6 @@
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/metrics:metrics_internal",
     "//ios/chrome/browser/sessions",
-    "//ios/chrome/browser/signin",
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/authentication:authentication_arc",
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_panel_controller.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_panel_controller.mm
index 2117a49..f3f0682 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_panel_controller.mm
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_panel_controller.mm
@@ -8,12 +8,10 @@
 
 #include "components/browser_sync/profile_sync_service.h"
 #include "components/sessions/core/tab_restore_service.h"
-#include "components/signin/core/browser/signin_manager.h"
 #include "components/sync_sessions/open_tabs_ui_delegate.h"
 #include "components/sync_sessions/synced_session.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
-#include "ios/chrome/browser/signin/signin_manager_factory.h"
 #include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
@@ -187,9 +185,7 @@
 #pragma mark - Private
 
 - (BOOL)isSignedIn {
-  SigninManager* signin_manager =
-      ios::SigninManagerFactory::GetForBrowserState(_browserState);
-  return signin_manager->IsAuthenticated();
+  return _syncedSessionsObserver->IsSignedIn();
 }
 
 - (BOOL)isSyncTabsEnabled {
diff --git a/ios/chrome/browser/ui/sync/synced_sessions_bridge.h b/ios/chrome/browser/ui/sync/synced_sessions_bridge.h
index fb2fb19..996c7fe 100644
--- a/ios/chrome/browser/ui/sync/synced_sessions_bridge.h
+++ b/ios/chrome/browser/ui/sync/synced_sessions_bridge.h
@@ -45,11 +45,19 @@
   // Returns true if the first sync cycle that contains session information is
   // completed. Returns false otherwise.
   bool IsFirstSyncCycleCompleted();
+  // Returns true if user is signed in.
+  bool IsSignedIn();
+  // Returns true if it is undergoing the first sync cycle.
+  bool IsSyncing();
+  // Check if the first sync cycle is completed.  This keeps
+  // IsFirstSyncCycleCompleted() and first_sync_cycle_is_completed_ updated.
+  void CheckIfFirstSyncIsCompleted();
 
  private:
   base::WeakNSProtocol<id<SyncedSessionsObserver>> owner_;
   SigninManager* signin_manager_;
   syncer::SyncService* sync_service_;
+  ios::ChromeBrowserState* browser_state_;
   ScopedObserver<SigninManagerBase, SigninManagerBase::Observer>
       signin_manager_observer_;
   // Stores whether the first sync cycle that contains session information is
diff --git a/ios/chrome/browser/ui/sync/synced_sessions_bridge.mm b/ios/chrome/browser/ui/sync/synced_sessions_bridge.mm
index 16b07af4..1847d7d 100644
--- a/ios/chrome/browser/ui/sync/synced_sessions_bridge.mm
+++ b/ios/chrome/browser/ui/sync/synced_sessions_bridge.mm
@@ -10,6 +10,8 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/signin/signin_manager_factory.h"
 #include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_setup_service.h"
+#include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -30,9 +32,11 @@
           ios::SigninManagerFactory::GetForBrowserState(browserState)),
       sync_service_(
           IOSChromeProfileSyncServiceFactory::GetForBrowserState(browserState)),
+      browser_state_(browserState),
       signin_manager_observer_(this),
       first_sync_cycle_is_completed_(false) {
   signin_manager_observer_.Add(signin_manager_);
+  CheckIfFirstSyncIsCompleted();
 }
 
 SyncedSessionsObserverBridge::~SyncedSessionsObserverBridge() {}
@@ -40,15 +44,14 @@
 #pragma mark - SyncObserverBridge
 
 void SyncedSessionsObserverBridge::OnStateChanged(syncer::SyncService* sync) {
-  if (!signin_manager_->IsAuthenticated())
+  if (!IsSignedIn())
     first_sync_cycle_is_completed_ = false;
   [owner_ onSyncStateChanged];
 }
 
 void SyncedSessionsObserverBridge::OnSyncCycleCompleted(
     syncer::SyncService* sync) {
-  if (sync_service_->GetActiveDataTypes().Has(syncer::SESSIONS))
-    first_sync_cycle_is_completed_ = true;
+  CheckIfFirstSyncIsCompleted();
   [owner_ onSyncStateChanged];
 }
 
@@ -66,6 +69,11 @@
   return first_sync_cycle_is_completed_;
 }
 
+void SyncedSessionsObserverBridge::CheckIfFirstSyncIsCompleted() {
+  first_sync_cycle_is_completed_ =
+      sync_service_->GetActiveDataTypes().Has(syncer::SESSIONS);
+}
+
 #pragma mark - SigninManagerBase::Observer
 
 void SyncedSessionsObserverBridge::GoogleSignedOut(
@@ -75,4 +83,24 @@
   [owner_ reloadSessions];
 }
 
+#pragma mark - Signin and syncing status
+
+bool SyncedSessionsObserverBridge::IsSignedIn() {
+  return signin_manager_->IsAuthenticated();
+}
+
+bool SyncedSessionsObserverBridge::IsSyncing() {
+  if (!IsSignedIn())
+    return false;
+
+  SyncSetupService* sync_setup_service =
+      SyncSetupServiceFactory::GetForBrowserState(browser_state_);
+
+  bool sync_enabled = sync_setup_service->IsSyncEnabled();
+  bool no_sync_error = (sync_setup_service->GetSyncServiceState() ==
+                        SyncSetupService::kNoSyncServiceError);
+
+  return sync_enabled && no_sync_error && !IsFirstSyncCycleCompleted();
+}
+
 }  // namespace synced_sessions
diff --git a/ios/components/io_thread/ios_io_thread.h b/ios/components/io_thread/ios_io_thread.h
index adad232e..cb2de145 100644
--- a/ios/components/io_thread/ios_io_thread.h
+++ b/ios/components/io_thread/ios_io_thread.h
@@ -18,7 +18,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
 #include "components/prefs/pref_member.h"
 #include "components/ssl_config/ssl_config_service_manager.h"
 #include "ios/web/public/web_thread_delegate.h"
@@ -153,8 +152,6 @@
 
   const net::HttpNetworkSession::Params& NetworkSessionParams() const;
 
-  base::TimeTicks creation_time() const;
-
  protected:
   // A string describing the current application version. For example: "stable"
   // or "dev". An empty string is an acceptable value. This string is used to
@@ -225,8 +222,6 @@
   scoped_refptr<SystemURLRequestContextGetter>
       system_url_request_context_getter_;
 
-  const base::TimeTicks creation_time_;
-
   base::WeakPtrFactory<IOSIOThread> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(IOSIOThread);
diff --git a/ios/components/io_thread/ios_io_thread.mm b/ios/components/io_thread/ios_io_thread.mm
index ababca5..e9be0f9 100644
--- a/ios/components/io_thread/ios_io_thread.mm
+++ b/ios/components/io_thread/ios_io_thread.mm
@@ -237,7 +237,6 @@
                          net_log::ChromeNetLog* net_log)
     : net_log_(net_log),
       globals_(nullptr),
-      creation_time_(base::TimeTicks::Now()),
       weak_factory_(this) {
   pref_proxy_config_tracker_ =
       ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
@@ -413,10 +412,6 @@
   return params_;
 }
 
-base::TimeTicks IOSIOThread::creation_time() const {
-  return creation_time_;
-}
-
 net::SSLConfigService* IOSIOThread::GetSSLConfigService() {
   return ssl_config_service_manager_->Get();
 }
diff --git a/ipc/ipc_mojo_perftest.cc b/ipc/ipc_mojo_perftest.cc
index b491abf1..8513e08 100644
--- a/ipc/ipc_mojo_perftest.cc
+++ b/ipc/ipc_mojo_perftest.cc
@@ -1,744 +1,753 @@
-// 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 <stddef.h>

-#include <memory>

-

-#include "base/memory/ptr_util.h"

-#include "base/message_loop/message_loop.h"

-#include "base/process/process_metrics.h"

-#include "base/run_loop.h"

-#include "base/strings/stringprintf.h"

-#include "base/test/perf_time_logger.h"

-#include "base/test/test_io_thread.h"

-#include "base/threading/thread_task_runner_handle.h"

-#include "build/build_config.h"

-#include "ipc/ipc_channel_mojo.h"

-#include "ipc/ipc_test.mojom.h"

-#include "ipc/ipc_test_base.h"

-#include "mojo/edk/embedder/embedder.h"

-#include "mojo/edk/embedder/platform_channel_pair.h"

-#include "mojo/edk/test/mojo_test_base.h"

-#include "mojo/edk/test/multiprocess_test_helper.h"

-#include "mojo/public/cpp/bindings/binding.h"

-#include "mojo/public/cpp/system/message_pipe.h"

-

-#define IPC_MESSAGE_IMPL

-#include "ipc/ipc_message_macros.h"

-

-#define IPC_MESSAGE_START TestMsgStart

-

-IPC_MESSAGE_CONTROL0(TestMsg_Hello)

-IPC_MESSAGE_CONTROL0(TestMsg_Quit)

-IPC_MESSAGE_CONTROL1(TestMsg_Ping, std::string)

-IPC_SYNC_MESSAGE_CONTROL1_1(TestMsg_SyncPing, std::string, std::string)

-

-namespace IPC {

-namespace {

-

-class PerformanceChannelListener : public Listener {

- public:

-  explicit PerformanceChannelListener(const std::string& label)

-      : label_(label),

-        sender_(NULL),

-        msg_count_(0),

-        msg_size_(0),

-        sync_(false),

-        count_down_(0) {

-    VLOG(1) << "Server listener up";

-  }

-

-  ~PerformanceChannelListener() override { VLOG(1) << "Server listener down"; }

-

-  void Init(Sender* sender) {

-    DCHECK(!sender_);

-    sender_ = sender;

-  }

-

-  // Call this before running the message loop.

-  void SetTestParams(int msg_count, size_t msg_size, bool sync) {

-    DCHECK_EQ(0, count_down_);

-    msg_count_ = msg_count;

-    msg_size_ = msg_size;

-    sync_ = sync;

-    count_down_ = msg_count_;

-    payload_ = std::string(msg_size_, 'a');

-  }

-

-  bool OnMessageReceived(const Message& message) override {

-    CHECK(sender_);

-

-    bool handled = true;

-    IPC_BEGIN_MESSAGE_MAP(PerformanceChannelListener, message)

-      IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)

-      IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)

-      IPC_MESSAGE_UNHANDLED(handled = false)

-    IPC_END_MESSAGE_MAP()

-    return handled;

-  }

-

-  void OnHello() {

-    // Start timing on hello.

-    DCHECK(!perf_logger_.get());

-    std::string test_name =

-        base::StringPrintf("IPC_%s_Perf_%dx_%u", label_.c_str(), msg_count_,

-                           static_cast<unsigned>(msg_size_));

-    perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));

-    if (sync_) {

-      for (int i = 0; i < count_down_; ++i) {

-        std::string response;

-        sender_->Send(new TestMsg_SyncPing(payload_, &response));

-      }

-      base::MessageLoop::current()->QuitWhenIdle();

-    } else {

-      SendPong();

-    }

-  }

-

-  void OnPing(const std::string& payload) {

-    // Include message deserialization in latency.

-    DCHECK_EQ(payload_.size(), payload.size());

-

-    CHECK(count_down_ > 0);

-    count_down_--;

-    if (count_down_ == 0) {

-      perf_logger_.reset();  // Stop the perf timer now.

-      base::MessageLoop::current()->QuitWhenIdle();

-      return;

-    }

-

-    SendPong();

-  }

-

-  void SendPong() { sender_->Send(new TestMsg_Ping(payload_)); }

-

- private:

-  std::string label_;

-  Sender* sender_;

-  int msg_count_;

-  size_t msg_size_;

-  bool sync_;

-

-  int count_down_;

-  std::string payload_;

-  std::unique_ptr<base::PerfTimeLogger> perf_logger_;

-};

-

-// This channel listener just replies to all messages with the exact same

-// message. It assumes each message has one string parameter. When the string

-// "quit" is sent, it will exit.

-class ChannelReflectorListener : public Listener {

- public:

-  ChannelReflectorListener() : channel_(NULL) {

-    VLOG(1) << "Client listener up";

-  }

-

-  ~ChannelReflectorListener() override { VLOG(1) << "Client listener down"; }

-

-  void Init(Sender* channel) {

-    DCHECK(!channel_);

-    channel_ = channel;

-  }

-

-  bool OnMessageReceived(const Message& message) override {

-    CHECK(channel_);

-    bool handled = true;

-    IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)

-      IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)

-      IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)

-      IPC_MESSAGE_HANDLER(TestMsg_SyncPing, OnSyncPing)

-      IPC_MESSAGE_HANDLER(TestMsg_Quit, OnQuit)

-      IPC_MESSAGE_UNHANDLED(handled = false)

-    IPC_END_MESSAGE_MAP()

-    return handled;

-  }

-

-  void OnHello() { channel_->Send(new TestMsg_Hello); }

-

-  void OnPing(const std::string& payload) {

-    channel_->Send(new TestMsg_Ping(payload));

-  }

-

-  void OnSyncPing(const std::string& payload, std::string* response) {

-    *response = payload;

-  }

-

-  void OnQuit() { base::MessageLoop::current()->QuitWhenIdle(); }

-

-  void Send(IPC::Message* message) { channel_->Send(message); }

-

- private:

-  Sender* channel_;

-};

-

-// This class locks the current thread to a particular CPU core. This is

-// important because otherwise the different threads and processes of these

-// tests end up on different CPU cores which means that all of the cores are

-// lightly loaded so the OS (Windows and Linux) fails to ramp up the CPU

-// frequency, leading to unpredictable and often poor performance.

-class LockThreadAffinity {

- public:

-  explicit LockThreadAffinity(int cpu_number) : affinity_set_ok_(false) {

-#if defined(OS_WIN)

-    const DWORD_PTR thread_mask = static_cast<DWORD_PTR>(1) << cpu_number;

-    old_affinity_ = SetThreadAffinityMask(GetCurrentThread(), thread_mask);

-    affinity_set_ok_ = old_affinity_ != 0;

-#elif defined(OS_LINUX)

-    cpu_set_t cpuset;

-    CPU_ZERO(&cpuset);

-    CPU_SET(cpu_number, &cpuset);

-    auto get_result = sched_getaffinity(0, sizeof(old_cpuset_), &old_cpuset_);

-    DCHECK_EQ(0, get_result);

-    auto set_result = sched_setaffinity(0, sizeof(cpuset), &cpuset);

-    // Check for get_result failure, even though it should always succeed.

-    affinity_set_ok_ = (set_result == 0) && (get_result == 0);

-#endif

-    if (!affinity_set_ok_)

-      LOG(WARNING) << "Failed to set thread affinity to CPU " << cpu_number;

-  }

-

-  ~LockThreadAffinity() {

-    if (!affinity_set_ok_)

-      return;

-#if defined(OS_WIN)

-    auto set_result = SetThreadAffinityMask(GetCurrentThread(), old_affinity_);

-    DCHECK_NE(0u, set_result);

-#elif defined(OS_LINUX)

-    auto set_result = sched_setaffinity(0, sizeof(old_cpuset_), &old_cpuset_);

-    DCHECK_EQ(0, set_result);

-#endif

-  }

-

- private:

-  bool affinity_set_ok_;

-#if defined(OS_WIN)

-  DWORD_PTR old_affinity_;

-#elif defined(OS_LINUX)

-  cpu_set_t old_cpuset_;

-#endif

-

-  DISALLOW_COPY_AND_ASSIGN(LockThreadAffinity);

-};

-

-class PingPongTestParams {

- public:

-  PingPongTestParams(size_t size, int count)

-      : message_size_(size), message_count_(count) {}

-

-  size_t message_size() const { return message_size_; }

-  int message_count() const { return message_count_; }

-

- private:

-  size_t message_size_;

-  int message_count_;

-};

-

-std::vector<PingPongTestParams> GetDefaultTestParams() {

-// Test several sizes. We use 12^N for message size, and limit the message

-// count to keep the test duration reasonable.

-#ifdef NDEBUG

-  const int kMultiplier = 100;

-#else

-  // Debug builds on Windows run these tests orders of magnitude more slowly.

-  const int kMultiplier = 1;

-#endif

-  std::vector<PingPongTestParams> list;

-  list.push_back(PingPongTestParams(12, 500 * kMultiplier));

-  list.push_back(PingPongTestParams(144, 500 * kMultiplier));

-  list.push_back(PingPongTestParams(1728, 500 * kMultiplier));

-  list.push_back(PingPongTestParams(20736, 120 * kMultiplier));

-  list.push_back(PingPongTestParams(248832, 10 * kMultiplier));

-  return list;

-}

-

-// Avoid core 0 due to conflicts with Intel's Power Gadget.

-// Setting thread affinity will fail harmlessly on single/dual core machines.

-const int kSharedCore = 2;

-

-class MojoChannelPerfTest : public IPCChannelMojoTestBase {

- public:

-  MojoChannelPerfTest() = default;

-  ~MojoChannelPerfTest() override = default;

-

-  void RunTestChannelProxyPingPong() {

-    io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));

-

-    Init("MojoPerfTestClient");

-

-    // Set up IPC channel and start client.

-    PerformanceChannelListener listener("ChannelProxy");

-    auto channel_proxy = IPC::ChannelProxy::Create(

-        TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,

-        io_thread_->task_runner());

-    listener.Init(channel_proxy.get());

-

-    LockThreadAffinity thread_locker(kSharedCore);

-    std::vector<PingPongTestParams> params = GetDefaultTestParams();

-    for (size_t i = 0; i < params.size(); i++) {

-      listener.SetTestParams(params[i].message_count(),

-                             params[i].message_size(), false);

-

-      // This initial message will kick-start the ping-pong of messages.

-      channel_proxy->Send(new TestMsg_Hello);

-

-      // Run message loop.

-      base::RunLoop().Run();

-    }

-

-    // Send quit message.

-    channel_proxy->Send(new TestMsg_Quit);

-

-    EXPECT_TRUE(WaitForClientShutdown());

-    channel_proxy.reset();

-

-    io_thread_.reset();

-  }

-

-  void RunTestChannelProxySyncPing() {

-    io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));

-

-    Init("MojoPerfTestClient");

-

-    // Set up IPC channel and start client.

-    PerformanceChannelListener listener("ChannelProxy");

-    auto channel_proxy = IPC::ChannelProxy::Create(

-        TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,

-        io_thread_->task_runner());

-    listener.Init(channel_proxy.get());

-

-    LockThreadAffinity thread_locker(kSharedCore);

-    std::vector<PingPongTestParams> params = GetDefaultTestParams();

-    for (size_t i = 0; i < params.size(); i++) {

-      listener.SetTestParams(params[i].message_count(),

-                             params[i].message_size(), true);

-

-      // This initial message will kick-start the ping-pong of messages.

-      channel_proxy->Send(new TestMsg_Hello);

-

-      // Run message loop.

-      base::RunLoop().Run();

-    }

-

-    // Send quit message.

-    channel_proxy->Send(new TestMsg_Quit);

-

-    EXPECT_TRUE(WaitForClientShutdown());

-    channel_proxy.reset();

-

-    io_thread_.reset();

-  }

-

-  scoped_refptr<base::TaskRunner> io_task_runner() {

-    if (io_thread_)

-      return io_thread_->task_runner();

-    return base::ThreadTaskRunnerHandle::Get();

-  }

-

- private:

-  std::unique_ptr<base::TestIOThread> io_thread_;

-};

-

-TEST_F(MojoChannelPerfTest, ChannelProxyPingPong) {

-  RunTestChannelProxyPingPong();

-

-  base::RunLoop run_loop;

-  run_loop.RunUntilIdle();

-}

-

-TEST_F(MojoChannelPerfTest, ChannelProxySyncPing) {

-  RunTestChannelProxySyncPing();

-

-  base::RunLoop run_loop;

-  run_loop.RunUntilIdle();

-}

-

-class MojoPerfTestClient {

- public:

-  MojoPerfTestClient() : listener_(new ChannelReflectorListener()) {

-    mojo::edk::test::MultiprocessTestHelper::ChildSetup();

-  }

-

-  ~MojoPerfTestClient() = default;

-

-  int Run(MojoHandle handle) {

-    handle_ = mojo::MakeScopedHandle(mojo::MessagePipeHandle(handle));

-    LockThreadAffinity thread_locker(kSharedCore);

-    base::TestIOThread io_thread(base::TestIOThread::kAutoStart);

-

-    std::unique_ptr<ChannelProxy> channel =

-        IPC::ChannelProxy::Create(handle_.release(), Channel::MODE_CLIENT,

-                                  listener_.get(), io_thread.task_runner());

-    listener_->Init(channel.get());

-

-    base::RunLoop().Run();

-    return 0;

-  }

-

- private:

-  base::MessageLoop main_message_loop_;

-  std::unique_ptr<ChannelReflectorListener> listener_;

-  std::unique_ptr<Channel> channel_;

-  mojo::ScopedMessagePipeHandle handle_;

-};

-

-MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain) {

-  MojoPerfTestClient client;

-  int rv = mojo::edk::test::MultiprocessTestHelper::RunClientMain(

-      base::Bind(&MojoPerfTestClient::Run, base::Unretained(&client)),

-      true /* pass_pipe_ownership_to_main */);

-

-  base::RunLoop run_loop;

-  run_loop.RunUntilIdle();

-

-  return rv;

-}

-

-class ReflectorImpl : public IPC::mojom::Reflector {

- public:

-  explicit ReflectorImpl(mojo::ScopedMessagePipeHandle handle)

-      : binding_(this, IPC::mojom::ReflectorRequest(std::move(handle))) {}

-  ~ReflectorImpl() override {

-    ignore_result(binding_.Unbind().PassMessagePipe().release());

-  }

-

- private:

-  // IPC::mojom::Reflector:

-  void Ping(const std::string& value, PingCallback callback) override {

-    std::move(callback).Run(value);

-  }

-

-  void SyncPing(const std::string& value, PingCallback callback) override {

-    std::move(callback).Run(value);

-  }

-

-  void Quit() override { base::MessageLoop::current()->QuitWhenIdle(); }

-

-  mojo::Binding<IPC::mojom::Reflector> binding_;

-};

-

-class MojoInterfacePerfTest : public mojo::edk::test::MojoTestBase {

- public:

-  MojoInterfacePerfTest() : message_count_(0), count_down_(0) {}

-

- protected:

-  void RunPingPongServer(MojoHandle mp, const std::string& label) {

-    label_ = label;

-

-    mojo::MessagePipeHandle mp_handle(mp);

-    mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);

-    ping_receiver_.Bind(IPC::mojom::ReflectorPtrInfo(std::move(scoped_mp), 0u));

-

-    LockThreadAffinity thread_locker(kSharedCore);

-    std::vector<PingPongTestParams> params = GetDefaultTestParams();

-    for (size_t i = 0; i < params.size(); i++) {

-      ping_receiver_->Ping("hello", base::Bind(&MojoInterfacePerfTest::OnPong,

-                                               base::Unretained(this)));

-      message_count_ = count_down_ = params[i].message_count();

-      payload_ = std::string(params[i].message_size(), 'a');

-

-      base::RunLoop().Run();

-    }

-

-    ping_receiver_->Quit();

-

-    ignore_result(ping_receiver_.PassInterface().PassHandle().release());

-  }

-

-  void OnPong(const std::string& value) {

-    if (value == "hello") {

-      DCHECK(!perf_logger_.get());

-      std::string test_name =

-          base::StringPrintf("IPC_%s_Perf_%dx_%zu", label_.c_str(),

-                             message_count_, payload_.size());

-      perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));

-    } else {

-      DCHECK_EQ(payload_.size(), value.size());

-

-      CHECK(count_down_ > 0);

-      count_down_--;

-      if (count_down_ == 0) {

-        perf_logger_.reset();

-        base::MessageLoop::current()->QuitWhenIdle();

-        return;

-      }

-    }

-

-    if (sync_) {

-      for (int i = 0; i < count_down_; ++i) {

-        std::string response;

-        ping_receiver_->SyncPing(payload_, &response);

-      }

-      base::MessageLoop::current()->QuitWhenIdle();

-    } else {

-      ping_receiver_->Ping(payload_, base::Bind(&MojoInterfacePerfTest::OnPong,

-                                                base::Unretained(this)));

-    }

-  }

-

-  static int RunPingPongClient(MojoHandle mp) {

-    mojo::MessagePipeHandle mp_handle(mp);

-    mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);

-

-    // In single process mode, this is running in a task and by default other

-    // tasks (in particular, the binding) won't run. To keep the single process

-    // and multi-process code paths the same, enable nestable tasks.

-    base::MessageLoop::ScopedNestableTaskAllower nest_loop(

-        base::MessageLoop::current());

-

-    LockThreadAffinity thread_locker(kSharedCore);

-    ReflectorImpl impl(std::move(scoped_mp));

-    base::RunLoop().Run();

-    return 0;

-  }

-

-  bool sync_ = false;

-

- private:

-  int message_count_;

-  int count_down_;

-  std::string label_;

-  std::string payload_;

-  IPC::mojom::ReflectorPtr ping_receiver_;

-  std::unique_ptr<base::PerfTimeLogger> perf_logger_;

-

-  DISALLOW_COPY_AND_ASSIGN(MojoInterfacePerfTest);

-};

-

-enum class InProcessMessageMode {

-  kSerialized,

-  kUnserialized,

-};

-

-class MojoInProcessInterfacePerfTest

-    : public MojoInterfacePerfTest,

-      public testing::WithParamInterface<InProcessMessageMode> {

- public:

-  MojoInProcessInterfacePerfTest() {

-    switch (GetParam()) {

-      case InProcessMessageMode::kSerialized:

-        mojo::Connector::OverrideDefaultSerializationBehaviorForTesting(

-            mojo::Connector::OutgoingSerializationMode::kEager,

-            mojo::Connector::IncomingSerializationMode::kDispatchAsIs);

-        break;

-      case InProcessMessageMode::kUnserialized:

-        mojo::Connector::OverrideDefaultSerializationBehaviorForTesting(

-            mojo::Connector::OutgoingSerializationMode::kLazy,

-            mojo::Connector::IncomingSerializationMode::kDispatchAsIs);

-        break;

-    }

-  }

-};

-

-DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MojoInterfacePerfTest, h) {

-  base::MessageLoop main_message_loop;

-  return RunPingPongClient(h);

-}

-

-// Similar to MojoChannelPerfTest above, but uses a Mojo interface instead of

-// raw IPC::Messages.

-TEST_F(MojoInterfacePerfTest, MultiprocessPingPong) {

-  RunTestClient("PingPongClient", [&](MojoHandle h) {

-    base::MessageLoop main_message_loop;

-    RunPingPongServer(h, "Multiprocess");

-  });

-}

-

-TEST_F(MojoInterfacePerfTest, MultiprocessSyncPing) {

-  sync_ = true;

-  RunTestClient("PingPongClient", [&](MojoHandle h) {

-    base::MessageLoop main_message_loop;

-    RunPingPongServer(h, "MultiprocessSync");

-  });

-}

-

-// A single process version of the above test.

-TEST_P(MojoInProcessInterfacePerfTest, MultiThreadPingPong) {

-  MojoHandle server_handle, client_handle;

-  CreateMessagePipe(&server_handle, &client_handle);

-

-  base::Thread client_thread("PingPongClient");

-  client_thread.Start();

-  client_thread.task_runner()->PostTask(

-      FROM_HERE,

-      base::Bind(base::IgnoreResult(&RunPingPongClient), client_handle));

-

-  base::MessageLoop main_message_loop;

-  RunPingPongServer(server_handle, "SingleProcess");

-}

-

-TEST_P(MojoInProcessInterfacePerfTest, SingleThreadPingPong) {

-  MojoHandle server_handle, client_handle;

-  CreateMessagePipe(&server_handle, &client_handle);

-

-  base::MessageLoop main_message_loop;

-  mojo::MessagePipeHandle mp_handle(client_handle);

-  mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);

-  LockThreadAffinity thread_locker(kSharedCore);

-  ReflectorImpl impl(std::move(scoped_mp));

-

-  RunPingPongServer(server_handle, "SingleProcess");

-}

-

-INSTANTIATE_TEST_CASE_P(,

-                        MojoInProcessInterfacePerfTest,

-                        testing::Values(InProcessMessageMode::kSerialized,

-                                        InProcessMessageMode::kUnserialized));

-

-class CallbackPerfTest : public testing::Test {

- public:

-  CallbackPerfTest()

-      : client_thread_("PingPongClient"), message_count_(0), count_down_(0) {}

-

- protected:

-  void RunMultiThreadPingPongServer() {

-    client_thread_.Start();

-

-    LockThreadAffinity thread_locker(kSharedCore);

-    std::vector<PingPongTestParams> params = GetDefaultTestParams();

-    for (size_t i = 0; i < params.size(); i++) {

-      std::string hello("hello");

-      client_thread_.task_runner()->PostTask(

-          FROM_HERE,

-          base::Bind(&CallbackPerfTest::Ping, base::Unretained(this), hello));

-      message_count_ = count_down_ = params[i].message_count();

-      payload_ = std::string(params[i].message_size(), 'a');

-

-      base::RunLoop().Run();

-    }

-  }

-

-  void Ping(const std::string& value) {

-    main_message_loop_.task_runner()->PostTask(

-        FROM_HERE,

-        base::Bind(&CallbackPerfTest::OnPong, base::Unretained(this), value));

-  }

-

-  void OnPong(const std::string& value) {

-    if (value == "hello") {

-      DCHECK(!perf_logger_.get());

-      std::string test_name =

-          base::StringPrintf("Callback_MultiProcess_Perf_%dx_%zu",

-                             message_count_, payload_.size());

-      perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));

-    } else {

-      DCHECK_EQ(payload_.size(), value.size());

-

-      CHECK(count_down_ > 0);

-      count_down_--;

-      if (count_down_ == 0) {

-        perf_logger_.reset();

-        base::MessageLoop::current()->QuitWhenIdle();

-        return;

-      }

-    }

-

-    client_thread_.task_runner()->PostTask(

-        FROM_HERE,

-        base::Bind(&CallbackPerfTest::Ping, base::Unretained(this), payload_));

-  }

-

-  void RunSingleThreadNoPostTaskPingPongServer() {

-    LockThreadAffinity thread_locker(kSharedCore);

-    std::vector<PingPongTestParams> params = GetDefaultTestParams();

-    base::Callback<void(const std::string&,

-                        const base::Callback<void(const std::string&)>&)>

-        ping = base::Bind(&CallbackPerfTest::SingleThreadPingNoPostTask,

-                          base::Unretained(this));

-    for (size_t i = 0; i < params.size(); i++) {

-      payload_ = std::string(params[i].message_size(), 'a');

-      std::string test_name =

-          base::StringPrintf("Callback_SingleThreadPostTask_Perf_%dx_%zu",

-                             params[i].message_count(), payload_.size());

-      perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));

-      for (int j = 0; j < params[i].message_count(); ++j) {

-        ping.Run(payload_,

-                 base::Bind(&CallbackPerfTest::SingleThreadPongNoPostTask,

-                            base::Unretained(this)));

-      }

-      perf_logger_.reset();

-    }

-  }

-

-  void SingleThreadPingNoPostTask(

-      const std::string& value,

-      const base::Callback<void(const std::string&)>& pong) {

-    pong.Run(value);

-  }

-

-  void SingleThreadPongNoPostTask(const std::string& value) {}

-

-  void RunSingleThreadPostTaskPingPongServer() {

-    LockThreadAffinity thread_locker(kSharedCore);

-    std::vector<PingPongTestParams> params = GetDefaultTestParams();

-    for (size_t i = 0; i < params.size(); i++) {

-      std::string hello("hello");

-      base::MessageLoop::current()->task_runner()->PostTask(

-          FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask,

-                                base::Unretained(this), hello));

-      message_count_ = count_down_ = params[i].message_count();

-      payload_ = std::string(params[i].message_size(), 'a');

-

-      base::RunLoop().Run();

-    }

-  }

-

-  void SingleThreadPingPostTask(const std::string& value) {

-    base::MessageLoop::current()->task_runner()->PostTask(

-        FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPongPostTask,

-                              base::Unretained(this), value));

-  }

-

-  void SingleThreadPongPostTask(const std::string& value) {

-    if (value == "hello") {

-      DCHECK(!perf_logger_.get());

-      std::string test_name =

-          base::StringPrintf("Callback_SingleThreadNoPostTask_Perf_%dx_%zu",

-                             message_count_, payload_.size());

-      perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));

-    } else {

-      DCHECK_EQ(payload_.size(), value.size());

-

-      CHECK(count_down_ > 0);

-      count_down_--;

-      if (count_down_ == 0) {

-        perf_logger_.reset();

-        base::MessageLoop::current()->QuitWhenIdle();

-        return;

-      }

-    }

-

-    base::MessageLoop::current()->task_runner()->PostTask(

-        FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask,

-                              base::Unretained(this), payload_));

-  }

-

- private:

-  base::Thread client_thread_;

-  base::MessageLoop main_message_loop_;

-  int message_count_;

-  int count_down_;

-  std::string payload_;

-  std::unique_ptr<base::PerfTimeLogger> perf_logger_;

-

-  DISALLOW_COPY_AND_ASSIGN(CallbackPerfTest);

-};

-

-// Sends the same data as above using PostTask to a different thread instead of

-// IPCs for comparison.

-TEST_F(CallbackPerfTest, MultiThreadPingPong) {

-  RunMultiThreadPingPongServer();

-}

-

-// Sends the same data as above using PostTask to the same thread.

-TEST_F(CallbackPerfTest, SingleThreadPostTaskPingPong) {

-  RunSingleThreadPostTaskPingPongServer();

-}

-

-// Sends the same data as above without using PostTask to the same thread.

-TEST_F(CallbackPerfTest, SingleThreadNoPostTaskPingPong) {

-  RunSingleThreadNoPostTaskPingPongServer();

-}

-

-}  // namespace

-}  // namespace IPC

+// 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 <stddef.h>
+#include <memory>
+
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/process/process_metrics.h"
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/perf_time_logger.h"
+#include "base/test/test_io_thread.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
+#include "ipc/ipc_channel_mojo.h"
+#include "ipc/ipc_sync_channel.h"
+#include "ipc/ipc_test.mojom.h"
+#include "ipc/ipc_test_base.h"
+#include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/embedder/platform_channel_pair.h"
+#include "mojo/edk/test/mojo_test_base.h"
+#include "mojo/edk/test/multiprocess_test_helper.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+
+#define IPC_MESSAGE_IMPL
+#include "ipc/ipc_message_macros.h"
+
+#define IPC_MESSAGE_START TestMsgStart
+
+IPC_MESSAGE_CONTROL0(TestMsg_Hello)
+IPC_MESSAGE_CONTROL0(TestMsg_Quit)
+IPC_MESSAGE_CONTROL1(TestMsg_Ping, std::string)
+IPC_SYNC_MESSAGE_CONTROL1_1(TestMsg_SyncPing, std::string, std::string)
+
+namespace IPC {
+namespace {
+
+class PerformanceChannelListener : public Listener {
+ public:
+  explicit PerformanceChannelListener(const std::string& label)
+      : label_(label),
+        sender_(NULL),
+        msg_count_(0),
+        msg_size_(0),
+        sync_(false),
+        count_down_(0) {
+    VLOG(1) << "Server listener up";
+  }
+
+  ~PerformanceChannelListener() override { VLOG(1) << "Server listener down"; }
+
+  void Init(Sender* sender) {
+    DCHECK(!sender_);
+    sender_ = sender;
+  }
+
+  // Call this before running the message loop.
+  void SetTestParams(int msg_count, size_t msg_size, bool sync) {
+    DCHECK_EQ(0, count_down_);
+    msg_count_ = msg_count;
+    msg_size_ = msg_size;
+    sync_ = sync;
+    count_down_ = msg_count_;
+    payload_ = std::string(msg_size_, 'a');
+  }
+
+  bool OnMessageReceived(const Message& message) override {
+    CHECK(sender_);
+
+    bool handled = true;
+    IPC_BEGIN_MESSAGE_MAP(PerformanceChannelListener, message)
+      IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
+      IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
+      IPC_MESSAGE_UNHANDLED(handled = false)
+    IPC_END_MESSAGE_MAP()
+    return handled;
+  }
+
+  void OnHello() {
+    // Start timing on hello.
+    DCHECK(!perf_logger_.get());
+    std::string test_name =
+        base::StringPrintf("IPC_%s_Perf_%dx_%u", label_.c_str(), msg_count_,
+                           static_cast<unsigned>(msg_size_));
+    perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
+    if (sync_) {
+      for (int i = 0; i < count_down_; ++i) {
+        std::string response;
+        sender_->Send(new TestMsg_SyncPing(payload_, &response));
+        DCHECK_EQ(response, payload_);
+      }
+      perf_logger_.reset();
+      base::MessageLoop::current()->QuitWhenIdle();
+    } else {
+      SendPong();
+    }
+  }
+
+  void OnPing(const std::string& payload) {
+    // Include message deserialization in latency.
+    DCHECK_EQ(payload_.size(), payload.size());
+
+    CHECK(count_down_ > 0);
+    count_down_--;
+    if (count_down_ == 0) {
+      perf_logger_.reset();  // Stop the perf timer now.
+      base::MessageLoop::current()->QuitWhenIdle();
+      return;
+    }
+
+    SendPong();
+  }
+
+  void SendPong() { sender_->Send(new TestMsg_Ping(payload_)); }
+
+ private:
+  std::string label_;
+  Sender* sender_;
+  int msg_count_;
+  size_t msg_size_;
+  bool sync_;
+
+  int count_down_;
+  std::string payload_;
+  std::unique_ptr<base::PerfTimeLogger> perf_logger_;
+};
+
+// This channel listener just replies to all messages with the exact same
+// message. It assumes each message has one string parameter. When the string
+// "quit" is sent, it will exit.
+class ChannelReflectorListener : public Listener {
+ public:
+  ChannelReflectorListener() : channel_(NULL) {
+    VLOG(1) << "Client listener up";
+  }
+
+  ~ChannelReflectorListener() override { VLOG(1) << "Client listener down"; }
+
+  void Init(Sender* channel) {
+    DCHECK(!channel_);
+    channel_ = channel;
+  }
+
+  bool OnMessageReceived(const Message& message) override {
+    CHECK(channel_);
+    bool handled = true;
+    IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
+      IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
+      IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
+      IPC_MESSAGE_HANDLER(TestMsg_SyncPing, OnSyncPing)
+      IPC_MESSAGE_HANDLER(TestMsg_Quit, OnQuit)
+      IPC_MESSAGE_UNHANDLED(handled = false)
+    IPC_END_MESSAGE_MAP()
+    return handled;
+  }
+
+  void OnHello() { channel_->Send(new TestMsg_Hello); }
+
+  void OnPing(const std::string& payload) {
+    channel_->Send(new TestMsg_Ping(payload));
+  }
+
+  void OnSyncPing(const std::string& payload, std::string* response) {
+    *response = payload;
+  }
+
+  void OnQuit() { base::MessageLoop::current()->QuitWhenIdle(); }
+
+  void Send(IPC::Message* message) { channel_->Send(message); }
+
+ private:
+  Sender* channel_;
+};
+
+// This class locks the current thread to a particular CPU core. This is
+// important because otherwise the different threads and processes of these
+// tests end up on different CPU cores which means that all of the cores are
+// lightly loaded so the OS (Windows and Linux) fails to ramp up the CPU
+// frequency, leading to unpredictable and often poor performance.
+class LockThreadAffinity {
+ public:
+  explicit LockThreadAffinity(int cpu_number) : affinity_set_ok_(false) {
+#if defined(OS_WIN)
+    const DWORD_PTR thread_mask = static_cast<DWORD_PTR>(1) << cpu_number;
+    old_affinity_ = SetThreadAffinityMask(GetCurrentThread(), thread_mask);
+    affinity_set_ok_ = old_affinity_ != 0;
+#elif defined(OS_LINUX)
+    cpu_set_t cpuset;
+    CPU_ZERO(&cpuset);
+    CPU_SET(cpu_number, &cpuset);
+    auto get_result = sched_getaffinity(0, sizeof(old_cpuset_), &old_cpuset_);
+    DCHECK_EQ(0, get_result);
+    auto set_result = sched_setaffinity(0, sizeof(cpuset), &cpuset);
+    // Check for get_result failure, even though it should always succeed.
+    affinity_set_ok_ = (set_result == 0) && (get_result == 0);
+#endif
+    if (!affinity_set_ok_)
+      LOG(WARNING) << "Failed to set thread affinity to CPU " << cpu_number;
+  }
+
+  ~LockThreadAffinity() {
+    if (!affinity_set_ok_)
+      return;
+#if defined(OS_WIN)
+    auto set_result = SetThreadAffinityMask(GetCurrentThread(), old_affinity_);
+    DCHECK_NE(0u, set_result);
+#elif defined(OS_LINUX)
+    auto set_result = sched_setaffinity(0, sizeof(old_cpuset_), &old_cpuset_);
+    DCHECK_EQ(0, set_result);
+#endif
+  }
+
+ private:
+  bool affinity_set_ok_;
+#if defined(OS_WIN)
+  DWORD_PTR old_affinity_;
+#elif defined(OS_LINUX)
+  cpu_set_t old_cpuset_;
+#endif
+
+  DISALLOW_COPY_AND_ASSIGN(LockThreadAffinity);
+};
+
+class PingPongTestParams {
+ public:
+  PingPongTestParams(size_t size, int count)
+      : message_size_(size), message_count_(count) {}
+
+  size_t message_size() const { return message_size_; }
+  int message_count() const { return message_count_; }
+
+ private:
+  size_t message_size_;
+  int message_count_;
+};
+
+std::vector<PingPongTestParams> GetDefaultTestParams() {
+// Test several sizes. We use 12^N for message size, and limit the message
+// count to keep the test duration reasonable.
+#ifdef NDEBUG
+  const int kMultiplier = 100;
+#else
+  // Debug builds on Windows run these tests orders of magnitude more slowly.
+  const int kMultiplier = 1;
+#endif
+  std::vector<PingPongTestParams> list;
+  list.push_back(PingPongTestParams(12, 500 * kMultiplier));
+  list.push_back(PingPongTestParams(144, 500 * kMultiplier));
+  list.push_back(PingPongTestParams(1728, 500 * kMultiplier));
+  list.push_back(PingPongTestParams(20736, 120 * kMultiplier));
+  list.push_back(PingPongTestParams(248832, 10 * kMultiplier));
+  return list;
+}
+
+// Avoid core 0 due to conflicts with Intel's Power Gadget.
+// Setting thread affinity will fail harmlessly on single/dual core machines.
+const int kSharedCore = 2;
+
+class MojoChannelPerfTest : public IPCChannelMojoTestBase {
+ public:
+  MojoChannelPerfTest() = default;
+  ~MojoChannelPerfTest() override = default;
+
+  void RunTestChannelProxyPingPong() {
+    io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));
+
+    Init("MojoPerfTestClient");
+
+    // Set up IPC channel and start client.
+    PerformanceChannelListener listener("ChannelProxy");
+    auto channel_proxy = IPC::ChannelProxy::Create(
+        TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
+        io_thread_->task_runner());
+    listener.Init(channel_proxy.get());
+
+    LockThreadAffinity thread_locker(kSharedCore);
+    std::vector<PingPongTestParams> params = GetDefaultTestParams();
+    for (size_t i = 0; i < params.size(); i++) {
+      listener.SetTestParams(params[i].message_count(),
+                             params[i].message_size(), false);
+
+      // This initial message will kick-start the ping-pong of messages.
+      channel_proxy->Send(new TestMsg_Hello);
+
+      // Run message loop.
+      base::RunLoop().Run();
+    }
+
+    // Send quit message.
+    channel_proxy->Send(new TestMsg_Quit);
+
+    EXPECT_TRUE(WaitForClientShutdown());
+    channel_proxy.reset();
+
+    io_thread_.reset();
+  }
+
+  void RunTestChannelProxySyncPing() {
+    io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));
+
+    Init("MojoPerfTestClient");
+
+    // Set up IPC channel and start client.
+    PerformanceChannelListener listener("ChannelProxy");
+    base::WaitableEvent shutdown_event(
+        base::WaitableEvent::ResetPolicy::MANUAL,
+        base::WaitableEvent::InitialState::NOT_SIGNALED);
+    auto channel_proxy = IPC::SyncChannel::Create(
+        TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
+        io_thread_->task_runner(), false, &shutdown_event);
+    listener.Init(channel_proxy.get());
+
+    LockThreadAffinity thread_locker(kSharedCore);
+    std::vector<PingPongTestParams> params = GetDefaultTestParams();
+    for (size_t i = 0; i < params.size(); i++) {
+      listener.SetTestParams(params[i].message_count(),
+                             params[i].message_size(), true);
+
+      // This initial message will kick-start the ping-pong of messages.
+      channel_proxy->Send(new TestMsg_Hello);
+
+      // Run message loop.
+      base::RunLoop().Run();
+    }
+
+    // Send quit message.
+    channel_proxy->Send(new TestMsg_Quit);
+
+    EXPECT_TRUE(WaitForClientShutdown());
+    channel_proxy.reset();
+
+    io_thread_.reset();
+  }
+
+  scoped_refptr<base::TaskRunner> io_task_runner() {
+    if (io_thread_)
+      return io_thread_->task_runner();
+    return base::ThreadTaskRunnerHandle::Get();
+  }
+
+ private:
+  std::unique_ptr<base::TestIOThread> io_thread_;
+};
+
+TEST_F(MojoChannelPerfTest, ChannelProxyPingPong) {
+  RunTestChannelProxyPingPong();
+
+  base::RunLoop run_loop;
+  run_loop.RunUntilIdle();
+}
+
+TEST_F(MojoChannelPerfTest, ChannelProxySyncPing) {
+  RunTestChannelProxySyncPing();
+
+  base::RunLoop run_loop;
+  run_loop.RunUntilIdle();
+}
+
+class MojoPerfTestClient {
+ public:
+  MojoPerfTestClient() : listener_(new ChannelReflectorListener()) {
+    mojo::edk::test::MultiprocessTestHelper::ChildSetup();
+  }
+
+  ~MojoPerfTestClient() = default;
+
+  int Run(MojoHandle handle) {
+    handle_ = mojo::MakeScopedHandle(mojo::MessagePipeHandle(handle));
+    LockThreadAffinity thread_locker(kSharedCore);
+    base::TestIOThread io_thread(base::TestIOThread::kAutoStart);
+
+    std::unique_ptr<ChannelProxy> channel =
+        IPC::ChannelProxy::Create(handle_.release(), Channel::MODE_CLIENT,
+                                  listener_.get(), io_thread.task_runner());
+    listener_->Init(channel.get());
+
+    base::RunLoop().Run();
+    return 0;
+  }
+
+ private:
+  base::MessageLoop main_message_loop_;
+  std::unique_ptr<ChannelReflectorListener> listener_;
+  std::unique_ptr<Channel> channel_;
+  mojo::ScopedMessagePipeHandle handle_;
+};
+
+MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain) {
+  MojoPerfTestClient client;
+  int rv = mojo::edk::test::MultiprocessTestHelper::RunClientMain(
+      base::Bind(&MojoPerfTestClient::Run, base::Unretained(&client)),
+      true /* pass_pipe_ownership_to_main */);
+
+  base::RunLoop run_loop;
+  run_loop.RunUntilIdle();
+
+  return rv;
+}
+
+class ReflectorImpl : public IPC::mojom::Reflector {
+ public:
+  explicit ReflectorImpl(mojo::ScopedMessagePipeHandle handle)
+      : binding_(this, IPC::mojom::ReflectorRequest(std::move(handle))) {}
+  ~ReflectorImpl() override {
+    ignore_result(binding_.Unbind().PassMessagePipe().release());
+  }
+
+ private:
+  // IPC::mojom::Reflector:
+  void Ping(const std::string& value, PingCallback callback) override {
+    std::move(callback).Run(value);
+  }
+
+  void SyncPing(const std::string& value, PingCallback callback) override {
+    std::move(callback).Run(value);
+  }
+
+  void Quit() override { base::MessageLoop::current()->QuitWhenIdle(); }
+
+  mojo::Binding<IPC::mojom::Reflector> binding_;
+};
+
+class MojoInterfacePerfTest : public mojo::edk::test::MojoTestBase {
+ public:
+  MojoInterfacePerfTest() : message_count_(0), count_down_(0) {}
+
+ protected:
+  void RunPingPongServer(MojoHandle mp, const std::string& label) {
+    label_ = label;
+
+    mojo::MessagePipeHandle mp_handle(mp);
+    mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
+    ping_receiver_.Bind(IPC::mojom::ReflectorPtrInfo(std::move(scoped_mp), 0u));
+
+    LockThreadAffinity thread_locker(kSharedCore);
+    std::vector<PingPongTestParams> params = GetDefaultTestParams();
+    for (size_t i = 0; i < params.size(); i++) {
+      ping_receiver_->Ping("hello", base::Bind(&MojoInterfacePerfTest::OnPong,
+                                               base::Unretained(this)));
+      message_count_ = count_down_ = params[i].message_count();
+      payload_ = std::string(params[i].message_size(), 'a');
+
+      base::RunLoop().Run();
+    }
+
+    ping_receiver_->Quit();
+
+    ignore_result(ping_receiver_.PassInterface().PassHandle().release());
+  }
+
+  void OnPong(const std::string& value) {
+    if (value == "hello") {
+      DCHECK(!perf_logger_.get());
+      std::string test_name =
+          base::StringPrintf("IPC_%s_Perf_%dx_%zu", label_.c_str(),
+                             message_count_, payload_.size());
+      perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
+    } else {
+      DCHECK_EQ(payload_.size(), value.size());
+
+      CHECK(count_down_ > 0);
+      count_down_--;
+      if (count_down_ == 0) {
+        perf_logger_.reset();
+        base::MessageLoop::current()->QuitWhenIdle();
+        return;
+      }
+    }
+
+    if (sync_) {
+      for (int i = 0; i < count_down_; ++i) {
+        std::string response;
+        ping_receiver_->SyncPing(payload_, &response);
+        DCHECK_EQ(response, payload_);
+      }
+      perf_logger_.reset();
+      base::MessageLoop::current()->QuitWhenIdle();
+    } else {
+      ping_receiver_->Ping(payload_, base::Bind(&MojoInterfacePerfTest::OnPong,
+                                                base::Unretained(this)));
+    }
+  }
+
+  static int RunPingPongClient(MojoHandle mp) {
+    mojo::MessagePipeHandle mp_handle(mp);
+    mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
+
+    // In single process mode, this is running in a task and by default other
+    // tasks (in particular, the binding) won't run. To keep the single process
+    // and multi-process code paths the same, enable nestable tasks.
+    base::MessageLoop::ScopedNestableTaskAllower nest_loop(
+        base::MessageLoop::current());
+
+    LockThreadAffinity thread_locker(kSharedCore);
+    ReflectorImpl impl(std::move(scoped_mp));
+    base::RunLoop().Run();
+    return 0;
+  }
+
+  bool sync_ = false;
+
+ private:
+  int message_count_;
+  int count_down_;
+  std::string label_;
+  std::string payload_;
+  IPC::mojom::ReflectorPtr ping_receiver_;
+  std::unique_ptr<base::PerfTimeLogger> perf_logger_;
+
+  DISALLOW_COPY_AND_ASSIGN(MojoInterfacePerfTest);
+};
+
+enum class InProcessMessageMode {
+  kSerialized,
+  kUnserialized,
+};
+
+class MojoInProcessInterfacePerfTest
+    : public MojoInterfacePerfTest,
+      public testing::WithParamInterface<InProcessMessageMode> {
+ public:
+  MojoInProcessInterfacePerfTest() {
+    switch (GetParam()) {
+      case InProcessMessageMode::kSerialized:
+        mojo::Connector::OverrideDefaultSerializationBehaviorForTesting(
+            mojo::Connector::OutgoingSerializationMode::kEager,
+            mojo::Connector::IncomingSerializationMode::kDispatchAsIs);
+        break;
+      case InProcessMessageMode::kUnserialized:
+        mojo::Connector::OverrideDefaultSerializationBehaviorForTesting(
+            mojo::Connector::OutgoingSerializationMode::kLazy,
+            mojo::Connector::IncomingSerializationMode::kDispatchAsIs);
+        break;
+    }
+  }
+};
+
+DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MojoInterfacePerfTest, h) {
+  base::MessageLoop main_message_loop;
+  return RunPingPongClient(h);
+}
+
+// Similar to MojoChannelPerfTest above, but uses a Mojo interface instead of
+// raw IPC::Messages.
+TEST_F(MojoInterfacePerfTest, MultiprocessPingPong) {
+  RunTestClient("PingPongClient", [&](MojoHandle h) {
+    base::MessageLoop main_message_loop;
+    RunPingPongServer(h, "Multiprocess");
+  });
+}
+
+TEST_F(MojoInterfacePerfTest, MultiprocessSyncPing) {
+  sync_ = true;
+  RunTestClient("PingPongClient", [&](MojoHandle h) {
+    base::MessageLoop main_message_loop;
+    RunPingPongServer(h, "MultiprocessSync");
+  });
+}
+
+// A single process version of the above test.
+TEST_P(MojoInProcessInterfacePerfTest, MultiThreadPingPong) {
+  MojoHandle server_handle, client_handle;
+  CreateMessagePipe(&server_handle, &client_handle);
+
+  base::Thread client_thread("PingPongClient");
+  client_thread.Start();
+  client_thread.task_runner()->PostTask(
+      FROM_HERE,
+      base::Bind(base::IgnoreResult(&RunPingPongClient), client_handle));
+
+  base::MessageLoop main_message_loop;
+  RunPingPongServer(server_handle, "SingleProcess");
+}
+
+TEST_P(MojoInProcessInterfacePerfTest, SingleThreadPingPong) {
+  MojoHandle server_handle, client_handle;
+  CreateMessagePipe(&server_handle, &client_handle);
+
+  base::MessageLoop main_message_loop;
+  mojo::MessagePipeHandle mp_handle(client_handle);
+  mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
+  LockThreadAffinity thread_locker(kSharedCore);
+  ReflectorImpl impl(std::move(scoped_mp));
+
+  RunPingPongServer(server_handle, "SingleProcess");
+}
+
+INSTANTIATE_TEST_CASE_P(,
+                        MojoInProcessInterfacePerfTest,
+                        testing::Values(InProcessMessageMode::kSerialized,
+                                        InProcessMessageMode::kUnserialized));
+
+class CallbackPerfTest : public testing::Test {
+ public:
+  CallbackPerfTest()
+      : client_thread_("PingPongClient"), message_count_(0), count_down_(0) {}
+
+ protected:
+  void RunMultiThreadPingPongServer() {
+    client_thread_.Start();
+
+    LockThreadAffinity thread_locker(kSharedCore);
+    std::vector<PingPongTestParams> params = GetDefaultTestParams();
+    for (size_t i = 0; i < params.size(); i++) {
+      std::string hello("hello");
+      client_thread_.task_runner()->PostTask(
+          FROM_HERE,
+          base::Bind(&CallbackPerfTest::Ping, base::Unretained(this), hello));
+      message_count_ = count_down_ = params[i].message_count();
+      payload_ = std::string(params[i].message_size(), 'a');
+
+      base::RunLoop().Run();
+    }
+  }
+
+  void Ping(const std::string& value) {
+    main_message_loop_.task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&CallbackPerfTest::OnPong, base::Unretained(this), value));
+  }
+
+  void OnPong(const std::string& value) {
+    if (value == "hello") {
+      DCHECK(!perf_logger_.get());
+      std::string test_name =
+          base::StringPrintf("Callback_MultiProcess_Perf_%dx_%zu",
+                             message_count_, payload_.size());
+      perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
+    } else {
+      DCHECK_EQ(payload_.size(), value.size());
+
+      CHECK(count_down_ > 0);
+      count_down_--;
+      if (count_down_ == 0) {
+        perf_logger_.reset();
+        base::MessageLoop::current()->QuitWhenIdle();
+        return;
+      }
+    }
+
+    client_thread_.task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&CallbackPerfTest::Ping, base::Unretained(this), payload_));
+  }
+
+  void RunSingleThreadNoPostTaskPingPongServer() {
+    LockThreadAffinity thread_locker(kSharedCore);
+    std::vector<PingPongTestParams> params = GetDefaultTestParams();
+    base::Callback<void(const std::string&,
+                        const base::Callback<void(const std::string&)>&)>
+        ping = base::Bind(&CallbackPerfTest::SingleThreadPingNoPostTask,
+                          base::Unretained(this));
+    for (size_t i = 0; i < params.size(); i++) {
+      payload_ = std::string(params[i].message_size(), 'a');
+      std::string test_name =
+          base::StringPrintf("Callback_SingleThreadPostTask_Perf_%dx_%zu",
+                             params[i].message_count(), payload_.size());
+      perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
+      for (int j = 0; j < params[i].message_count(); ++j) {
+        ping.Run(payload_,
+                 base::Bind(&CallbackPerfTest::SingleThreadPongNoPostTask,
+                            base::Unretained(this)));
+      }
+      perf_logger_.reset();
+    }
+  }
+
+  void SingleThreadPingNoPostTask(
+      const std::string& value,
+      const base::Callback<void(const std::string&)>& pong) {
+    pong.Run(value);
+  }
+
+  void SingleThreadPongNoPostTask(const std::string& value) {}
+
+  void RunSingleThreadPostTaskPingPongServer() {
+    LockThreadAffinity thread_locker(kSharedCore);
+    std::vector<PingPongTestParams> params = GetDefaultTestParams();
+    for (size_t i = 0; i < params.size(); i++) {
+      std::string hello("hello");
+      base::MessageLoop::current()->task_runner()->PostTask(
+          FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask,
+                                base::Unretained(this), hello));
+      message_count_ = count_down_ = params[i].message_count();
+      payload_ = std::string(params[i].message_size(), 'a');
+
+      base::RunLoop().Run();
+    }
+  }
+
+  void SingleThreadPingPostTask(const std::string& value) {
+    base::MessageLoop::current()->task_runner()->PostTask(
+        FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPongPostTask,
+                              base::Unretained(this), value));
+  }
+
+  void SingleThreadPongPostTask(const std::string& value) {
+    if (value == "hello") {
+      DCHECK(!perf_logger_.get());
+      std::string test_name =
+          base::StringPrintf("Callback_SingleThreadNoPostTask_Perf_%dx_%zu",
+                             message_count_, payload_.size());
+      perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
+    } else {
+      DCHECK_EQ(payload_.size(), value.size());
+
+      CHECK(count_down_ > 0);
+      count_down_--;
+      if (count_down_ == 0) {
+        perf_logger_.reset();
+        base::MessageLoop::current()->QuitWhenIdle();
+        return;
+      }
+    }
+
+    base::MessageLoop::current()->task_runner()->PostTask(
+        FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask,
+                              base::Unretained(this), payload_));
+  }
+
+ private:
+  base::Thread client_thread_;
+  base::MessageLoop main_message_loop_;
+  int message_count_;
+  int count_down_;
+  std::string payload_;
+  std::unique_ptr<base::PerfTimeLogger> perf_logger_;
+
+  DISALLOW_COPY_AND_ASSIGN(CallbackPerfTest);
+};
+
+// Sends the same data as above using PostTask to a different thread instead of
+// IPCs for comparison.
+TEST_F(CallbackPerfTest, MultiThreadPingPong) {
+  RunMultiThreadPingPongServer();
+}
+
+// Sends the same data as above using PostTask to the same thread.
+TEST_F(CallbackPerfTest, SingleThreadPostTaskPingPong) {
+  RunSingleThreadPostTaskPingPongServer();
+}
+
+// Sends the same data as above without using PostTask to the same thread.
+TEST_F(CallbackPerfTest, SingleThreadNoPostTaskPingPong) {
+  RunSingleThreadNoPostTaskPingPongServer();
+}
+
+}  // namespace
+}  // namespace IPC
diff --git a/mash/test/mash_test_suite.cc b/mash/test/mash_test_suite.cc
index 9b0d6684..1b9abf6 100644
--- a/mash/test/mash_test_suite.cc
+++ b/mash/test/mash_test_suite.cc
@@ -43,7 +43,7 @@
   resources = resources.Append(FILE_PATH_LITERAL("ash_mus_resources.pak"));
   ui::ResourceBundle::InitSharedInstanceWithPakPath(resources);
 
-  ash::test::AshTestHelper::config_ = ash::Config::MASH;
+  ash::AshTestHelper::config_ = ash::Config::MASH;
 
   base::DiscardableMemoryAllocator::SetInstance(&discardable_memory_allocator_);
   env_ = aura::Env::CreateInstance(aura::Env::Mode::MUS);
diff --git a/media/capture/mojo/BUILD.gn b/media/capture/mojo/BUILD.gn
index e862ea15..0f982ab 100644
--- a/media/capture/mojo/BUILD.gn
+++ b/media/capture/mojo/BUILD.gn
@@ -21,9 +21,6 @@
     "image_capture.mojom",
   ]
 
-  # TODO(crbug.com/714018): Convert the implementation to use OnceCallback.
-  use_once_callback = false
-
   # TODO(crbug.com/699569): Convert to use the new JS bindings.
   use_new_js_bindings = false
 }
diff --git a/media/capture/video/fake_video_capture_device_unittest.cc b/media/capture/video/fake_video_capture_device_unittest.cc
index 841fad5..f636d225 100644
--- a/media/capture/video/fake_video_capture_device_unittest.cc
+++ b/media/capture/video/fake_video_capture_device_unittest.cc
@@ -163,13 +163,24 @@
     OnCorrectGetPhotoState();
   }
   MOCK_METHOD0(OnCorrectGetPhotoState, void(void));
-  MOCK_METHOD1(OnGetPhotoStateFailure,
-               void(base::Callback<void(mojom::PhotoStatePtr)>));
+
+  void OnGetPhotoStateFailure(
+      mojom::ImageCapture::GetPhotoStateCallback callback) {
+    OnGetPhotoStateFailureInternal(callback);
+  }
+  MOCK_METHOD1(OnGetPhotoStateFailureInternal,
+               void(mojom::ImageCapture::GetPhotoStateCallback&));
 
   const mojom::PhotoState* state() { return state_.get(); }
 
   MOCK_METHOD1(OnCorrectSetPhotoOptions, void(bool));
-  MOCK_METHOD1(OnSetPhotoOptionsFailure, void(base::Callback<void(bool)>));
+
+  void OnSetPhotoOptionsFailure(
+      mojom::ImageCapture::SetOptionsCallback callback) {
+    OnSetPhotoOptionsFailureInternal(callback);
+  }
+  MOCK_METHOD1(OnSetPhotoOptionsFailureInternal,
+               void(mojom::ImageCapture::SetOptionsCallback&));
 
   // GMock doesn't support move-only arguments, so we use this forward method.
   void DoOnPhotoTaken(mojom::BlobPtr blob) {
@@ -184,7 +195,12 @@
     OnCorrectPhotoTaken();
   }
   MOCK_METHOD0(OnCorrectPhotoTaken, void(void));
-  MOCK_METHOD1(OnTakePhotoFailure, void(base::Callback<void(mojom::BlobPtr)>));
+
+  void OnTakePhotoFailure(mojom::ImageCapture::TakePhotoCallback callback) {
+    OnTakePhotoFailureInternal(callback);
+  }
+  MOCK_METHOD1(OnTakePhotoFailureInternal,
+               void(mojom::ImageCapture::TakePhotoCallback&));
 
  private:
   friend class base::RefCounted<ImageCaptureClient>;
@@ -376,9 +392,10 @@
   device->AllocateAndStart(capture_params, std::move(client_));
 
   VideoCaptureDevice::GetPhotoStateCallback scoped_get_callback(
-      base::Bind(&ImageCaptureClient::DoOnGetPhotoState, image_capture_client_),
-      base::Bind(&ImageCaptureClient::OnGetPhotoStateFailure,
-                 image_capture_client_));
+      base::BindOnce(&ImageCaptureClient::DoOnGetPhotoState,
+                     image_capture_client_),
+      base::BindOnce(&ImageCaptureClient::OnGetPhotoStateFailure,
+                     image_capture_client_));
 
   EXPECT_CALL(*image_capture_client_.get(), OnCorrectGetPhotoState()).Times(1);
   device->GetPhotoState(std::move(scoped_get_callback));
@@ -445,10 +462,10 @@
   // Set options: zoom to the maximum value.
   const int max_zoom_value = state->zoom->max;
   VideoCaptureDevice::SetPhotoOptionsCallback scoped_set_callback(
-      base::Bind(&ImageCaptureClient::OnCorrectSetPhotoOptions,
-                 image_capture_client_),
-      base::Bind(&ImageCaptureClient::OnSetPhotoOptionsFailure,
-                 image_capture_client_));
+      base::BindOnce(&ImageCaptureClient::OnCorrectSetPhotoOptions,
+                     image_capture_client_),
+      base::BindOnce(&ImageCaptureClient::OnSetPhotoOptionsFailure,
+                     image_capture_client_));
 
   mojom::PhotoSettingsPtr settings = mojom::PhotoSettings::New();
   settings->zoom = max_zoom_value;
@@ -490,9 +507,10 @@
   device->AllocateAndStart(capture_params, std::move(client_));
 
   VideoCaptureDevice::TakePhotoCallback scoped_callback(
-      base::Bind(&ImageCaptureClient::DoOnPhotoTaken, image_capture_client_),
-      base::Bind(&ImageCaptureClient::OnTakePhotoFailure,
-                 image_capture_client_));
+      base::BindOnce(&ImageCaptureClient::DoOnPhotoTaken,
+                     image_capture_client_),
+      base::BindOnce(&ImageCaptureClient::OnTakePhotoFailure,
+                     image_capture_client_));
 
   EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1);
   device->TakePhoto(std::move(scoped_callback));
diff --git a/media/capture/video/video_capture_device.h b/media/capture/video/video_capture_device.h
index 888462a..6cff3ae9 100644
--- a/media/capture/video/video_capture_device.h
+++ b/media/capture/video/video_capture_device.h
@@ -275,13 +275,13 @@
   // levels etc). On success, invokes |callback|. On failure, drops callback
   // without invoking it.
   using GetPhotoStateCallback =
-      ScopedResultCallback<base::Callback<void(mojom::PhotoStatePtr)>>;
+      ScopedResultCallback<base::OnceCallback<void(mojom::PhotoStatePtr)>>;
   virtual void GetPhotoState(GetPhotoStateCallback callback);
 
   // On success, invokes |callback| with value |true|. On failure, drops
   // callback without invoking it.
   using SetPhotoOptionsCallback =
-      ScopedResultCallback<base::Callback<void(bool)>>;
+      ScopedResultCallback<base::OnceCallback<void(bool)>>;
   virtual void SetPhotoOptions(mojom::PhotoSettingsPtr settings,
                                SetPhotoOptionsCallback callback);
 
@@ -290,7 +290,7 @@
   // where TakePhoto() is called, if the photo was successfully taken. On
   // failure, drops callback without invoking it.
   using TakePhotoCallback =
-      ScopedResultCallback<base::Callback<void(mojom::BlobPtr blob)>>;
+      ScopedResultCallback<base::OnceCallback<void(mojom::BlobPtr blob)>>;
   virtual void TakePhoto(TakePhotoCallback callback);
 
   // Gets the power line frequency, either from the params if specified by the
diff --git a/media/capture/video/video_capture_device_unittest.cc b/media/capture/video/video_capture_device_unittest.cc
index 4aa5f483..23b2f3e 100644
--- a/media/capture/video/video_capture_device_unittest.cc
+++ b/media/capture/video/video_capture_device_unittest.cc
@@ -192,7 +192,13 @@
     }
   }
   MOCK_METHOD0(OnCorrectPhotoTaken, void(void));
-  MOCK_METHOD1(OnTakePhotoFailure, void(base::Callback<void(mojom::BlobPtr)>));
+
+  void OnTakePhotoFailure(mojom::ImageCapture::TakePhotoCallback callback) {
+    OnTakePhotoFailureInternal(callback);
+  }
+
+  MOCK_METHOD1(OnTakePhotoFailureInternal,
+               void(mojom::ImageCapture::TakePhotoCallback&));
 
   // GMock doesn't support move-only arguments, so we use this forward method.
   void DoOnGetPhotoState(mojom::PhotoStatePtr state) {
@@ -200,8 +206,13 @@
     OnCorrectGetPhotoState();
   }
   MOCK_METHOD0(OnCorrectGetPhotoState, void(void));
-  MOCK_METHOD1(OnGetPhotoStateFailure,
-               void(base::Callback<void(mojom::PhotoStatePtr)>));
+
+  void OnGetPhotoStateFailure(
+      mojom::ImageCapture::GetPhotoStateCallback callback) {
+    OnGetPhotoStateFailureInternal(callback);
+  }
+  MOCK_METHOD1(OnGetPhotoStateFailureInternal,
+               void(mojom::ImageCapture::GetPhotoStateCallback&));
 
   const mojom::PhotoState* capabilities() { return state_.get(); }
 
@@ -604,8 +615,8 @@
   device->AllocateAndStart(capture_params, std::move(video_capture_client_));
 
   VideoCaptureDevice::TakePhotoCallback scoped_callback(
-      base::Bind(&MockImageCaptureClient::DoOnPhotoTaken,
-                 image_capture_client_),
+      base::BindOnce(&MockImageCaptureClient::DoOnPhotoTaken,
+                     image_capture_client_),
       media::BindToCurrentLoop(base::Bind(
           &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_)));
 
@@ -656,11 +667,11 @@
   device->AllocateAndStart(capture_params, std::move(video_capture_client_));
 
   VideoCaptureDevice::GetPhotoStateCallback scoped_get_callback(
-      base::Bind(&MockImageCaptureClient::DoOnGetPhotoState,
-                 image_capture_client_),
+      base::BindOnce(&MockImageCaptureClient::DoOnGetPhotoState,
+                     image_capture_client_),
       media::BindToCurrentLoop(
-          base::Bind(&MockImageCaptureClient::OnGetPhotoStateFailure,
-                     image_capture_client_)));
+          base::BindOnce(&MockImageCaptureClient::OnGetPhotoStateFailure,
+                         image_capture_client_)));
 
   base::RunLoop run_loop;
   base::Closure quit_closure = media::BindToCurrentLoop(run_loop.QuitClosure());
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc
index 841fc7b..fdfe898c 100644
--- a/media/gpu/video_decode_accelerator_unittest.cc
+++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -1851,9 +1851,7 @@
                 new media::VideoDecodeAcceleratorTestEnvironment()));
 
 #if defined(USE_OZONE)
-    ui::OzonePlatform::InitParams params;
-    params.single_process = true;
-    ui::OzonePlatform::InitializeForUI(params);
+    ui::OzonePlatform::InitializeForUI();
 #endif
 
 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index 8b9f4c4b..2c9186e 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -438,7 +438,8 @@
   scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle);
   if (!dispatcher)
     return MOJO_RESULT_INVALID_ARGUMENT;
-  return watcher->WatchDispatcher(dispatcher, signals, condition, context);
+  return watcher->WatchDispatcher(std::move(dispatcher), signals, condition,
+                                  context);
 }
 
 MojoResult Core::CancelWatch(MojoHandle watcher_handle, uintptr_t context) {
diff --git a/mojo/edk/system/ports/node.cc b/mojo/edk/system/ports/node.cc
index c2edd87..658c9d0e 100644
--- a/mojo/edk/system/ports/node.cc
+++ b/mojo/edk/system/ports/node.cc
@@ -132,8 +132,14 @@
 
   scoped_refptr<Port> port(new Port(kInitialSequenceNum, kInitialSequenceNum));
   int rv = AddPortWithName(port_name, port);
-  if (rv != OK)
+  if (rv != OK) {
+    // TODO(crbug.com/725605): Remove this CHECK. This is testing whether or not
+    // random port name generation is somehow resulting in insufficiently random
+    // and thus colliding names in the wild, which would be one explanation for
+    // some of the weird behavior we're seeing.
+    CHECK(false);
     return rv;
+  }
 
   *port_ref = PortRef(port_name, std::move(port));
   return OK;
diff --git a/mojo/edk/system/watch.cc b/mojo/edk/system/watch.cc
index faeae0ae..b629f90f 100644
--- a/mojo/edk/system/watch.cc
+++ b/mojo/edk/system/watch.cc
@@ -25,6 +25,9 @@
                         bool allowed_to_call_callback) {
   AssertWatcherLockAcquired();
 
+  // TODO(crbug.com/740044): Remove this CHECK.
+  CHECK(this);
+
   // NOTE: This method must NEVER call into |dispatcher_| directly, because it
   // may be called while |dispatcher_| holds a lock.
 
@@ -56,6 +59,9 @@
 }
 
 void Watch::Cancel() {
+  // TODO(crbug.com/740044): Remove this CHECK.
+  CHECK(this);
+
   RequestContext::current()->AddWatchCancelFinalizer(this);
 }
 
diff --git a/mojo/edk/system/watcher_dispatcher.cc b/mojo/edk/system/watcher_dispatcher.cc
index 3b8d156..c3d59fc 100644
--- a/mojo/edk/system/watcher_dispatcher.cc
+++ b/mojo/edk/system/watcher_dispatcher.cc
@@ -25,7 +25,7 @@
   if (it == watched_handles_.end())
     return;
 
-  // Maybe fire a notification to the watch assoicated with this dispatcher,
+  // Maybe fire a notification to the watch associated with this dispatcher,
   // provided we're armed and it cares about the new state.
   if (it->second->NotifyState(state, armed_)) {
     ready_watches_.insert(it->second.get());
@@ -47,6 +47,9 @@
 
     watch = std::move(it->second);
 
+    // TODO(crbug.com/740044): Remove this CHECK.
+    CHECK(watch);
+
     // Wipe out all state associated with the closed dispatcher.
     watches_.erase(watch->context());
     ready_watches_.erase(watch.get());
@@ -119,6 +122,10 @@
   // after we've updated all our own relevant state and released |lock_|.
   {
     base::AutoLock lock(lock_);
+
+    // TODO(crbug.com/740044): Remove this CHECK.
+    CHECK(!closed_);
+
     if (watches_.count(context) || watched_handles_.count(dispatcher.get()))
       return MOJO_RESULT_ALREADY_EXISTS;
 
@@ -156,6 +163,11 @@
     watches_.erase(it);
   }
 
+  // TODO(crbug.com/740044): Remove these CHECKs.
+  CHECK(watch);
+  CHECK(watch->dispatcher());
+  CHECK(this);
+
   // Mark the watch as cancelled so no further notifications get through.
   watch->Cancel();
 
@@ -167,7 +179,12 @@
   {
     base::AutoLock lock(lock_);
     auto handle_it = watched_handles_.find(watch->dispatcher().get());
-    DCHECK(handle_it != watched_handles_.end());
+
+    // If another thread races to close this watcher handler, |watched_handles_|
+    // may have been cleared by the time we reach this section.
+    if (handle_it == watched_handles_.end())
+      return MOJO_RESULT_OK;
+
     ready_watches_.erase(handle_it->second.get());
     watched_handles_.erase(handle_it);
   }
@@ -229,7 +246,7 @@
 }
 
 WatcherDispatcher::~WatcherDispatcher() {
-  // TODO(crbug.com/74044): Remove this.
+  // TODO(crbug.com/740044): Remove this.
   CHECK(closed_);
 }
 
diff --git a/net/websockets/README.md b/net/websockets/README.md
new file mode 100644
index 0000000..6cc512c
--- /dev/null
+++ b/net/websockets/README.md
@@ -0,0 +1,4 @@
+# WebSocket protocol
+
+This directory contains the implementation of
+[the WebSocket protocol](https://tools.ietf.org/html/rfc6455).
diff --git a/remoting/host/it2me/it2me_native_messaging_host_main.cc b/remoting/host/it2me/it2me_native_messaging_host_main.cc
index 8bf9a28..9c66e163 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_main.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_main.cc
@@ -207,7 +207,7 @@
       ChromotingHostContext::Create(new remoting::AutoThreadTaskRunner(
           message_loop.task_runner(), run_loop.QuitClosure()));
   std::unique_ptr<PolicyWatcher> policy_watcher =
-      PolicyWatcher::Create(nullptr, context->file_task_runner());
+      PolicyWatcher::CreateWithTaskRunner(context->file_task_runner());
   std::unique_ptr<extensions::NativeMessageHost> host(
       new It2MeNativeMessagingHost(needs_elevation, std::move(policy_watcher),
                                    std::move(context), std::move(factory)));
diff --git a/remoting/host/policy_watcher.cc b/remoting/host/policy_watcher.cc
index b8078863..08c72bdd 100644
--- a/remoting/host/policy_watcher.cc
+++ b/remoting/host/policy_watcher.cc
@@ -384,17 +384,15 @@
       std::move(policy_provider), std::move(schema_registry)));
 }
 
-std::unique_ptr<PolicyWatcher> PolicyWatcher::Create(
-    policy::PolicyService* policy_service,
-    const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) {
-#if defined(OS_CHROMEOS)
-  // On Chrome OS the PolicyService is owned by the browser.
+std::unique_ptr<PolicyWatcher> PolicyWatcher::CreateWithPolicyService(
+    policy::PolicyService* policy_service) {
   DCHECK(policy_service);
   return base::WrapUnique(new PolicyWatcher(policy_service, nullptr, nullptr,
                                             CreateSchemaRegistry()));
-#else  // !defined(OS_CHROMEOS)
-  DCHECK(!policy_service);
+}
 
+std::unique_ptr<PolicyWatcher> PolicyWatcher::CreateWithTaskRunner(
+    const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) {
   // Create platform-specific PolicyLoader. Always read the Chrome policies
   // (even on Chromium) so that policy enforcement can't be bypassed by running
   // Chromium.
@@ -422,12 +420,14 @@
   return base::WrapUnique(new PolicyWatcher(
       owned_policy_service.get(), std::move(owned_policy_service), nullptr,
       CreateSchemaRegistry()));
+#elif defined(OS_CHROMEOS)
+  NOTREACHED() << "CreateWithPolicyService() should be used on ChromeOS.";
+  return nullptr;
 #else
 #error OS that is not yet supported by PolicyWatcher code.
 #endif
 
   return PolicyWatcher::CreateFromPolicyLoader(std::move(policy_loader));
-#endif  // !(OS_CHROMEOS)
 }
 
 std::unique_ptr<PolicyWatcher> PolicyWatcher::CreateFromPolicyLoaderForTesting(
diff --git a/remoting/host/policy_watcher.h b/remoting/host/policy_watcher.h
index 076cd45..9a6b98f 100644
--- a/remoting/host/policy_watcher.h
+++ b/remoting/host/policy_watcher.h
@@ -66,22 +66,21 @@
   static std::unique_ptr<base::DictionaryValue> GetDefaultPolicies();
 
   // Specify a |policy_service| to borrow (on Chrome OS, from the browser
-  // process) or specify nullptr to internally construct and use a new
-  // PolicyService (on other OS-es). PolicyWatcher must be used on the thread on
-  // which it is created. |policy_service| is called on the same thread.
+  // process). PolicyWatcher must be used on the thread on which it is created.
+  // |policy_service| is called on the same thread.
   //
-  // When |policy_service| is null, then |file_task_runner| is used for reading
-  // the policy from files / registry / preferences (which are blocking
-  // operations). |file_task_runner| should be of TYPE_IO type.
+  // When |policy_service| is specified then BrowserThread::UI is used for
+  // PolicyUpdatedCallback and PolicyErrorCallback.
+  static std::unique_ptr<PolicyWatcher> CreateWithPolicyService(
+      policy::PolicyService* policy_service);
+
+  // Construct and a new PolicyService for non-ChromeOS platforms.
+  // PolicyWatcher must be used on the thread on which it is created.
   //
-  // When |policy_service| is specified then |file_task_runner| argument is
-  // ignored and 1) BrowserThread::UI is used for PolicyUpdatedCallback and
-  // PolicyErrorCallback and 2) BrowserThread::FILE is used for reading the
-  // policy from files / registry / preferences (although (2) is just an
-  // implementation detail and should likely be ignored outside of
-  // PolicyWatcher).
-  static std::unique_ptr<PolicyWatcher> Create(
-      policy::PolicyService* policy_service,
+  // |file_task_runner| is used for reading the policy from files / registry /
+  // preferences (which are blocking operations). |file_task_runner| should be
+  // of TYPE_IO type.
+  static std::unique_ptr<PolicyWatcher> CreateWithTaskRunner(
       const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner);
 
   // Creates a PolicyWatcher from the given loader instead of loading the policy
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index 944a92b..fe1d971 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -811,7 +811,7 @@
   }
 
   policy_watcher_ =
-      PolicyWatcher::Create(nullptr, context_->file_task_runner());
+      PolicyWatcher::CreateWithTaskRunner(context_->file_task_runner());
   policy_watcher_->StartWatching(
       base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this)),
       base::Bind(&HostProcess::OnPolicyError, base::Unretained(this)));
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc
index 761a292..cf2900a 100644
--- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc
@@ -88,10 +88,11 @@
     case __NR_getdents64:
     case __NR_getpriority:
     case __NR_ioctl:
-#if defined(__i386__)
-    // While mincore is on multiple arches, it is only used on Android by x86.
-    case __NR_mincore:  // https://crbug.com/701137
-#endif
+    // TODO(https://crbug.com/739879): Mincore should only be allowed in the
+    // baseline policy for x86 (https://crbug.com/701137), but currently this
+    // policy is used directly by //content, and mincore needs to be allowed per
+    // https://crbug.com/741984.
+    case __NR_mincore:
     case __NR_mremap:
 #if defined(__i386__)
     // Used on pre-N to initialize threads in ART.
diff --git a/services/BUILD.gn b/services/BUILD.gn
index 37a9a0d..ff35c71 100644
--- a/services/BUILD.gn
+++ b/services/BUILD.gn
@@ -137,7 +137,11 @@
 
   android_library("service_javatests") {
     testonly = true
-    java_files = [ "shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java" ]
+    java_files = [
+      "shape_detection/android/javatests/src/org/chromium/shape_detection/BarcodeDetectionImplTest.java",
+      "shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java",
+      "shape_detection/android/javatests/src/org/chromium/shape_detection/TestUtils.java",
+    ]
     deps = [
       "$google_play_services_package:google_play_services_base_java",
       "$google_play_services_package:google_play_services_basement_java",
diff --git a/services/shape_detection/android/javatests/src/org/chromium/shape_detection/BarcodeDetectionImplTest.java b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/BarcodeDetectionImplTest.java
new file mode 100644
index 0000000..9f25452
--- /dev/null
+++ b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/BarcodeDetectionImplTest.java
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.shape_detection;
+
+import android.support.test.filters.SmallTest;
+import android.test.InstrumentationTestCase;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.shape_detection.mojom.BarcodeDetection;
+import org.chromium.shape_detection.mojom.BarcodeDetectionResult;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test suite for BarcodeDetectionImpl.
+ */
+public class BarcodeDetectionImplTest extends InstrumentationTestCase {
+    public static final org.chromium.skia.mojom.Bitmap QR_CODE_BITMAP =
+            TestUtils.mojoBitmapFromFile("qr_code.png");
+
+    public BarcodeDetectionImplTest() {}
+
+    private static BarcodeDetectionResult[] detect(org.chromium.skia.mojom.Bitmap mojoBitmap) {
+        BarcodeDetection detector = new BarcodeDetectionImpl();
+
+        final ArrayBlockingQueue<BarcodeDetectionResult[]> queue = new ArrayBlockingQueue<>(1);
+        detector.detect(mojoBitmap, new BarcodeDetection.DetectResponse() {
+            public void call(BarcodeDetectionResult[] results) {
+                queue.add(results);
+            }
+        });
+        BarcodeDetectionResult[] toReturn = null;
+        try {
+            toReturn = queue.poll(5L, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            fail("Could not get BarcodeDetectionResult: " + e.toString());
+        }
+        assertNotNull(toReturn);
+        return toReturn;
+    }
+
+    @SmallTest
+    @Feature({"ShapeDetection"})
+    public void testDetectBase64ValidImageString() {
+        if (!TestUtils.IS_GMS_CORE_SUPPORTED) {
+            return;
+        }
+        BarcodeDetectionResult[] results = detect(QR_CODE_BITMAP);
+        assertEquals(1, results.length);
+        assertEquals("https://chromium.org", results[0].rawValue);
+        assertEquals(40.0, results[0].boundingBox.x, 0.0);
+        assertEquals(40.0, results[0].boundingBox.y, 0.0);
+        assertEquals(250.0, results[0].boundingBox.width, 0.0);
+        assertEquals(250.0, results[0].boundingBox.height, 0.0);
+    }
+}
diff --git a/services/shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java
index 1d68929..d3bd2959 100644
--- a/services/shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java
+++ b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java
@@ -5,23 +5,15 @@
 package org.chromium.shape_detection;
 
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.support.test.filters.SmallTest;
 import android.test.InstrumentationTestCase;
 
-import com.google.android.gms.common.ConnectionResult;
-import com.google.android.gms.common.GoogleApiAvailability;
-
-import org.chromium.base.ContextUtils;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.UrlUtils;
 import org.chromium.shape_detection.mojom.FaceDetection;
 import org.chromium.shape_detection.mojom.FaceDetectionResult;
 import org.chromium.shape_detection.mojom.FaceDetectorOptions;
-import org.chromium.skia.mojom.ColorType;
 
-import java.nio.ByteBuffer;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
@@ -30,40 +22,15 @@
  */
 public class FaceDetectionImplTest extends InstrumentationTestCase {
     public static final org.chromium.skia.mojom.Bitmap MONA_LISA_BITMAP =
-            mojoBitmapFromFile("mona_lisa.jpg");
+            TestUtils.mojoBitmapFromFile("mona_lisa.jpg");
     // Different versions of Android have different implementations of FaceDetector.findFaces(), so
     // we have to use a large error threshold.
     public static final double BOUNDING_BOX_POSITION_ERROR = 10.0;
     public static final double BOUNDING_BOX_SIZE_ERROR = 5.0;
     public static enum DetectionProviderType { ANDROID, GMS_CORE }
-    public static final boolean IS_GMS_CORE_SUPPORTED = isGmsCoreSupported();
 
     public FaceDetectionImplTest() {}
 
-    private static boolean isGmsCoreSupported() {
-        return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
-                       ContextUtils.getApplicationContext())
-                == ConnectionResult.SUCCESS;
-    }
-
-    private static org.chromium.skia.mojom.Bitmap mojoBitmapFromBitmap(Bitmap bitmap) {
-        ByteBuffer buffer = ByteBuffer.allocate(bitmap.getByteCount());
-        bitmap.copyPixelsToBuffer(buffer);
-
-        org.chromium.skia.mojom.Bitmap mojoBitmap = new org.chromium.skia.mojom.Bitmap();
-        mojoBitmap.width = bitmap.getWidth();
-        mojoBitmap.height = bitmap.getHeight();
-        mojoBitmap.pixelData = buffer.array();
-        mojoBitmap.colorType = ColorType.RGBA_8888;
-        return mojoBitmap;
-    }
-
-    private static org.chromium.skia.mojom.Bitmap mojoBitmapFromFile(String relPath) {
-        String path = UrlUtils.getIsolatedTestFilePath("services/test/data/" + relPath);
-        Bitmap bitmap = BitmapFactory.decodeFile(path);
-        return mojoBitmapFromBitmap(bitmap);
-    }
-
     private static FaceDetectionResult[] detect(
             org.chromium.skia.mojom.Bitmap mojoBitmap, DetectionProviderType api) {
         FaceDetectorOptions options = new FaceDetectorOptions();
@@ -113,7 +80,7 @@
     @SmallTest
     @Feature({"ShapeDetection"})
     public void testDetectValidImageWithGmsCore() {
-        if (IS_GMS_CORE_SUPPORTED) {
+        if (TestUtils.IS_GMS_CORE_SUPPORTED) {
             detectSucceedsOnValidImage(DetectionProviderType.GMS_CORE);
         }
     }
@@ -126,7 +93,7 @@
                 MONA_LISA_BITMAP.height, Bitmap.Config.ARGB_8888);
         Canvas canvas = new Canvas(paddedBitmap);
         canvas.drawBitmap(BitmapUtils.convertToBitmap(MONA_LISA_BITMAP), 0, 0, null);
-        org.chromium.skia.mojom.Bitmap mojoBitmap = mojoBitmapFromBitmap(paddedBitmap);
+        org.chromium.skia.mojom.Bitmap mojoBitmap = TestUtils.mojoBitmapFromBitmap(paddedBitmap);
         assertEquals(1, mojoBitmap.width % 2);
 
         FaceDetectionResult[] results = detect(mojoBitmap, DetectionProviderType.ANDROID);
diff --git a/services/shape_detection/android/javatests/src/org/chromium/shape_detection/TestUtils.java b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/TestUtils.java
new file mode 100644
index 0000000..26410e62
--- /dev/null
+++ b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/TestUtils.java
@@ -0,0 +1,50 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.shape_detection;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.GoogleApiAvailability;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.base.test.util.UrlUtils;
+import org.chromium.skia.mojom.ColorType;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Utility class for ShapeDetection instrumentation tests,
+ * provides support for e.g. reading files and converting
+ * Bitmaps to mojom.Bitmaps.
+ */
+public class TestUtils {
+    public static final boolean IS_GMS_CORE_SUPPORTED = isGmsCoreSupported();
+
+    private static boolean isGmsCoreSupported() {
+        return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
+                       ContextUtils.getApplicationContext())
+                == ConnectionResult.SUCCESS;
+    }
+
+    public static org.chromium.skia.mojom.Bitmap mojoBitmapFromBitmap(Bitmap bitmap) {
+        ByteBuffer buffer = ByteBuffer.allocate(bitmap.getByteCount());
+        bitmap.copyPixelsToBuffer(buffer);
+
+        org.chromium.skia.mojom.Bitmap mojoBitmap = new org.chromium.skia.mojom.Bitmap();
+        mojoBitmap.width = bitmap.getWidth();
+        mojoBitmap.height = bitmap.getHeight();
+        mojoBitmap.pixelData = buffer.array();
+        mojoBitmap.colorType = ColorType.RGBA_8888;
+        return mojoBitmap;
+    }
+
+    public static org.chromium.skia.mojom.Bitmap mojoBitmapFromFile(String relPath) {
+        String path = UrlUtils.getIsolatedTestFilePath("services/test/data/" + relPath);
+        Bitmap bitmap = BitmapFactory.decodeFile(path);
+        return mojoBitmapFromBitmap(bitmap);
+    }
+}
diff --git a/services/test/data/qr_code.png b/services/test/data/qr_code.png
new file mode 100644
index 0000000..9d2a4fa
--- /dev/null
+++ b/services/test/data/qr_code.png
Binary files differ
diff --git a/services/video_capture/device_factory_media_to_mojo_adapter.cc b/services/video_capture/device_factory_media_to_mojo_adapter.cc
index 53c47520..d39f035 100644
--- a/services/video_capture/device_factory_media_to_mojo_adapter.cc
+++ b/services/video_capture/device_factory_media_to_mojo_adapter.cc
@@ -28,7 +28,7 @@
 // happen in VideoCaptureDeviceClient, and talk only to VideoCaptureDeviceClient
 // instead of VideoCaptureSystem.
 static void TranslateDeviceInfos(
-    const video_capture::mojom::DeviceFactory::GetDeviceInfosCallback& callback,
+    video_capture::mojom::DeviceFactory::GetDeviceInfosCallback callback,
     const std::vector<media::VideoCaptureDeviceInfo>& device_infos) {
   std::vector<media::VideoCaptureDeviceInfo> translated_device_infos;
   for (const auto& device_info : device_infos) {
@@ -52,13 +52,13 @@
       continue;
     translated_device_infos.push_back(translated_device_info);
   }
-  callback.Run(translated_device_infos);
+  std::move(callback).Run(translated_device_infos);
 }
 
 static void DiscardDeviceInfosAndCallContinuation(
-    base::Closure continuation,
+    base::OnceClosure continuation,
     const std::vector<media::VideoCaptureDeviceInfo>&) {
-  continuation.Run();
+  std::move(continuation).Run();
 }
 
 }  // anonymous namespace
@@ -92,16 +92,16 @@
 DeviceFactoryMediaToMojoAdapter::~DeviceFactoryMediaToMojoAdapter() = default;
 
 void DeviceFactoryMediaToMojoAdapter::GetDeviceInfos(
-    const GetDeviceInfosCallback& callback) {
+    GetDeviceInfosCallback callback) {
   capture_system_->GetDeviceInfosAsync(
-      base::Bind(&TranslateDeviceInfos, callback));
+      base::Bind(&TranslateDeviceInfos, base::Passed(&callback)));
   has_called_get_device_infos_ = true;
 }
 
 void DeviceFactoryMediaToMojoAdapter::CreateDevice(
     const std::string& device_id,
     mojom::DeviceRequest device_request,
-    const CreateDeviceCallback& callback) {
+    CreateDeviceCallback callback) {
   auto active_device_iter = active_devices_by_id_.find(device_id);
   if (active_device_iter != active_devices_by_id_.end()) {
     // The requested device is already in use.
@@ -113,32 +113,34 @@
     device_entry.binding->set_connection_error_handler(base::Bind(
         &DeviceFactoryMediaToMojoAdapter::OnClientConnectionErrorOrClose,
         base::Unretained(this), device_id));
-    callback.Run(mojom::DeviceAccessResultCode::SUCCESS);
+    std::move(callback).Run(mojom::DeviceAccessResultCode::SUCCESS);
     return;
   }
 
-  const auto create_and_add_new_device_cb =
-      base::Bind(&DeviceFactoryMediaToMojoAdapter::CreateAndAddNewDevice,
-                 weak_factory_.GetWeakPtr(), device_id,
-                 base::Passed(&device_request), callback);
+  auto create_and_add_new_device_cb =
+      base::BindOnce(&DeviceFactoryMediaToMojoAdapter::CreateAndAddNewDevice,
+                     weak_factory_.GetWeakPtr(), device_id,
+                     std::move(device_request), std::move(callback));
 
   if (has_called_get_device_infos_) {
-    create_and_add_new_device_cb.Run();
+    std::move(create_and_add_new_device_cb).Run();
     return;
   }
 
-  capture_system_->GetDeviceInfosAsync(base::Bind(
-      &DiscardDeviceInfosAndCallContinuation, create_and_add_new_device_cb));
+  capture_system_->GetDeviceInfosAsync(
+      base::Bind(&DiscardDeviceInfosAndCallContinuation,
+                 base::Passed(&create_and_add_new_device_cb)));
 }
 
 void DeviceFactoryMediaToMojoAdapter::CreateAndAddNewDevice(
     const std::string& device_id,
     mojom::DeviceRequest device_request,
-    const CreateDeviceCallback& callback) {
+    CreateDeviceCallback callback) {
   std::unique_ptr<media::VideoCaptureDevice> media_device =
       capture_system_->CreateDevice(device_id);
   if (media_device == nullptr) {
-    callback.Run(mojom::DeviceAccessResultCode::ERROR_DEVICE_NOT_FOUND);
+    std::move(callback).Run(
+        mojom::DeviceAccessResultCode::ERROR_DEVICE_NOT_FOUND);
     return;
   }
 
@@ -154,7 +156,7 @@
       base::Unretained(this), device_id));
   active_devices_by_id_[device_id] = std::move(device_entry);
 
-  callback.Run(mojom::DeviceAccessResultCode::SUCCESS);
+  std::move(callback).Run(mojom::DeviceAccessResultCode::SUCCESS);
 }
 
 void DeviceFactoryMediaToMojoAdapter::OnClientConnectionErrorOrClose(
diff --git a/services/video_capture/device_factory_media_to_mojo_adapter.h b/services/video_capture/device_factory_media_to_mojo_adapter.h
index e3ae55e..a62b8e3 100644
--- a/services/video_capture/device_factory_media_to_mojo_adapter.h
+++ b/services/video_capture/device_factory_media_to_mojo_adapter.h
@@ -31,10 +31,10 @@
   ~DeviceFactoryMediaToMojoAdapter() override;
 
   // mojom::DeviceFactory implementation.
-  void GetDeviceInfos(const GetDeviceInfosCallback& callback) override;
+  void GetDeviceInfos(GetDeviceInfosCallback callback) override;
   void CreateDevice(const std::string& device_id,
                     mojom::DeviceRequest device_request,
-                    const CreateDeviceCallback& callback) override;
+                    CreateDeviceCallback callback) override;
 
  private:
   struct ActiveDeviceEntry {
@@ -52,7 +52,7 @@
 
   void CreateAndAddNewDevice(const std::string& device_id,
                              mojom::DeviceRequest device_request,
-                             const CreateDeviceCallback& callback);
+                             CreateDeviceCallback callback);
   void OnClientConnectionErrorOrClose(const std::string& device_id);
 
   const std::unique_ptr<service_manager::ServiceContextRef> service_ref_;
diff --git a/services/video_capture/device_media_to_mojo_adapter.cc b/services/video_capture/device_media_to_mojo_adapter.cc
index 25d6d1f..fdacea4 100644
--- a/services/video_capture/device_media_to_mojo_adapter.cc
+++ b/services/video_capture/device_media_to_mojo_adapter.cc
@@ -20,17 +20,17 @@
 static const int kMaxBufferCount = 3;
 
 void RunFailedGetPhotoStateCallback(
-    base::Callback<void(media::mojom::PhotoStatePtr)> cb) {
-  cb.Run(nullptr);
+    base::OnceCallback<void(media::mojom::PhotoStatePtr)> cb) {
+  std::move(cb).Run(nullptr);
 }
 
-void RunFailedSetOptionsCallback(base::Callback<void(bool)> cb) {
-  cb.Run(false);
+void RunFailedSetOptionsCallback(base::OnceCallback<void(bool)> cb) {
+  std::move(cb).Run(false);
 }
 
 void RunFailedTakePhotoCallback(
-    base::Callback<void(media::mojom::BlobPtr blob)> cb) {
-  cb.Run(nullptr);
+    base::OnceCallback<void(media::mojom::BlobPtr blob)> cb) {
+  std::move(cb).Run(nullptr);
 }
 
 }  // anonymous namespace
@@ -112,29 +112,29 @@
   device_->Resume();
 }
 
-void DeviceMediaToMojoAdapter::GetPhotoState(
-    const GetPhotoStateCallback& callback) {
+void DeviceMediaToMojoAdapter::GetPhotoState(GetPhotoStateCallback callback) {
   media::VideoCaptureDevice::GetPhotoStateCallback scoped_callback(
-      media::BindToCurrentLoop(callback),
-      media::BindToCurrentLoop(base::Bind(&RunFailedGetPhotoStateCallback)));
+      media::BindToCurrentLoop(std::move(callback)),
+      media::BindToCurrentLoop(
+          base::BindOnce(&RunFailedGetPhotoStateCallback)));
   device_->GetPhotoState(std::move(scoped_callback));
 }
 
 void DeviceMediaToMojoAdapter::SetPhotoOptions(
     media::mojom::PhotoSettingsPtr settings,
-    const SetPhotoOptionsCallback& callback) {
+    SetPhotoOptionsCallback callback) {
   media::ScopedResultCallback<media::mojom::ImageCapture::SetOptionsCallback>
-      scoped_callback(
-          media::BindToCurrentLoop(std::move(callback)),
-          media::BindToCurrentLoop(base::Bind(&RunFailedSetOptionsCallback)));
+      scoped_callback(media::BindToCurrentLoop(std::move(callback)),
+                      media::BindToCurrentLoop(
+                          base::BindOnce(&RunFailedSetOptionsCallback)));
   device_->SetPhotoOptions(std::move(settings), std::move(scoped_callback));
 }
 
-void DeviceMediaToMojoAdapter::TakePhoto(const TakePhotoCallback& callback) {
+void DeviceMediaToMojoAdapter::TakePhoto(TakePhotoCallback callback) {
   media::ScopedResultCallback<media::mojom::ImageCapture::TakePhotoCallback>
-      scoped_callback(
-          media::BindToCurrentLoop(callback),
-          media::BindToCurrentLoop(base::Bind(&RunFailedTakePhotoCallback)));
+      scoped_callback(media::BindToCurrentLoop(std::move(callback)),
+                      media::BindToCurrentLoop(
+                          base::BindOnce(&RunFailedTakePhotoCallback)));
   device_->TakePhoto(std::move(scoped_callback));
 }
 
diff --git a/services/video_capture/device_media_to_mojo_adapter.h b/services/video_capture/device_media_to_mojo_adapter.h
index 3c61520..18e97fcf 100644
--- a/services/video_capture/device_media_to_mojo_adapter.h
+++ b/services/video_capture/device_media_to_mojo_adapter.h
@@ -35,10 +35,10 @@
   void RequestRefreshFrame() override;
   void MaybeSuspend() override;
   void Resume() override;
-  void GetPhotoState(const GetPhotoStateCallback& callback) override;
+  void GetPhotoState(GetPhotoStateCallback callback) override;
   void SetPhotoOptions(media::mojom::PhotoSettingsPtr settings,
-                       const SetPhotoOptionsCallback& callback) override;
-  void TakePhoto(const TakePhotoCallback& callback) override;
+                       SetPhotoOptionsCallback callback) override;
+  void TakePhoto(TakePhotoCallback callback) override;
 
   void Stop();
   void OnClientConnectionErrorOrClose();
diff --git a/services/video_capture/public/interfaces/BUILD.gn b/services/video_capture/public/interfaces/BUILD.gn
index 03e7459d..9228f30 100644
--- a/services/video_capture/public/interfaces/BUILD.gn
+++ b/services/video_capture/public/interfaces/BUILD.gn
@@ -19,9 +19,6 @@
     "//media/mojo/interfaces",
     "//ui/gfx/geometry/mojo",
   ]
-
-  # TODO(crbug.com/714018): Convert the implementation to use OnceCallback.
-  use_once_callback = false
 }
 
 mojom("constants") {
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index f0165667..a3ca099 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -195,6 +195,10 @@
 #define SK_SUPPORT_LEGACY_HQ_SCALER
 #endif
 
+#ifndef SK_SUPPORT_LEGACY_BILERP
+#define SK_SUPPORT_LEGACY_BILERP
+#endif
+
 // Workaround for poor anisotropic mipmap quality,
 // pending Skia ripmap support.
 // (https://bugs.chromium.org/p/skia/issues/detail?id=4863)
@@ -224,6 +228,10 @@
 #define SK_SUPPORT_NONSTD_BLENDMODES
 #endif
 
+#ifndef SK_SUPPORT_LEGACY_COLORTABLE
+#define SK_SUPPORT_LEGACY_COLORTABLE
+#endif
+
 ///////////////////////// Imported from BUILD.gn and skia_common.gypi
 
 /* In some places Skia can use static initializers for global initialization,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 6580512c..1d02c49 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -10011,10 +10011,6 @@
     "additional_compile_targets": [
       "d8",
       "gl_unittests",
-      "mojo_common_unittests",
-      "mojo_public_bindings_unittests",
-      "mojo_public_system_unittests",
-      "mojo_system_unittests",
       "net_unittests",
       "skia_unittests",
       "ui_base_unittests"
@@ -10037,6 +10033,42 @@
           "can_use_on_swarming_builders": false
         },
         "test": "ipc_tests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_common_unittests"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_js_unittests.filter"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_js_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_public_bindings_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_public_system_unittests"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_system_unittests.filter"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_system_unittests"
       }
     ]
   },
@@ -10044,10 +10076,6 @@
     "additional_compile_targets": [
       "d8",
       "gl_unittests",
-      "mojo_common_unittests",
-      "mojo_public_bindings_unittests",
-      "mojo_public_system_unittests",
-      "mojo_system_unittests",
       "net_unittests",
       "skia_unittests",
       "ui_base_unittests"
@@ -10070,6 +10098,42 @@
           "can_use_on_swarming_builders": false
         },
         "test": "ipc_tests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_common_unittests"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_js_unittests.filter"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_js_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_public_bindings_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_public_system_unittests"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_system_unittests.filter"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "mojo_system_unittests"
       }
     ]
   },
diff --git a/testing/buildbot/filters/fuchsia.mojo_js_unittests.filter b/testing/buildbot/filters/fuchsia.mojo_js_unittests.filter
new file mode 100644
index 0000000..57c9ce6
--- /dev/null
+++ b/testing/buildbot/filters/fuchsia.mojo_js_unittests.filter
@@ -0,0 +1,3 @@
+# TODO(fuchsia): Fix the test and delete this file. crbug.com/740791
+
+-JSTest.Core
diff --git a/testing/buildbot/filters/fuchsia.mojo_system_unittests.filter b/testing/buildbot/filters/fuchsia.mojo_system_unittests.filter
new file mode 100644
index 0000000..6ffd4b7a7
--- /dev/null
+++ b/testing/buildbot/filters/fuchsia.mojo_system_unittests.filter
@@ -0,0 +1,13 @@
+# TODO(fuchsia): Fix the tests and delete this file. crbug.com/740791
+
+-*MultiprocessMessagePipeTest*
+-DataPipeTest*
+-MessagePipeTest.SharedBufferHandlePingPong
+-PlatformWrapperTest.Wrap*
+-PlatformSharedBufferTest.TooBig
+-PlatformChannelPairPosixTest*
+-SharedBufferTest*
+-SignalsTest.*
+-SharedBufferTest.PassSharedBufferLocal
+-EmbedderTest.*
+-MessageTest.Serialize*
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 6bea4f56..38750e5 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1626,6 +1626,25 @@
             ]
         }
     ],
+    "NTPCaptureThumbnail": [
+        {
+            "platforms": [
+                "chromeos",
+                "linux",
+                "mac",
+                "win"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "CaptureThumbnailDependingOnTransitionType",
+                        "CaptureThumbnailOnNavigatingAway"
+                    ]
+                }
+            ]
+        }
+    ],
     "NTPFaviconsFromNewServer": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index a72431f..dfc049c 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -13717,7 +13717,7 @@
 crbug.com/591099 inspector/console-document-write-from-external-script-logging.html [ Failure ]
 crbug.com/591099 inspector/console/alert-toString-exception.html [ Crash Failure ]
 crbug.com/591099 inspector/console/command-line-api-getEventListeners.html [ Crash Failure ]
-crbug.com/591099 http/tests/inspector/devtools-js/console/command-line-api.js [ Crash Failure ]
+crbug.com/591099 http/tests/devtools/console/command-line-api.js [ Crash Failure ]
 crbug.com/591099 inspector/console/console-Object-overwritten.html [ Failure ]
 crbug.com/591099 inspector/console/console-api-on-call-frame.html [ Crash Failure ]
 crbug.com/591099 inspector/console/console-assert.html [ Failure ]
@@ -13725,7 +13725,7 @@
 crbug.com/591099 inspector/console/console-bind-fake.html [ Failure ]
 crbug.com/591099 inspector/console/console-call-getter-on-proto.html [ Failure ]
 crbug.com/591099 inspector/console/console-clear-function.html [ Failure ]
-crbug.com/591099 http/tests/inspector/devtools-js/console/console-clear.js [ Failure ]
+crbug.com/591099 http/tests/devtools/console/console-clear.js [ Failure ]
 crbug.com/591099 inspector/console/console-command-clear.html [ Failure ]
 crbug.com/591099 inspector/console/console-command-copy.html [ Failure ]
 crbug.com/591099 inspector/console/console-context-selector.html [ Crash Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 0f316d7..f545de4 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2768,13 +2768,13 @@
 # Timeouts
 crbug.com/709227 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-idb.any.worker.html [ Timeout ]
 crbug.com/709227 external/wpt/websockets/binary/001.html?wss [ Timeout ]
-crbug.com/709227 external/wpt/websockets/binary/002.html?wss [ Timeout ]
-crbug.com/709227 external/wpt/websockets/binary/004.html?wss [ Timeout ]
+crbug.com/709227 external/wpt/websockets/binary/002.html?wss [ Failure Timeout ]
+crbug.com/709227 external/wpt/websockets/binary/004.html?wss [ Failure Timeout ]
 crbug.com/709227 external/wpt/websockets/binary/005.html?wss [ Timeout ]
-crbug.com/709227 external/wpt/websockets/extended-payload-length.html?wss [ Timeout ]
+crbug.com/709227 external/wpt/websockets/extended-payload-length.html?wss [ Failure Timeout ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-arraybuffer.html?wss [ Timeout ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-blob.html?wss [ Timeout ]
-crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-large.html?wss [ Timeout ]
+crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-large.html?wss [ Failure Timeout ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-unicode.html?wss [ Timeout ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/events/018.html?wss [ Timeout ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/005.html?wss [ Timeout ]
@@ -3098,3 +3098,5 @@
 # Sheriff failures 2017-07-03
 crbug.com/708994 http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ]
 crbug.com/708994 virtual/mojo-loading/http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ]
+
+crbug.com/626703 [ Win7 ] external/wpt/html/semantics/tabular-data/processing-model-1/span-limits.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/animations/responsive/zoom-responsive-transform-animation-expected.html b/third_party/WebKit/LayoutTests/animations/responsive/zoom-responsive-transform-animation-expected.html
index d35fdf3..b1781e3 100644
--- a/third_party/WebKit/LayoutTests/animations/responsive/zoom-responsive-transform-animation-expected.html
+++ b/third_party/WebKit/LayoutTests/animations/responsive/zoom-responsive-transform-animation-expected.html
@@ -53,7 +53,7 @@
   testRunner.waitUntilDone();
 
 function waitForCompositor() {
-  return footer.animate({opacity: ['1', '1']}, 1).ready;
+  return footer.animate({opacity: ['1', '1']}, 1).finished;
 }
 
 requestAnimationFrame(() => {
diff --git a/third_party/WebKit/LayoutTests/animations/responsive/zoom-responsive-transform-animation.html b/third_party/WebKit/LayoutTests/animations/responsive/zoom-responsive-transform-animation.html
index dda23df..d2581da 100644
--- a/third_party/WebKit/LayoutTests/animations/responsive/zoom-responsive-transform-animation.html
+++ b/third_party/WebKit/LayoutTests/animations/responsive/zoom-responsive-transform-animation.html
@@ -50,16 +50,18 @@
   testRunner.waitUntilDone();
 
 function waitForCompositor() {
-  return footer.animate({opacity: ['1', '1']}, 1).ready;
+  return footer.animate({opacity: ['1', '1']}, 1).finished;
 }
 
 requestAnimationFrame(() => {
   requestAnimationFrame(() => {
     internals.setZoomFactor(2);
     requestAnimationFrame(() => {
-      waitForCompositor().then(() => {
-        if (window.testRunner)
-          testRunner.notifyDone();
+      requestAnimationFrame(() => {
+        waitForCompositor().then(() => {
+          if (window.testRunner)
+            testRunner.notifyDone();
+        });
       });
     });
   });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/overridemimetype-blob-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/overridemimetype-blob-expected.txt
deleted file mode 100644
index 1b0fd78..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/overridemimetype-blob-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Use text/xml as fallback MIME type assert_equals: expected "text/xml" but got ""
-PASS Use text/xml as fallback MIME type, 2 
-FAIL Bogus MIME type should end up as application/octet-stream assert_equals: expected "application/octet-stream" but got ""
-FAIL Bogus MIME type should end up as application/octet-stream, 2 assert_equals: expected "application/octet-stream" but got ""
-FAIL Valid MIME types need to be normalized assert_equals: expected "hi/x" but got ""
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/overridemimetype-blob.html b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/overridemimetype-blob.html
index 4094480..83378a8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/overridemimetype-blob.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/overridemimetype-blob.html
@@ -59,7 +59,7 @@
   })
   client.open("GET", "resources/status.py")
   client.responseType = "blob"
-  client.overrideMimeType("HI/x;test")
+  client.overrideMimeType("HI/x;test=test")
   client.send()
 }, "Valid MIME types need to be normalized")
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/files/script-tests/xhr-response-blob.js b/third_party/WebKit/LayoutTests/fast/files/script-tests/xhr-response-blob.js
index 7759e39e2..87e5585 100644
--- a/third_party/WebKit/LayoutTests/fast/files/script-tests/xhr-response-blob.js
+++ b/third_party/WebKit/LayoutTests/fast/files/script-tests/xhr-response-blob.js
@@ -15,6 +15,7 @@
             return;
         }
         shouldBeTrue("xhr.response instanceof Blob");
+        // This is checking a value determined by MIME sniffing
         shouldBeEqualToString("xhr.response.type", blobType);
         doneFunction();
     }
@@ -22,7 +23,7 @@
 
 testBlob("resources/UTF8.txt", "text/plain", function() {
     testBlob("resources/does_not_exist.txt", "", function() {
-        testBlob("resources/empty-file", "", function() {
+        testBlob("resources/empty-file", "text/plain", function() {
             if (window.testRunner)
                 testRunner.notifyDone();
         })
diff --git a/third_party/WebKit/LayoutTests/fast/files/xhr-response-blob-expected.txt b/third_party/WebKit/LayoutTests/fast/files/xhr-response-blob-expected.txt
index 99fa487..9e8f8fc 100644
--- a/third_party/WebKit/LayoutTests/fast/files/xhr-response-blob-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/files/xhr-response-blob-expected.txt
@@ -17,5 +17,5 @@
 PASS xhr.responseType is "blob"
 PASS xhr.response is null
 PASS xhr.response instanceof Blob is true
-PASS xhr.response.type is ""
+PASS xhr.response.type is "text/plain"
 
diff --git a/third_party/WebKit/LayoutTests/fast/sub-pixel/sub-pixel-border.html b/third_party/WebKit/LayoutTests/fast/sub-pixel/sub-pixel-border.html
index 874ca2b..568d97f 100644
--- a/third_party/WebKit/LayoutTests/fast/sub-pixel/sub-pixel-border.html
+++ b/third_party/WebKit/LayoutTests/fast/sub-pixel/sub-pixel-border.html
@@ -82,13 +82,13 @@
 
       test(function() {
         assert_equals(borderAsString(testElements['0.25px']),
-            '0.25px 0.25px 0.25px 0.25px',
+            '1px 1px 1px 1px',
             'Border thickness of 0.25px box should be 0.25px.');
         assert_equals(borderAsString(testElements['0.5px']),
-            '0.5px 0.5px 0.5px 0.5px',
+            '1px 1px 1px 1px',
             'Border thickness of 0.5px box should be 0.5px.');
         assert_equals(borderAsString(testElements['0.75px']),
-            '0.75px 0.75px 0.75px 0.75px',
+            '1px 1px 1px 1px',
             'Border thickness of 0.75px box should be 0.75px.');
         assert_equals(borderAsString(testElements['1.25px']),
             '1.25px 1.25px 1.25px 1.25px',
diff --git a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-no-file-access-expected.txt b/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-no-file-access-expected.txt
index d6a2f93..2a04bac 100644
--- a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-no-file-access-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-no-file-access-expected.txt
@@ -1,4 +1,4 @@
 CONSOLE WARNING: line 22: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 23: XMLHttpRequest cannot load xmlhttprequest-no-file-access-expected.txt. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 23: Failed to load xmlhttprequest-no-file-access-expected.txt: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
 
 The child iframe cannot paste its textual results into this iframe because it is considered a different domain - that's the point of this test! Therefore, success is denoted by the child iframe calling notifyDone. The test will hang if something goes amiss with the access control checks.
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/console/command-line-api-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/command-line-api-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/console/command-line-api-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/console/command-line-api-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/console/command-line-api.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/command-line-api.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/console/command-line-api.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/console/command-line-api.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/console/console-clear-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-clear-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/console/console-clear-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/console/console-clear-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/console/console-clear.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-clear.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/console/console-clear.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/console/console-clear.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-basic-expected.txt b/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-basic-expected.txt
index 532b57cc..c1f2cfe1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-basic-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-basic-expected.txt
@@ -1,5 +1,5 @@
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php?count=1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php?count=2. The 'Access-Control-Allow-Origin' header has a value 'http://some.other.origin:80' that is not equal to the supplied origin. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php?count=1: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php?count=2: The 'Access-Control-Allow-Origin' header has a value 'http://some.other.origin:80' that is not equal to the supplied origin. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that basic EventSource cross-origin requests fail until they are allowed by the Access-Control-Allow-Origin header.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-non-http-expected.txt b/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-non-http-expected.txt
index f72c4114..f58bfef0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-non-http-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-non-http-expected.txt
@@ -1,7 +1,7 @@
-CONSOLE ERROR: EventSource cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: EventSource cannot load motd. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: EventSource cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: EventSource cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load motd: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
 Test EventSource with non-HTTP protocol schemes in the URL.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-redirect-expected.txt
index 2bdb0c7..074f1b1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-redirect-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-redirect-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that basic EventSource cross-origin requests fail on redirect.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-with-credentials-expected.txt b/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-with-credentials-expected.txt
index cddc02f7..6f48db8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-with-credentials-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/eventsource/eventsource-cors-with-credentials-expected.txt
@@ -1,6 +1,6 @@
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=1. The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=2. The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=3. The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=1: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=2: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=3: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that EventSource cross-origin requests with credentials fail until the correct CORS headers are sent.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-basic-expected.txt b/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-basic-expected.txt
index 69c503e..0365adc 100644
--- a/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-basic-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-basic-expected.txt
@@ -1,5 +1,5 @@
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php?count=1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php?count=2. The 'Access-Control-Allow-Origin' header has a value 'http://some.other.origin:80' that is not equal to the supplied origin. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php?count=1: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php?count=2: The 'Access-Control-Allow-Origin' header has a value 'http://some.other.origin:80' that is not equal to the supplied origin. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 [Worker] Test that basic EventSource cross-origin requests fail until they are allowed by the Access-Control-Allow-Origin header.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-non-http-expected.txt b/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-non-http-expected.txt
index 02804dbd..b6585b2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-non-http-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-non-http-expected.txt
@@ -1,7 +1,7 @@
-CONSOLE ERROR: EventSource cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: EventSource cannot load motd. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: EventSource cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: EventSource cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load motd: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
 [Worker] Test EventSource with non-HTTP protocol schemes in the URL.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-redirect-expected.txt
index 10bf757..254860bf 100644
--- a/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-redirect-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-redirect-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-basic.php: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 [Worker] Test that basic EventSource cross-origin requests fail on redirect.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-with-credentials-expected.txt b/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-with-credentials-expected.txt
index 0b5cc87..e8d4d61 100644
--- a/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-with-credentials-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/eventsource/workers/eventsource-cors-with-credentials-expected.txt
@@ -1,6 +1,6 @@
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=1. The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=2. The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: EventSource cannot load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=3. The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=1: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=2: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8080/eventsource/resources/es-cors-credentials.php?count=3: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 [Worker] Test that EventSource cross-origin requests with credentials fail until the correct CORS headers are sent.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/error-messages-expected.txt b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/error-messages-expected.txt
index 8e220c41..af739eb 100644
--- a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/error-messages-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/error-messages-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: Fetch API cannot load http://localhost:8000/fetch/resources/doctype.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
+CONSOLE ERROR: Failed to load http://localhost:8000/fetch/resources/doctype.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
 CONSOLE ERROR: Fetch API cannot load http://localhost:8000/fetch/resources/redirect-loop.php?Count=100&ACAOrigin=*. Redirect failed.
 This is a testharness.js-based test.
 PASS fetch() with 200 should not output error messages 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console-xhr-logging-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/console-xhr-logging-expected.txt
index dd9ac27..1c332bc 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/console-xhr-logging-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console-xhr-logging-expected.txt
@@ -3,12 +3,12 @@
 CONSOLE MESSAGE: line 10: sending a %s request to %s
 CONSOLE MESSAGE: line 10: sending a %s request to %s
 CONSOLE MESSAGE: line 10: sending a %s request to %s
-CONSOLE ERROR: line 37: XMLHttpRequest cannot load http://localhost:8000/inspector/resources/xhr-exists.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 37: Failed to load http://localhost:8000/inspector/resources/xhr-exists.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 CONSOLE MESSAGE: line 10: sending a %s request to %s
 CONSOLE MESSAGE: line 10: sending a %s request to %s
 CONSOLE MESSAGE: line 10: sending a %s request to %s
 CONSOLE MESSAGE: line 10: sending a %s request to %s
-CONSOLE ERROR: line 37: XMLHttpRequest cannot load http://localhost:8000/inspector/resources/xhr-exists.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 37: Failed to load http://localhost:8000/inspector/resources/xhr-exists.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Tests that XMLHttpRequest Logging works when Enabled and doesn't show logs when Disabled.
 
 console-xhr-logging.html:5 sending a GET request to resources/xhr-exists.html
@@ -45,7 +45,7 @@
 requestHelper @ console-xhr-logging.html:6
 (anonymous) @ VM:1
 console-xhr-logging.html:5 sending a GET request to http://localhost:8000/inspector/resources/xhr-exists.html
-network-test.js:37 XMLHttpRequest cannot load http://localhost:8000/inspector/resources/xhr-exists.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+network-test.js:37 Failed to load http://localhost:8000/inspector/resources/xhr-exists.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 makeXHR @ network-test.js:37
 makeSimpleXHRWithPayload @ network-test.js:16
 makeSimpleXHR @ network-test.js:11
@@ -67,7 +67,7 @@
 (anonymous) @ VM:1
 console-xhr-logging.html:5 sending a POST request to resources/post-target.cgi
 console-xhr-logging.html:5 sending a GET request to http://localhost:8000/inspector/resources/xhr-exists.html
-network-test.js:37 XMLHttpRequest cannot load http://localhost:8000/inspector/resources/xhr-exists.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+network-test.js:37 Failed to load http://localhost:8000/inspector/resources/xhr-exists.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 makeXHR @ network-test.js:37
 makeSimpleXHRWithPayload @ network-test.js:16
 makeSimpleXHR @ network-test.js:11
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/.clang-format b/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/.clang-format
deleted file mode 100644
index ea647be..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/.clang-format
+++ /dev/null
@@ -1,8 +0,0 @@
----
-BasedOnStyle: Chromium
-Language: JavaScript
-ColumnLimit: 120
-CommentPragmas: .*\@.*
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: None
-ReflowComments: false
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/simple-test-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/simple-test-expected.txt
deleted file mode 100644
index 1e52e11..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/simple-test-expected.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Start test
-Make sure the new test runner works
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/simple-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/simple-test.js
deleted file mode 100644
index e88e1a1..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/devtools-js/simple-test.js
+++ /dev/null
@@ -1,9 +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.
-
-(function() {
-  TestRunner.addResult('Start test');
-  TestRunner.addResult('Make sure the new test runner works');
-  TestRunner.completeTest();
-})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network-preflight-options-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/network-preflight-options-expected.txt
index d44e46d9..f17c909 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/network-preflight-options-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network-preflight-options-expected.txt
@@ -1,8 +1,8 @@
 CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load http://localhost:8000/inspector/resources/cors-target.php?id=0&deny=yes. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load http://localhost:8000/inspector/resources/cors-target.php?id=1&deny=yes. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/inspector/resources/cors-target.php?id=3&deny=yes. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/inspector/resources/cors-target.php?id=4&deny=yes. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 20: Failed to load http://localhost:8000/inspector/resources/cors-target.php?id=0&deny=yes: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 20: Failed to load http://localhost:8000/inspector/resources/cors-target.php?id=1&deny=yes: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/inspector/resources/cors-target.php?id=3&deny=yes: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/inspector/resources/cors-target.php?id=4&deny=yes: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Tests that preflight OPTIONS requests appear in Network resources
 
 Bug 63712
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-datasaver-warning-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-datasaver-warning-expected.txt
new file mode 100644
index 0000000..c5dec33
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-datasaver-warning-expected.txt
@@ -0,0 +1,14 @@
+Tests to ensure datsaver logs warning in console if enabled and only shown once on reloads.
+
+Console messages:
+
+Enabling data saver
+Reloading Page
+Page reloaded.
+Console messages:
+Consider disabling Chrome Data Saver while debugging. For more info see: https://support.google.com/chrome/?p=datasaver
+
+Reloading Page
+Page reloaded.
+Console messages:
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-datasaver-warning.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-datasaver-warning.html
new file mode 100644
index 0000000..f1163a45
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-datasaver-warning.html
@@ -0,0 +1,34 @@
+<html>
+<head>
+<script src="../inspector-test.js"></script>
+<script src="../console-test.js"></script>
+<script src="../network-test.js"></script>
+<script>
+
+async function test() {
+    InspectorTest.addResult('Console messages:')
+    InspectorTest.dumpConsoleMessages();
+    InspectorTest.addResult('');
+
+    InspectorTest.addResult('Enabling data saver');
+    InspectorTest.evaluateInPagePromise('window.internals.settings.setDataSaverEnabled(true)');
+    InspectorTest.addResult('Reloading Page');
+    await InspectorTest.reloadPagePromise();
+
+    InspectorTest.addResult('Console messages:')
+    InspectorTest.dumpConsoleMessages();
+    InspectorTest.addResult('');
+
+    InspectorTest.addResult('Reloading Page');
+    await InspectorTest.reloadPagePromise();
+    InspectorTest.addResult('Console messages:')
+    InspectorTest.dumpConsoleMessages();
+
+    InspectorTest.completeTest();
+}
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests to ensure datsaver logs warning in console if enabled and only shown once on reloads.</p>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-disable-cache-cors-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-disable-cache-cors-expected.txt
index 07b460c..ec9ed85 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-disable-cache-cors-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-disable-cache-cors-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: Fetch API cannot load http://localhost:8080/inspector/network/resources/cors-redirect.cgi. Response for preflight is invalid (redirect)
+CONSOLE ERROR: Failed to load http://localhost:8080/inspector/network/resources/cors-redirect.cgi: Response for preflight is invalid (redirect)
 CONSOLE MESSAGE: line 32: Done.
 Tests that preflight OPTIONS is always sent if 'Disable cache' is checked, and that network instrumentation does not produce errors for redirected preflights.
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/isolatedWorld/cross-origin-xhr-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/isolatedWorld/cross-origin-xhr-expected.txt
index deea6863..ecc5aa7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/isolatedWorld/cross-origin-xhr-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/isolatedWorld/cross-origin-xhr-expected.txt
@@ -1,6 +1,6 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/security/isolatedWorld/resources/cross-origin-xhr.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/security/isolatedWorld/resources/cross-origin-xhr.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/security/isolatedWorld/resources/cross-origin-xhr.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/security/isolatedWorld/resources/cross-origin-xhr.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/security/isolatedWorld/resources/cross-origin-xhr.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/security/isolatedWorld/resources/cross-origin-xhr.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Tests that isolated worlds can have XHRs run in a different origin.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/suborigins/crossorigin/suborigin-cors-fetch-failure-output-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/suborigins/crossorigin/suborigin-cors-fetch-failure-output-expected.txt
index b8be91b..be0194cc 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/suborigins/crossorigin/suborigin-cors-fetch-failure-output-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/suborigins/crossorigin/suborigin-cors-fetch-failure-output-expected.txt
@@ -1,5 +1,5 @@
-CONSOLE ERROR: Fetch API cannot load http://127.0.0.1:8000/security/resources/cors-script.php?cors=false. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http-so://foobar.127.0.0.1:8000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
-CONSOLE ERROR: Fetch API cannot load http://127.0.0.1:8000/security/resources/cors-script.php?cors=false. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http-so://foobar.127.0.0.1:8000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8000/security/resources/cors-script.php?cors=false: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http-so://foobar.127.0.0.1:8000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8000/security/resources/cors-script.php?cors=false: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http-so://foobar.127.0.0.1:8000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
 This is a testharness.js-based test.
 PASS Custom headers causes preflight failure 
 PASS Lack of Access-Control-Allow-Suborigin on response causes failure 
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/suborigins/crossorigin/suborigin-cors-xhr-failure-output-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/suborigins/crossorigin/suborigin-cors-xhr-failure-output-expected.txt
index ed840e3b..3c7731e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/suborigins/crossorigin/suborigin-cors-xhr-failure-output-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/suborigins/crossorigin/suborigin-cors-xhr-failure-output-expected.txt
@@ -1,5 +1,5 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://127.0.0.1:8000/security/resources/cors-script.php?cors=false. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http-so://foobar.127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://127.0.0.1:8000/security/resources/cors-script.php?cors=false. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http-so://foobar.127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8000/security/resources/cors-script.php?cors=false: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http-so://foobar.127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8000/security/resources/cors-script.php?cors=false: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http-so://foobar.127.0.0.1:8000' is therefore not allowed access.
 This is a testharness.js-based test.
 PASS Custom headers causes preflight failure 
 PASS Lack of Access-Control-Allow-Suborigin on response causes failure 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt
index d976089..9f5f77c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt
@@ -1,8 +1,8 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' to 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000' has been blocked by CORS policy: Redirect location 'http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' contains a username and password, which is disallowed for cross-origin requests.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000' has been blocked by CORS policy: Redirect location 'foo://bar.cgi' has a disallowed scheme for cross-origin requests.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true&%20%20url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=*. Response for preflight is invalid (redirect)
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi. Request header field x-webkit is not allowed by Access-Control-Allow-Headers in preflight response.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' to 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000' has been blocked by CORS policy: Redirect location 'http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' contains a username and password, which is disallowed for cross-origin requests.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000' has been blocked by CORS policy: Redirect location 'foo://bar.cgi' has a disallowed scheme for cross-origin requests.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true&%20%20url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=*: Response for preflight is invalid (redirect)
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi: Request header field x-webkit is not allowed by Access-Control-Allow-Headers in preflight response.
 Tests that asynchronous XMLHttpRequests handle redirects according to the CORS standard.
 
 Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi without credentials
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-same-origin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-same-origin-expected.txt
index c27205fd..da2258b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-same-origin-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-same-origin-expected.txt
@@ -1,5 +1,5 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi. The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-no-credentials.cgi. The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-no-credentials.cgi: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
 Tests that asynchronous XMLHttpRequests handle redirects according to the CORS standard.
 
 Testing resources/redirect.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi without credentials
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-expected.txt
index 5285aae..e7d1b197 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-expected.txt
@@ -1,6 +1,6 @@
 CONSOLE WARNING: line 22: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/redirect.php?url=http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow.cgi. Redirect from 'http://localhost:8000/resources/redirect.php?url=http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow.cgi' to 'http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow.cgi' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/redirect.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow.cgi. Redirect from 'http://localhost:8000/resources/redirect.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow.cgi' to 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow.cgi' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/redirect.php?url=http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow.cgi: Redirect from 'http://localhost:8000/resources/redirect.php?url=http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow.cgi' to 'http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow.cgi' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/redirect.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow.cgi: Redirect from 'http://localhost:8000/resources/redirect.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow.cgi' to 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow.cgi' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Tests that redirects between origins are never allowed, even when access control is involved.
 
 Per the spec, these test cases should be allowed, but cross-origin redirects are currently unsupported in WebCore.
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-denied-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-denied-expected.txt
index 19773be..4d8ebb2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-denied-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-denied-expected.txt
@@ -1,4 +1,4 @@
 CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 24: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 24: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 PASS: Exception thrown. Cross-domain access was denied in 'send'. [Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi'.].
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-denied-preflight-cache-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-denied-preflight-cache-expected.txt
index 054b06c..15bbf8ac 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-denied-preflight-cache-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-denied-preflight-cache-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test async xhr preflight cache denial. If this test passes, there should be a single PASS below.
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-get-fail-non-simple-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-get-fail-non-simple-expected.txt
index a3267150..2a15954 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-get-fail-non-simple-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-get-fail-non-simple-expected.txt
@@ -1,4 +1,4 @@
 CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 28: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-get-fail-non-simple.cgi. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The response had HTTP status code 403.
+CONSOLE ERROR: line 28: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-get-fail-non-simple.cgi: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The response had HTTP status code 403.
 PASS: Exception thrown. Cross-domain access was denied in 'send'. [Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-get-fail-non-simple.cgi'.].
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-non-simple-deny-cached-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-non-simple-deny-cached-expected.txt
index 5f88b21..1ac69bb 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-non-simple-deny-cached-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-non-simple-deny-cached-expected.txt
@@ -1,4 +1,4 @@
 CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 42: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-non-get-allow.cgi. Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
+CONSOLE ERROR: line 42: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-non-get-allow.cgi: Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
 PASS: Exception thrown. Cross-domain access is not allowed in 'send'. [Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-non-get-allow.cgi'.].
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-post-fail-non-simple-content-type-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-post-fail-non-simple-content-type-expected.txt
index 378e3ccd..102ce164 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-post-fail-non-simple-content-type-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-basic-post-fail-non-simple-content-type-expected.txt
@@ -1,4 +1,4 @@
 CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 28: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-options-not-supported.cgi. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 28: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-options-not-supported.cgi: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 PASS: Exception thrown. Cross-domain access was denied in 'send'. [Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-options-not-supported.cgi'.].
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-header-denied-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-header-denied-expected.txt
index f703a006..e8fa1b6b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-header-denied-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-header-denied-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 19: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=header. Request header field X-NON-STANDARD is not allowed by Access-Control-Allow-Headers in preflight response.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=header: Request header field X-NON-STANDARD is not allowed by Access-Control-Allow-Headers in preflight response.
 PASS: Request successfully blocked.
 
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-method-denied-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-method-denied-expected.txt
index 5cf68a64..6014db6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-method-denied-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-method-denied-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 19: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=method. Method DELETE is not allowed by Access-Control-Allow-Methods in preflight response.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=method: Method DELETE is not allowed by Access-Control-Allow-Methods in preflight response.
 PASS: Request successfully blocked.
 
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-not-supported-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-not-supported-expected.txt
index 18fd2a2..0635351e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-not-supported-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-async-not-supported-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 19: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 PASS: Request successfully blocked.
 
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-301-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-301-expected.txt
index d3cddfde..9e4beeb 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-301-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-301-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-request-invalid-status.php?code=301. Response for preflight has invalid HTTP status code 301
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-request-invalid-status.php?code=301: Response for preflight has invalid HTTP status code 301
 Test that preflight requests with invalid status code results in error. Should print PASS.
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-400-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-400-expected.txt
index 1b95c77e..2dddee0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-400-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-400-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-request-invalid-status.php?code=400. Response for preflight has invalid HTTP status code 400
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-request-invalid-status.php?code=400: Response for preflight has invalid HTTP status code 400
 Test that preflight requests with invalid status code results in error. Should print PASS.
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-501-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-501-expected.txt
index f2b9b07..2f97a0cc 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-501-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-request-invalid-status-501-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-request-invalid-status.php?code=501. Response for preflight has invalid HTTP status code 501
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-request-invalid-status.php?code=501: Response for preflight has invalid HTTP status code 501
 Test that preflight requests with invalid status code results in error. Should print PASS.
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-header-denied-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-header-denied-expected.txt
index 46eca2d..dfb79e2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-header-denied-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-header-denied-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 35: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=header. Request header field X-NON-STANDARD is not allowed by Access-Control-Allow-Headers in preflight response.
+CONSOLE ERROR: line 35: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=header: Request header field X-NON-STANDARD is not allowed by Access-Control-Allow-Headers in preflight response.
 PASS: Request successfully blocked.
 
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-method-denied-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-method-denied-expected.txt
index 026b76c..a3f84f3a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-method-denied-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-method-denied-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 34: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=method. Method DELETE is not allowed by Access-Control-Allow-Methods in preflight response.
+CONSOLE ERROR: line 34: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=method: Method DELETE is not allowed by Access-Control-Allow-Methods in preflight response.
 PASS: Request successfully blocked.
 
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-not-supported-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-not-supported-expected.txt
index 1f76c978..15ab859 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-not-supported-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-preflight-sync-not-supported-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 34: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 34: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 PASS: Request successfully blocked.
 
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-repeated-failed-preflight-crash-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-repeated-failed-preflight-crash-expected.txt
index 4dcc1ac..274519d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-repeated-failed-preflight-crash-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-repeated-failed-preflight-crash-expected.txt
@@ -1,7 +1,7 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-expected.txt
index c5a5bac..fef2dc4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 11: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 17: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-denied.cgi. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
+CONSOLE ERROR: line 17: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-denied.cgi: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
 This test verifies that sandboxed iframe does not have XmlHttpRequest access to its server. It will print "PASS" on success.
 
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard-expected.txt
index 3c9fa08..f4e983b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 10: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 16: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard.cgi. Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'http://127.0.0.1:8000' that is not equal to the supplied origin. Origin 'null' is therefore not allowed access.
+CONSOLE ERROR: line 16: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard.cgi: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'http://127.0.0.1:8000' that is not equal to the supplied origin. Origin 'null' is therefore not allowed access.
 This test verifies that sandboxed iframe does not have XmlHttpRequest access to its server with "Access-Control-Allow-Origin" set to its own origin (127.0.0.1).
 
 This test will print "PASS" on success.
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-origin-no-credential-prompt-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-origin-no-credential-prompt-expected.txt
index cc37872..1ee0dfd 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-origin-no-credential-prompt-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-origin-no-credential-prompt-expected.txt
@@ -1,2 +1,2 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/basic-auth/basic-auth.php?uid=41531. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The response had HTTP status code 401.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/basic-auth/basic-auth.php?uid=41531: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The response had HTTP status code 401.
 There should be no authentication prompt displayed, since this is a cross-origin request. In automatic mode, the test relies on logging of authentication sheets.
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-origin-unsupported-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-origin-unsupported-url-expected.txt
index 4959f73..bf07bdf 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-origin-unsupported-url-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-origin-unsupported-url-expected.txt
@@ -1,16 +1,16 @@
 CONSOLE WARNING: line 14: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 20: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 20: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 20: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 20: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 20: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 20: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
 Test cross-origin XHRs to CORS-unsupported protocol schemes in the URL.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-expected.txt
index e8ffe1f..a549a52 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-expected.txt
@@ -1,3 +1,3 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 PASS
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-sync-2-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-sync-2-expected.txt
index 98fc7f0..f05c29b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-sync-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-sync-2-expected.txt
@@ -1,4 +1,4 @@
 CONSOLE WARNING: line 48: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 50: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 50: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 PASS
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-sync-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-sync-expected.txt
index b44df2d..9faf1f1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/cross-site-denied-response-sync-expected.txt
@@ -1,4 +1,4 @@
 CONSOLE WARNING: line 53: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 55: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 55: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 PASS
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/onerror-event-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/onerror-event-expected.txt
index 1a34ef3..d46bab5b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/onerror-event-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/onerror-event-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 This test that the error event is fired for XMLHttpRequests
 
 PASS: error event fired.
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/ontimeout-event-override-after-failure-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/ontimeout-event-override-after-failure-expected.txt
index b57cc321..43b3133 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/ontimeout-event-override-after-failure-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/ontimeout-event-override-after-failure-expected.txt
@@ -1,3 +1,3 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-denied.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 PASS: Timeout override did not reactivate timer after failure
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-cross-origin-response-handling-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-cross-origin-response-handling-expected.txt
index c8cc3207..33a9df0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-cross-origin-response-handling-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-cross-origin-response-handling-expected.txt
@@ -1,13 +1,13 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/test.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/test.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 XMLHttpRequest doesn't crash even when open() is invoked synchronously to handling of a response to a cross-origin request.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-preflight-handling-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-preflight-handling-expected.txt
index 8ff47cb..01c3f5c4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-preflight-handling-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-preflight-handling-expected.txt
@@ -1,13 +1,13 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 XMLHttpRequest doesn't crash even when open() is invoked synchronously to handling of an invalid preflight response.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-redirect-response-handling-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-redirect-response-handling-expected.txt
index bc58ea7..695a65e3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-redirect-response-handling-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-redirect-response-handling-expected.txt
@@ -1,13 +1,13 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect.php?url=/' to 'http://localhost:8000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 XMLHttpRequest doesn't crash even when open() is invoked synchronously to handling of a redirect response to a cross-origin request.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/07-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/07-expected.txt
index 4514c787..3104bad 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/07-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/07-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Fwww2.localhost%3A8000. The 'Access-Control-Allow-Origin' header has a value 'http://www2.localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Fwww2.localhost%3A8000: The 'Access-Control-Allow-Origin' header has a value 'http://www2.localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/08-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/08-expected.txt
index f3fc627..dd5a13ce 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/08-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/08-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains the invalid value '//localhost:8000'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains the invalid value '//localhost:8000'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/09-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/09-expected.txt
index 541ed79..d49d549 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/09-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/09-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains the invalid value '://localhost:8000'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains the invalid value '://localhost:8000'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/10-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/10-expected.txt
index 4e1423f..705914312 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/10-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/10-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=ftp%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header has a value 'ftp://localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=ftp%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header has a value 'ftp://localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/11-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/11-expected.txt
index 023a560..4edaa97c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/11-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/11-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains the invalid value 'http:://localhost:8000'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains the invalid value 'http:://localhost:8000'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/12-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/12-expected.txt
index 391bf93..dc7beeb0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/12-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/12-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header has a value 'http:/localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header has a value 'http:/localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/13-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/13-expected.txt
index aa5179ea..d222a61 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/13-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/13-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3Alocalhost%3A8000. The 'Access-Control-Allow-Origin' header has a value 'http:localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3Alocalhost%3A8000: The 'Access-Control-Allow-Origin' header has a value 'http:localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/14-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/14-expected.txt
index ef31a15..947071c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/14-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/14-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=localhost%3A8000. The 'Access-Control-Allow-Origin' header has a value 'localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=localhost%3A8000: The 'Access-Control-Allow-Origin' header has a value 'localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/15-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/15-expected.txt
index df5ff57..a1a3612 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/15-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/15-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%3F. The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000?' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%3F: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000?' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/16-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/16-expected.txt
index dcb03a5..901af71 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/16-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/16-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2F. The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000/' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2F: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000/' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/17-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/17-expected.txt
index f0e6ca60..abc57e3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/17-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/17-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%20%2F. The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8000 /', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%20%2F: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8000 /', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/18-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/18-expected.txt
index e9baf8e..0fbbeb7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/18-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/18-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%23. The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000#' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%23: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000#' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/19-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/19-expected.txt
index 5c0a9cf..79589c8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/19-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/19-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2523. The 'Access-Control-Allow-Origin' header contains the invalid value 'http://localhost:8000%23'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2523: The 'Access-Control-Allow-Origin' header contains the invalid value 'http://localhost:8000%23'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/20-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/20-expected.txt
index 8f6fd7b..8f69ba3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/20-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/20-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%3A80. The 'Access-Control-Allow-Origin' header contains the invalid value 'http://localhost:8000:80'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%3A80: The 'Access-Control-Allow-Origin' header contains the invalid value 'http://localhost:8000:80'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/21-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/21-expected.txt
index a16ec25..bd64b1f5 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/21-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/21-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2C%20*. The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8000, *', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2C%20*: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8000, *', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/22-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/22-expected.txt
index db07008b..ece4e563 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/22-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/22-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%00. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%00: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/23-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/23-expected.txt
index 8bc1f73..1751337f 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/23-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/23-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=HTTP%3A%2F%2FLOCALHOST%3A8000. The 'Access-Control-Allow-Origin' header has a value 'HTTP://LOCALHOST:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=HTTP%3A%2F%2FLOCALHOST%3A8000: The 'Access-Control-Allow-Origin' header has a value 'HTTP://LOCALHOST:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/24-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/24-expected.txt
index 19acbbe3..85a5577c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/24-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/24-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=HTTP%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header has a value 'HTTP://localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=HTTP%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header has a value 'HTTP://localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/25-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/25-expected.txt
index bf76ff9d..20b1cac 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/25-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/25-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=-. The 'Access-Control-Allow-Origin' header contains the invalid value '-'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=-: The 'Access-Control-Allow-Origin' header contains the invalid value '-'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/26-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/26-expected.txt
index dc61839..10ce2665 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/26-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/26-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=**. The 'Access-Control-Allow-Origin' header contains the invalid value '**'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=**: The 'Access-Control-Allow-Origin' header contains the invalid value '**'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/27-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/27-expected.txt
index c1ecce2..9465f1d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/27-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/27-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%00*. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%00*: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/28-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/28-expected.txt
index 96d8c5e..c56dd05 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/28-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/28-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*%00. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*%00: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/29-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/29-expected.txt
index 7cc7440..d7cf512c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/29-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/29-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%27*%27. The 'Access-Control-Allow-Origin' header contains the invalid value ''*''. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%27*%27: The 'Access-Control-Allow-Origin' header contains the invalid value ''*''. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/30-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/30-expected.txt
index 6b1858b..46998df3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/30-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/30-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%22*%22. The 'Access-Control-Allow-Origin' header contains the invalid value '"*"'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%22*%22: The 'Access-Control-Allow-Origin' header contains the invalid value '"*"'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/31-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/31-expected.txt
index 65a1773..cbfbbc47 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/31-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/31-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*%20*. The 'Access-Control-Allow-Origin' header contains multiple values '* *', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*%20*: The 'Access-Control-Allow-Origin' header contains multiple values '* *', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/32-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/32-expected.txt
index 4c297af..1293e18 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/32-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/32-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*http%3A%2F%2F*. The 'Access-Control-Allow-Origin' header contains the invalid value '*http://*'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*http%3A%2F%2F*: The 'Access-Control-Allow-Origin' header contains the invalid value '*http://*'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/33-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/33-expected.txt
index f5517de..b6eea2e7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/33-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/33-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*http%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains the invalid value '*http://localhost:8000'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*http%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains the invalid value '*http://localhost:8000'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/34-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/34-expected.txt
index 2b8e3eb..43caa70 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/34-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/34-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*%20http%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains multiple values '* http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*%20http%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains multiple values '* http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/35-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/35-expected.txt
index 252fc4c..b99ee5fa 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/35-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/35-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*%2C%20http%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains multiple values '*, http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=*%2C%20http%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains multiple values '*, http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/36-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/36-expected.txt
index 91fd715..e92ff09 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/36-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/36-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%00http%3A%2F%2Flocalhost%3A8000. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=%00http%3A%2F%2Flocalhost%3A8000: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/37-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/37-expected.txt
index 9eccea3..c18c4e8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/37-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/37-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=null%20http%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains multiple values 'null http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=null%20http%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains multiple values 'null http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/38-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/38-expected.txt
index e2e55e6e..aa3254c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/38-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/38-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Fexample.net. The 'Access-Control-Allow-Origin' header has a value 'http://example.net' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Fexample.net: The 'Access-Control-Allow-Origin' header has a value 'http://example.net' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/39-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/39-expected.txt
index c7c26d7..ec786bdf 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/39-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/39-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Fexample.net%20http%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains multiple values 'http://example.net http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Fexample.net%20http%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains multiple values 'http://example.net http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/40-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/40-expected.txt
index e2c2f67..8f09933 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/40-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/40-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Fexample.net%2C%20http%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains multiple values 'http://example.net, http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Fexample.net%2C%20http%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains multiple values 'http://example.net, http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/41-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/41-expected.txt
index bac3d63..6a07755 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/41-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/41-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origins=http%3A%2F%2Fexample.net,http%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains multiple values 'http://example.net, http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origins=http%3A%2F%2Fexample.net,http%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains multiple values 'http://example.net, http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/42-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/42-expected.txt
index 6dbb5d2b..27c13e1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/42-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/42-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origins=http%3A%2F%2Flocalhost%3A8000,http%3A%2F%2Flocalhost%3A8000. The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8000, http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origins=http%3A%2F%2Flocalhost%3A8000,http%3A%2F%2Flocalhost%3A8000: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8000, http://localhost:8000', but only one is allowed. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/43-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/43-expected.txt
index 745c0d5..9ada9e4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/43-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/43-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=null. The 'Access-Control-Allow-Origin' header contains the invalid value 'null'. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=null: The 'Access-Control-Allow-Origin' header contains the invalid value 'null'. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/44-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/44-expected.txt
index 1f67fd3..ab3efc8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/44-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/44-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=. The 'Access-Control-Allow-Origin' header contains the invalid value ''. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=: The 'Access-Control-Allow-Origin' header contains the invalid value ''. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/45-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/45-expected.txt
index f0af58b..7bda2cc9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/45-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/45-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2Fxmlhttprequest%2Fresources%2Forigin-exact-matching-iframe.html%3F45. The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000/xmlhttprequest/resources/origin-exact-matching-iframe.html?45' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2Fxmlhttprequest%2Fresources%2Forigin-exact-matching-iframe.html%3F45: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000/xmlhttprequest/resources/origin-exact-matching-iframe.html?45' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/46-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/46-expected.txt
index aea2ab6..47053e8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/46-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/46-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2Fxmlhttprequest%2Fresources%2F. The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000/xmlhttprequest/resources/' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2Fxmlhttprequest%2Fresources%2F: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000/xmlhttprequest/resources/' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/47-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/47-expected.txt
index e19dbd1b6..210e6d2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/47-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-exact-matching/47-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 24: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2Fxmlhttprequest%2Fresources%2Forigin-exact-matching-iframe.html%3F47. The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000/xmlhttprequest/resources/origin-exact-matching-iframe.html?47' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 1: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-allow-lists.php?origin=http%3A%2F%2Flocalhost%3A8000%2Fxmlhttprequest%2Fresources%2Forigin-exact-matching-iframe.html%3F47: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000/xmlhttprequest/resources/origin-exact-matching-iframe.html?47' that is not equal to the supplied origin. Origin 'http://localhost:8000' is therefore not allowed access.
 
 
 --------
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-https-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-https-expected.txt
index db99a89c8..e631929 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-https-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-https-expected.txt
@@ -1,6 +1,6 @@
 CONSOLE WARNING: line 18: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt?sync. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt?async. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 20: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt?sync: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt?async: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Tests that origin whitelisting for https does not match http URLs.
 
 Testing: http://localhost:8000/xmlhttprequest/resources/get.txt (sync)
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-ip-addresses-with-subdomains-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-ip-addresses-with-subdomains-expected.txt
index f29e815..8b2566e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-ip-addresses-with-subdomains-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-ip-addresses-with-subdomains-expected.txt
@@ -1,6 +1,6 @@
 CONSOLE WARNING: line 14: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 16: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: line 16: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://127.0.0.1:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
 Specifying that an IP address should match subdomains doesn't make sense. This test verifies that it doesn't do anything.
 
 Testing: http://127.0.0.1:8000/xmlhttprequest/resources/get.txt (sync)
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-removal-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-removal-expected.txt
index 607fb62..81621e2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-removal-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-whitelisting-removal-expected.txt
@@ -1,12 +1,12 @@
 CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 19: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: line 19: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: line 19: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: line 19: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: line 19: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: line 19: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: line 19: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: line 19: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/get.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 19: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 19: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 19: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 19: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 19: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 19: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 19: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 19: Failed to load http://localhost:8000/xmlhttprequest/resources/get.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Tests the behavior of whitelisting origins and removing them later.
 
 Testing: source origin: http://127.0.0.1:8000 destination origin: http:localhost 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt
index f437d12a..8dd1dce4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-allow-lists.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-allow-lists.php: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test verifies that content MIME type is set correctly when Blob is sent using XMLHttpRequest asynchronously.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-sync-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-sync-expected.txt
index 847cba8..7281292 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-sync-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 49: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 52: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-allow-lists.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 52: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-allow-lists.php: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test verifies that content MIME type is set correctly when Blob is sent using XMLHttpRequest synchronously.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-2-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-2-expected.txt
index 6da12c1..c8910a2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-2-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that a cross-origin redirect to a server that responds is indistinguishable from one that does not. Should say PASS:
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-expected.txt
index 6da12c1..c8910a2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that a cross-origin redirect to a server that responds is indistinguishable from one that does not. Should say PASS:
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-post-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-post-expected.txt
index dacc9ca..ed93a6c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-post-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-post-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that a cross-origin redirect to a server that responds is indistinguishable from one that does not. Should say PASS:
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-tripmine-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-tripmine-expected.txt
index 5b397bc..4cb39d41 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-tripmine-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/redirect-cross-origin-tripmine-expected.txt
@@ -1,14 +1,14 @@
 CONSOLE WARNING: line 21: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/resources/tripmine.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/resources/tripmine.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that a cross-origin redirect does not result in a non-simple request being sent to the target.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-expected.txt
index dcc9e9d..6dcf331 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that a simple cross-origin request to a server that responds (but does not permit cross-origin requests) is indistinguishable from one that does not exist. Should say PASS:
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post-expected.txt
index ee5737653..59b8f4f 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that a simple cross-origin request to a server that responds (but does not permit cross-origin requests) is indistinguishable from one that does not exist. Should say PASS:
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post-sync-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post-sync-expected.txt
index 80d363a..37f4263 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post-sync-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 30: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 32: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 32: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that a simple cross-origin request to a server that responds (but does not permit cross-origin requests) is indistinguishable from one that does not exist. Should say PASS:
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-sync-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-sync-expected.txt
index a87608b..835f11a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-sync-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 25: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 26: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/reply.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 26: Failed to load http://localhost:8000/xmlhttprequest/resources/reply.xml: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that a simple cross-origin request to a server that responds (but does not permit cross-origin requests) is indistinguishable from one that does not exist. Should say PASS:
 
 PASS
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-progress-events-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-progress-events-expected.txt
index 62b5ea5..c34b512 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-progress-events-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/simple-cross-origin-progress-events-expected.txt
@@ -1,5 +1,5 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/cross-site-progress-events.cgi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/cross-site-progress-events.cgi. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/cross-site-progress-events.cgi: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/cross-site-progress-events.cgi: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test that upload progress events are not dispatched for simple cross-origin requests (i.e. if the listener is set after calling send(), and there are no other reasons to make a preflight request).
 
 Test 1: The URL is allowed for cross-origin requests
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/upload-request-error-event-order-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/upload-request-error-event-order-expected.txt
index 01cc617..3c435c1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/upload-request-error-event-order-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/upload-request-error-event-order-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/cross-site-progress-events.cgi. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/cross-site-progress-events.cgi: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test to validate the order in which the events are fired in case of a request error.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/access-control-basic-get-fail-non-simple-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/access-control-basic-get-fail-non-simple-expected.txt
index 6fb095c..2351d41 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/access-control-basic-get-fail-non-simple-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/access-control-basic-get-fail-non-simple-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: line 37: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-get-fail-non-simple.cgi. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The response had HTTP status code 403.
+CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-get-fail-non-simple.cgi: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The response had HTTP status code 403.
 GET should not trigger a preflight request from a worker unless it has non-simple headers.
 
 PASS: Cross-domain access allowed for simple get.
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt
index 43eac5a..1fe12c7d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt
@@ -1,15 +1,15 @@
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
 [Worker] Test cross-origin XHRs to CORS-unsupported protocol schemes in the URL.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-sync-no-progress-events-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-sync-no-progress-events-expected.txt
index da64263..c3e4ac95 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-sync-no-progress-events-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-sync-no-progress-events-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 18: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 35: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/xmlhttprequest-sync-vs-async-assertion-failure.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: line 35: Failed to load http://localhost:8000/xmlhttprequest/xmlhttprequest-sync-vs-async-assertion-failure.html: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 Test for:
 
 bug 40996: Progress event should not be fired during synchronous XMLHttpRequest;
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-unsafe-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-unsafe-redirect-expected.txt
index 7097aed..d4e1fcbb 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-unsafe-redirect-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-unsafe-redirect-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 52: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8080/xmlhttprequest/resources/forbidden.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
+CONSOLE ERROR: Failed to load http://localhost:8080/xmlhttprequest/resources/forbidden.txt: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 This tests that unsafe redirects won't be allowed when making an XMLHttpRequest.
 Sync XHR started.
 readyState change 1
diff --git a/third_party/WebKit/LayoutTests/inspector/modules-load-network-expected.txt b/third_party/WebKit/LayoutTests/inspector/modules-load-network-expected.txt
index 57894491..e33ea058 100644
--- a/third_party/WebKit/LayoutTests/inspector/modules-load-network-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/modules-load-network-expected.txt
@@ -6,6 +6,7 @@
     data_grid
     diff
     formatter
+    har_importer
     network
     network_priorities
     object_ui
diff --git a/third_party/WebKit/LayoutTests/virtual/off-main-thread-fetch/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt b/third_party/WebKit/LayoutTests/virtual/off-main-thread-fetch/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt
index de5a621..e4a0621 100644
--- a/third_party/WebKit/LayoutTests/virtual/off-main-thread-fetch/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/off-main-thread-fetch/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt
@@ -1,15 +1,15 @@
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load ftp://127.0.0.1/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load localhost:8080/. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 20: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
-CONSOLE ERROR: line 1: XMLHttpRequest cannot load tel:1234. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load ftp://127.0.0.1/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load localhost:8080/: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
+CONSOLE ERROR: line 1: Failed to load tel:1234: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
 [Worker] Test cross-origin XHRs to CORS-unsupported protocol schemes in the URL.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/Source/build/scripts/make_cssom_types.py b/third_party/WebKit/Source/build/scripts/core/css/make_cssom_types.py
similarity index 71%
rename from third_party/WebKit/Source/build/scripts/make_cssom_types.py
rename to third_party/WebKit/Source/build/scripts/core/css/make_cssom_types.py
index 01b62398..a9c9e3d 100755
--- a/third_party/WebKit/Source/build/scripts/make_cssom_types.py
+++ b/third_party/WebKit/Source/build/scripts/core/css/make_cssom_types.py
@@ -3,7 +3,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import os
 import sys
+sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
 
 import css_properties
 import json5_generator
@@ -21,33 +23,33 @@
     def __init__(self, json5_file_path):
         super(CSSOMTypesWriter, self).__init__(json5_file_path)
 
-        for property in self._properties.values():
+        for property_ in self._properties.values():
             types = []
             # Expand types
-            for singleType in property['typedom_types']:
-                if singleType == 'Image':
+            for single_type in property_['typedom_types']:
+                if single_type == 'Image':
                     types.append('URLImage')
                 else:
-                    types.append(singleType)
-            property['typedom_types'] = types
+                    types.append(single_type)
+            property_['typedom_types'] = types
 
             # Generate Keyword ID values from keywords.
-            property['keywordIDs'] = map(
-                enum_for_css_keyword, property['keywords'])
+            property_['keywordIDs'] = map(
+                enum_for_css_keyword, property_['keywords'])
 
         self._outputs = {
             'CSSOMTypes.cpp': self.generate_types,
             'CSSOMKeywords.cpp': self.generate_keywords,
         }
 
-    @template_expander.use_jinja('templates/CSSOMTypes.cpp.tmpl')
+    @template_expander.use_jinja('core/css/templates/CSSOMTypes.cpp.tmpl')
     def generate_types(self):
         return {
             'input_files': self._input_files,
             'properties': self._properties,
         }
 
-    @template_expander.use_jinja('templates/CSSOMKeywords.cpp.tmpl')
+    @template_expander.use_jinja('core/css/templates/CSSOMKeywords.cpp.tmpl')
     def generate_keywords(self):
         return {
             'input_files': self._input_files,
diff --git a/third_party/WebKit/Source/build/scripts/templates/CSSOMKeywords.cpp.tmpl b/third_party/WebKit/Source/build/scripts/core/css/templates/CSSOMKeywords.cpp.tmpl
similarity index 100%
rename from third_party/WebKit/Source/build/scripts/templates/CSSOMKeywords.cpp.tmpl
rename to third_party/WebKit/Source/build/scripts/core/css/templates/CSSOMKeywords.cpp.tmpl
diff --git a/third_party/WebKit/Source/build/scripts/templates/CSSOMTypes.cpp.tmpl b/third_party/WebKit/Source/build/scripts/core/css/templates/CSSOMTypes.cpp.tmpl
similarity index 100%
rename from third_party/WebKit/Source/build/scripts/templates/CSSOMTypes.cpp.tmpl
rename to third_party/WebKit/Source/build/scripts/core/css/templates/CSSOMTypes.cpp.tmpl
diff --git a/third_party/WebKit/Source/build/scripts/scripts.gni b/third_party/WebKit/Source/build/scripts/scripts.gni
index af56725e..9bac561 100644
--- a/third_party/WebKit/Source/build/scripts/scripts.gni
+++ b/third_party/WebKit/Source/build/scripts/scripts.gni
@@ -79,6 +79,8 @@
   "//third_party/WebKit/Source/core:core_event_interfaces",
 ]
 
+# TODO(shend): Remove this once everything that uses this switches over to
+# the 'code_generator' template instead.
 # Template to run most of scripts that process "*.in" files.
 #   script: script to run.
 #   in_files: ".in" files to pass to the script
@@ -129,6 +131,56 @@
   }
 }
 
+# Template to run code generators in build/scripts/.
+#   script: the path to the script to run.
+#   json_inputs: ".json5" files to pass to the generator.
+#   templates: ".tmpl" files that this generator depends on.
+#   other_inputs: (optional) other input files the generator depends on
+#                 defaults to "scripts_for_json5_files" (if specified, we assume
+#                 that the contents of "scripts_for_json5_files" are included in
+#                 this list).
+#   outputs: expected results. Note that the directory of the 0th item in this
+#            list will be taken to be the output path.
+#   other_args: (optional) other arguments to pass to the script.
+#   deps [optional]:
+#     Depenendencies. If unspecified defaults to make_core_generated_deps.
+template("code_generator") {
+  action(target_name) {
+    script = invoker.script
+    inputs = invoker.json_inputs + invoker.templates
+    if (defined(invoker.other_inputs)) {
+      inputs += invoker.other_inputs
+    } else {
+      inputs += scripts_for_json5_files
+    }
+    outputs = invoker.outputs
+
+    # Extract the directory to write files to.
+    output_dir = get_path_info(outputs[0], "dir")
+
+    args = rebase_path(invoker.json_inputs, root_build_dir) + [
+             "--output_dir",
+             rebase_path(output_dir, root_build_dir),
+           ]
+    if (is_mac && !use_system_xcode) {
+      args += [
+        "--developer_dir",
+        hermetic_xcode_path,
+      ]
+    }
+    if (defined(invoker.other_args)) {
+      args += invoker.other_args
+    }
+
+    if (defined(invoker.deps)) {
+      deps = invoker.deps
+    } else {
+      deps = make_core_generated_deps
+    }
+    forward_variables_from(invoker, [ "visibility" ])
+  }
+}
+
 # Template for scripts using css_properties.py. This is a special case of
 # process_in_files.
 #   outputs: expected results
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index ef3e81c..8b26fa3 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -592,6 +592,7 @@
     "$blink_core_output_dir/css/properties/CSSPropertyAPIZoom.h",
     "$blink_core_output_dir/css/properties/CSSPropertyDescriptor.cpp",
     "$blink_core_output_dir/css/properties/CSSPropertyDescriptor.h",
+    "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIAnimation.h",
     "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIBorderImage.h",
     "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIBorderRadius.h",
     "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIBorderSpacing.h",
@@ -608,6 +609,7 @@
     "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.h",
     "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIScrollSnapMarginInline.h",
     "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPITextDecoration.h",
+    "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPITransition.h",
     "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIWebkitBorderAfter.h",
     "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIWebkitBorderBefore.h",
     "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIWebkitBorderEnd.h",
@@ -666,11 +668,12 @@
   ]
 }
 
-css_properties("make_core_generated_cssom_types") {
-  script = "../build/scripts/make_cssom_types.py"
-  other_inputs = [
-    "../build/scripts/templates/CSSOMKeywords.cpp.tmpl",
-    "../build/scripts/templates/CSSOMTypes.cpp.tmpl",
+code_generator("make_core_generated_cssom_types") {
+  script = "../build/scripts/core/css/make_cssom_types.py"
+  json_inputs = [ "css/CSSProperties.json5" ]
+  templates = [
+    "../build/scripts/core/css/templates/CSSOMKeywords.cpp.tmpl",
+    "../build/scripts/core/css/templates/CSSOMTypes.cpp.tmpl",
   ]
   outputs = [
     "$blink_core_output_dir/CSSOMKeywords.cpp",
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn
index ec78751..3efa6a6 100644
--- a/third_party/WebKit/Source/core/css/BUILD.gn
+++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -506,6 +506,10 @@
     "properties/CSSPropertyAnimationIterationCountUtils.h",
     "properties/CSSPropertyAnimationNameUtils.cpp",
     "properties/CSSPropertyAnimationNameUtils.h",
+    "properties/CSSPropertyAnimationTimingFunctionUtils.cpp",
+    "properties/CSSPropertyAnimationTimingFunctionUtils.h",
+    "properties/CSSPropertyAnimationUtils.cpp",
+    "properties/CSSPropertyAnimationUtils.h",
     "properties/CSSPropertyBorderImageUtils.cpp",
     "properties/CSSPropertyBorderImageUtils.h",
     "properties/CSSPropertyBoxShadowUtils.cpp",
@@ -535,6 +539,7 @@
     "properties/CSSPropertyTransitionPropertyUtils.h",
     "properties/CSSPropertyWebkitBorderWidthUtils.cpp",
     "properties/CSSPropertyWebkitBorderWidthUtils.h",
+    "properties/CSSShorthandPropertyAPIAnimation.cpp",
     "properties/CSSShorthandPropertyAPIBorderImage.cpp",
     "properties/CSSShorthandPropertyAPIBorderRadius.cpp",
     "properties/CSSShorthandPropertyAPIBorderSpacing.cpp",
@@ -551,6 +556,7 @@
     "properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.cpp",
     "properties/CSSShorthandPropertyAPIScrollSnapMarginInline.cpp",
     "properties/CSSShorthandPropertyAPITextDecoration.cpp",
+    "properties/CSSShorthandPropertyAPITransition.cpp",
     "properties/CSSShorthandPropertyAPIWebkitBorderAfter.cpp",
     "properties/CSSShorthandPropertyAPIWebkitBorderBefore.cpp",
     "properties/CSSShorthandPropertyAPIWebkitBorderEnd.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index 9e6bfdac..eddc55d 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -3663,6 +3663,8 @@
     {
       name: "animation",
       longhands: ["animation-name", "animation-duration", "animation-timing-function", "animation-delay", "animation-iteration-count", "animation-direction", "animation-fill-mode", "animation-play-state"],
+      api_class: true,
+      api_methods: ["parseShorthand"],
     },
     {
       name: "background",
@@ -3885,6 +3887,8 @@
     {
       name: "transition",
       longhands: ["transition-property", "transition-duration", "transition-timing-function", "transition-delay"],
+      api_class: true,
+      api_methods: ["parseShorthand"],
     },
     {
       name: "-webkit-border-after",
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index b7f4e48..d6bf9f9 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -2118,6 +2118,16 @@
   return !object.IsSVGChild();
 }
 
+CSSPrimitiveValue* ZoomAdjustedPixelValueWithBorderWidthRounding(
+    double value,
+    const ComputedStyle& style) {
+  const double px_value = AdjustFloatForAbsoluteZoom(value, style);
+
+  return CSSPrimitiveValue::Create(
+      px_value > 0.0 && px_value < 1 ? 1.0 : px_value,
+      CSSPrimitiveValue::UnitType::kPixels);
+}
+
 const CSSValue* ComputedStyleCSSValueMapping::Get(
     CSSPropertyID property_id,
     const ComputedStyle& style,
@@ -2304,13 +2314,17 @@
     case CSSPropertyBorderLeftStyle:
       return CSSIdentifierValue::Create(style.BorderLeftStyle());
     case CSSPropertyBorderTopWidth:
-      return ZoomAdjustedPixelValue(style.BorderTopWidth(), style);
+      return ZoomAdjustedPixelValueWithBorderWidthRounding(
+          style.BorderTopWidth(), style);
     case CSSPropertyBorderRightWidth:
-      return ZoomAdjustedPixelValue(style.BorderRightWidth(), style);
+      return ZoomAdjustedPixelValueWithBorderWidthRounding(
+          style.BorderRightWidth(), style);
     case CSSPropertyBorderBottomWidth:
-      return ZoomAdjustedPixelValue(style.BorderBottomWidth(), style);
+      return ZoomAdjustedPixelValueWithBorderWidthRounding(
+          style.BorderBottomWidth(), style);
     case CSSPropertyBorderLeftWidth:
-      return ZoomAdjustedPixelValue(style.BorderLeftWidth(), style);
+      return ZoomAdjustedPixelValueWithBorderWidthRounding(
+          style.BorderLeftWidth(), style);
     case CSSPropertyBottom:
       return ValueForPositionOffset(style, CSSPropertyBottom, layout_object);
     case CSSPropertyWebkitBoxAlign:
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 9ee80dc4..a66f1ce 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -22,7 +22,6 @@
 #include "core/css/CSSReflectValue.h"
 #include "core/css/CSSShadowValue.h"
 #include "core/css/CSSStringValue.h"
-#include "core/css/CSSTimingFunctionValue.h"
 #include "core/css/CSSURIValue.h"
 #include "core/css/CSSUnicodeRangeValue.h"
 #include "core/css/CSSUnsetValue.h"
@@ -35,8 +34,7 @@
 #include "core/css/parser/CSSPropertyParserHelpers.h"
 #include "core/css/parser/CSSVariableParser.h"
 #include "core/css/properties/CSSPropertyAlignmentUtils.h"
-#include "core/css/properties/CSSPropertyAnimationIterationCountUtils.h"
-#include "core/css/properties/CSSPropertyAnimationNameUtils.h"
+#include "core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h"
 #include "core/css/properties/CSSPropertyBorderImageUtils.h"
 #include "core/css/properties/CSSPropertyBoxShadowUtils.h"
 #include "core/css/properties/CSSPropertyDescriptor.h"
@@ -311,192 +309,6 @@
   return ConsumeString(range);
 }
 
-static CSSValue* ConsumeSteps(CSSParserTokenRange& range) {
-  DCHECK_EQ(range.Peek().FunctionId(), CSSValueSteps);
-  CSSParserTokenRange range_copy = range;
-  CSSParserTokenRange args = ConsumeFunction(range_copy);
-
-  CSSPrimitiveValue* steps = ConsumePositiveInteger(args);
-  if (!steps)
-    return nullptr;
-
-  StepsTimingFunction::StepPosition position =
-      StepsTimingFunction::StepPosition::END;
-  if (ConsumeCommaIncludingWhitespace(args)) {
-    switch (args.ConsumeIncludingWhitespace().Id()) {
-      case CSSValueMiddle:
-        if (!RuntimeEnabledFeatures::WebAnimationsAPIEnabled())
-          return nullptr;
-        position = StepsTimingFunction::StepPosition::MIDDLE;
-        break;
-      case CSSValueStart:
-        position = StepsTimingFunction::StepPosition::START;
-        break;
-      case CSSValueEnd:
-        position = StepsTimingFunction::StepPosition::END;
-        break;
-      default:
-        return nullptr;
-    }
-  }
-
-  if (!args.AtEnd())
-    return nullptr;
-
-  range = range_copy;
-  return CSSStepsTimingFunctionValue::Create(steps->GetIntValue(), position);
-}
-
-static CSSValue* ConsumeFrames(CSSParserTokenRange& range) {
-  DCHECK_EQ(range.Peek().FunctionId(), CSSValueFrames);
-  CSSParserTokenRange range_copy = range;
-  CSSParserTokenRange args = ConsumeFunction(range_copy);
-
-  CSSPrimitiveValue* frames = ConsumePositiveInteger(args);
-  if (!frames)
-    return nullptr;
-
-  int frames_int = frames->GetIntValue();
-  if (frames_int <= 1)
-    return nullptr;
-
-  if (!args.AtEnd())
-    return nullptr;
-
-  range = range_copy;
-  return CSSFramesTimingFunctionValue::Create(frames_int);
-}
-
-static CSSValue* ConsumeCubicBezier(CSSParserTokenRange& range) {
-  DCHECK_EQ(range.Peek().FunctionId(), CSSValueCubicBezier);
-  CSSParserTokenRange range_copy = range;
-  CSSParserTokenRange args = ConsumeFunction(range_copy);
-
-  double x1, y1, x2, y2;
-  if (ConsumeNumberRaw(args, x1) && x1 >= 0 && x1 <= 1 &&
-      ConsumeCommaIncludingWhitespace(args) && ConsumeNumberRaw(args, y1) &&
-      ConsumeCommaIncludingWhitespace(args) && ConsumeNumberRaw(args, x2) &&
-      x2 >= 0 && x2 <= 1 && ConsumeCommaIncludingWhitespace(args) &&
-      ConsumeNumberRaw(args, y2) && args.AtEnd()) {
-    range = range_copy;
-    return CSSCubicBezierTimingFunctionValue::Create(x1, y1, x2, y2);
-  }
-
-  return nullptr;
-}
-
-static CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange& range) {
-  CSSValueID id = range.Peek().Id();
-  if (id == CSSValueEase || id == CSSValueLinear || id == CSSValueEaseIn ||
-      id == CSSValueEaseOut || id == CSSValueEaseInOut ||
-      id == CSSValueStepStart || id == CSSValueStepEnd ||
-      id == CSSValueStepMiddle)
-    return ConsumeIdent(range);
-
-  CSSValueID function = range.Peek().FunctionId();
-  if (function == CSSValueSteps)
-    return ConsumeSteps(range);
-  if (RuntimeEnabledFeatures::FramesTimingFunctionEnabled() &&
-      function == CSSValueFrames) {
-    return ConsumeFrames(range);
-  }
-  if (function == CSSValueCubicBezier)
-    return ConsumeCubicBezier(range);
-  return nullptr;
-}
-
-static CSSValue* ConsumeAnimationValue(CSSPropertyID property,
-                                       CSSParserTokenRange& range,
-                                       const CSSParserContext* context,
-                                       bool use_legacy_parsing) {
-  switch (property) {
-    case CSSPropertyAnimationDelay:
-    case CSSPropertyTransitionDelay:
-      return ConsumeTime(range, kValueRangeAll);
-    case CSSPropertyAnimationDirection:
-      return ConsumeIdent<CSSValueNormal, CSSValueAlternate, CSSValueReverse,
-                          CSSValueAlternateReverse>(range);
-    case CSSPropertyAnimationDuration:
-    case CSSPropertyTransitionDuration:
-      return ConsumeTime(range, kValueRangeNonNegative);
-    case CSSPropertyAnimationFillMode:
-      return ConsumeIdent<CSSValueNone, CSSValueForwards, CSSValueBackwards,
-                          CSSValueBoth>(range);
-    case CSSPropertyAnimationIterationCount:
-      return CSSPropertyAnimationIterationCountUtils::
-          ConsumeAnimationIterationCount(range);
-    case CSSPropertyAnimationName:
-      return CSSPropertyAnimationNameUtils::ConsumeAnimationName(
-          range, context, use_legacy_parsing);
-    case CSSPropertyAnimationPlayState:
-      return ConsumeIdent<CSSValueRunning, CSSValuePaused>(range);
-    case CSSPropertyTransitionProperty:
-      return CSSPropertyTransitionPropertyUtils::ConsumeTransitionProperty(
-          range);
-    case CSSPropertyAnimationTimingFunction:
-    case CSSPropertyTransitionTimingFunction:
-      return ConsumeAnimationTimingFunction(range);
-    default:
-      NOTREACHED();
-      return nullptr;
-  }
-}
-
-bool CSSPropertyParser::ConsumeAnimationShorthand(
-    const StylePropertyShorthand& shorthand,
-    bool use_legacy_parsing,
-    bool important) {
-  const unsigned longhand_count = shorthand.length();
-  CSSValueList* longhands[8];
-  DCHECK_LE(longhand_count, 8u);
-  for (size_t i = 0; i < longhand_count; ++i)
-    longhands[i] = CSSValueList::CreateCommaSeparated();
-
-  do {
-    bool parsed_longhand[8] = {false};
-    do {
-      bool found_property = false;
-      for (size_t i = 0; i < longhand_count; ++i) {
-        if (parsed_longhand[i])
-          continue;
-
-        if (CSSValue* value =
-                ConsumeAnimationValue(shorthand.properties()[i], range_,
-                                      context_, use_legacy_parsing)) {
-          parsed_longhand[i] = true;
-          found_property = true;
-          longhands[i]->Append(*value);
-          break;
-        }
-      }
-      if (!found_property)
-        return false;
-    } while (!range_.AtEnd() && range_.Peek().GetType() != kCommaToken);
-
-    // TODO(timloh): This will make invalid longhands, see crbug.com/386459
-    for (size_t i = 0; i < longhand_count; ++i) {
-      if (!parsed_longhand[i])
-        longhands[i]->Append(*CSSInitialValue::Create());
-      parsed_longhand[i] = false;
-    }
-  } while (ConsumeCommaIncludingWhitespace(range_));
-
-  for (size_t i = 0; i < longhand_count; ++i) {
-    // TODO(bugsnash): Refactor out the need to check for
-    // CSSPropertyTransitionProperty here when this is method implemented in the
-    // property APIs
-    if (shorthand.properties()[i] == CSSPropertyTransitionProperty &&
-        !CSSPropertyTransitionPropertyUtils::IsValidPropertyList(*longhands[i]))
-      return false;
-  }
-
-  for (size_t i = 0; i < longhand_count; ++i) {
-    AddParsedProperty(shorthand.properties()[i], shorthand.id(), *longhands[i],
-                      important);
-  }
-  return range_.AtEnd();
-}
-
 static CSSFunctionValue* ConsumeFilterFunction(
     CSSParserTokenRange& range,
     const CSSParserContext* context) {
@@ -1216,7 +1028,9 @@
                                        kValueRangeNonNegative);
     case CSSPropertyAnimationTimingFunction:
     case CSSPropertyTransitionTimingFunction:
-      return ConsumeCommaSeparatedList(ConsumeAnimationTimingFunction, range_);
+      return ConsumeCommaSeparatedList(CSSPropertyAnimationTimingFunctionUtils::
+                                           ConsumeAnimationTimingFunction,
+                                       range_);
     case CSSPropertyGridColumnGap:
     case CSSPropertyGridRowGap:
       return ConsumeLengthOrPercent(range_, context_->Mode(),
@@ -2321,13 +2135,6 @@
   }
 
   switch (property) {
-    case CSSPropertyAnimation:
-      return ConsumeAnimationShorthand(
-          animationShorthandForParsing(),
-          unresolved_property == CSSPropertyAliasWebkitAnimation, important);
-    case CSSPropertyTransition:
-      return ConsumeAnimationShorthand(transitionShorthandForParsing(), false,
-                                       important);
     case CSSPropertyTextDecoration:
       DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
       return ConsumeShorthandGreedily(textDecorationShorthand(), important);
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
index f7a662c4..6c96729f 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -88,10 +88,6 @@
   bool Consume2Values(const StylePropertyShorthand&, bool important);
   bool Consume4Values(const StylePropertyShorthand&, bool important);
 
-  // Legacy parsing allows <string>s for animation-name
-  bool ConsumeAnimationShorthand(const StylePropertyShorthand&,
-                                 bool use_legacy_parsing,
-                                 bool important);
   bool ConsumeBackgroundShorthand(const StylePropertyShorthand&,
                                   bool important);
 
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationTimingFunctionUtils.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationTimingFunctionUtils.cpp
new file mode 100644
index 0000000..57961c2
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationTimingFunctionUtils.cpp
@@ -0,0 +1,122 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h"
+
+#include "core/css/CSSTimingFunctionValue.h"
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+#include "platform/RuntimeEnabledFeatures.h"
+
+namespace blink {
+
+namespace {
+
+CSSValue* ConsumeSteps(CSSParserTokenRange& range) {
+  DCHECK_EQ(range.Peek().FunctionId(), CSSValueSteps);
+  CSSParserTokenRange range_copy = range;
+  CSSParserTokenRange args =
+      CSSPropertyParserHelpers::ConsumeFunction(range_copy);
+
+  CSSPrimitiveValue* steps =
+      CSSPropertyParserHelpers::ConsumePositiveInteger(args);
+  if (!steps)
+    return nullptr;
+
+  StepsTimingFunction::StepPosition position =
+      StepsTimingFunction::StepPosition::END;
+  if (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) {
+    switch (args.ConsumeIncludingWhitespace().Id()) {
+      case CSSValueMiddle:
+        if (!RuntimeEnabledFeatures::WebAnimationsAPIEnabled())
+          return nullptr;
+        position = StepsTimingFunction::StepPosition::MIDDLE;
+        break;
+      case CSSValueStart:
+        position = StepsTimingFunction::StepPosition::START;
+        break;
+      case CSSValueEnd:
+        position = StepsTimingFunction::StepPosition::END;
+        break;
+      default:
+        return nullptr;
+    }
+  }
+
+  if (!args.AtEnd())
+    return nullptr;
+
+  range = range_copy;
+  return CSSStepsTimingFunctionValue::Create(steps->GetIntValue(), position);
+}
+
+CSSValue* ConsumeFrames(CSSParserTokenRange& range) {
+  DCHECK_EQ(range.Peek().FunctionId(), CSSValueFrames);
+  CSSParserTokenRange range_copy = range;
+  CSSParserTokenRange args =
+      CSSPropertyParserHelpers::ConsumeFunction(range_copy);
+
+  CSSPrimitiveValue* frames =
+      CSSPropertyParserHelpers::ConsumePositiveInteger(args);
+  if (!frames)
+    return nullptr;
+
+  int frames_int = frames->GetIntValue();
+  if (frames_int <= 1)
+    return nullptr;
+
+  if (!args.AtEnd())
+    return nullptr;
+
+  range = range_copy;
+  return CSSFramesTimingFunctionValue::Create(frames_int);
+}
+
+CSSValue* ConsumeCubicBezier(CSSParserTokenRange& range) {
+  DCHECK_EQ(range.Peek().FunctionId(), CSSValueCubicBezier);
+  CSSParserTokenRange range_copy = range;
+  CSSParserTokenRange args =
+      CSSPropertyParserHelpers::ConsumeFunction(range_copy);
+
+  double x1, y1, x2, y2;
+  if (CSSPropertyParserHelpers::ConsumeNumberRaw(args, x1) && x1 >= 0 &&
+      x1 <= 1 &&
+      CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args) &&
+      CSSPropertyParserHelpers::ConsumeNumberRaw(args, y1) &&
+      CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args) &&
+      CSSPropertyParserHelpers::ConsumeNumberRaw(args, x2) && x2 >= 0 &&
+      x2 <= 1 &&
+      CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args) &&
+      CSSPropertyParserHelpers::ConsumeNumberRaw(args, y2) && args.AtEnd()) {
+    range = range_copy;
+    return CSSCubicBezierTimingFunctionValue::Create(x1, y1, x2, y2);
+  }
+
+  return nullptr;
+}
+
+}  // namespace
+
+CSSValue*
+CSSPropertyAnimationTimingFunctionUtils::ConsumeAnimationTimingFunction(
+    CSSParserTokenRange& range) {
+  CSSValueID id = range.Peek().Id();
+  if (id == CSSValueEase || id == CSSValueLinear || id == CSSValueEaseIn ||
+      id == CSSValueEaseOut || id == CSSValueEaseInOut ||
+      id == CSSValueStepStart || id == CSSValueStepEnd ||
+      id == CSSValueStepMiddle)
+    return CSSPropertyParserHelpers::ConsumeIdent(range);
+
+  CSSValueID function = range.Peek().FunctionId();
+  if (function == CSSValueSteps)
+    return ConsumeSteps(range);
+  if (RuntimeEnabledFeatures::FramesTimingFunctionEnabled() &&
+      function == CSSValueFrames) {
+    return ConsumeFrames(range);
+  }
+  if (function == CSSValueCubicBezier)
+    return ConsumeCubicBezier(range);
+  return nullptr;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h
new file mode 100644
index 0000000..d067fd98
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h
@@ -0,0 +1,24 @@
+// 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 CSSPropertyAnimationTimingFunctionUtils_h
+#define CSSPropertyAnimationTimingFunctionUtils_h
+
+#include "platform/wtf/Allocator.h"
+
+namespace blink {
+
+class CSSParserTokenRange;
+class CSSValue;
+
+class CSSPropertyAnimationTimingFunctionUtils {
+  STATIC_ONLY(CSSPropertyAnimationTimingFunctionUtils);
+
+ public:
+  static CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange&);
+};
+
+}  // namespace blink
+
+#endif  // CSSPropertyAnimationTimingFunctionUtils_h
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationUtils.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationUtils.cpp
new file mode 100644
index 0000000..7813e85d
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationUtils.cpp
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSPropertyAnimationUtils.h"
+
+#include "core/StylePropertyShorthand.h"
+#include "core/css/CSSInitialValue.h"
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+
+namespace blink {
+
+bool CSSPropertyAnimationUtils::ConsumeAnimationShorthand(
+    const StylePropertyShorthand& shorthand,
+    HeapVector<CSSValueList*, kMaxNumAnimationLonghands>& longhands,
+    ConsumeAnimationItemValue consumeLonghandItem,
+    CSSParserTokenRange& range,
+    const CSSParserContext& context,
+    bool use_legacy_parsing) {
+  DCHECK(consumeLonghandItem);
+  const unsigned longhand_count = shorthand.length();
+  DCHECK_LE(longhand_count, kMaxNumAnimationLonghands);
+
+  for (size_t i = 0; i < longhand_count; ++i)
+    longhands[i] = CSSValueList::CreateCommaSeparated();
+
+  do {
+    bool parsed_longhand[kMaxNumAnimationLonghands] = {false};
+    do {
+      bool found_property = false;
+      for (size_t i = 0; i < longhand_count; ++i) {
+        if (parsed_longhand[i])
+          continue;
+
+        CSSValue* value = consumeLonghandItem(shorthand.properties()[i], range,
+                                              context, use_legacy_parsing);
+        if (value) {
+          parsed_longhand[i] = true;
+          found_property = true;
+          longhands[i]->Append(*value);
+          break;
+        }
+      }
+      if (!found_property)
+        return false;
+    } while (!range.AtEnd() && range.Peek().GetType() != kCommaToken);
+
+    // TODO(timloh): This will make invalid longhands, see crbug.com/386459
+    for (size_t i = 0; i < longhand_count; ++i) {
+      if (!parsed_longhand[i])
+        longhands[i]->Append(*CSSInitialValue::Create());
+      parsed_longhand[i] = false;
+    }
+  } while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(range));
+
+  return true;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationUtils.h b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationUtils.h
new file mode 100644
index 0000000..fd2403b
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationUtils.h
@@ -0,0 +1,41 @@
+// 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 CSSPropertyAnimationUtils_h
+#define CSSPropertyAnimationUtils_h
+
+#include "core/CSSPropertyNames.h"
+#include "platform/heap/HeapAllocator.h"
+#include "platform/wtf/Allocator.h"
+
+namespace blink {
+
+class CSSParserContext;
+class CSSParserTokenRange;
+class CSSValue;
+class CSSValueList;
+class StylePropertyShorthand;
+
+constexpr size_t kMaxNumAnimationLonghands = 8;
+using ConsumeAnimationItemValue = CSSValue* (*)(CSSPropertyID,
+                                                CSSParserTokenRange&,
+                                                const CSSParserContext&,
+                                                bool use_legacy_parsing);
+
+class CSSPropertyAnimationUtils {
+  STATIC_ONLY(CSSPropertyAnimationUtils);
+
+ public:
+  static bool ConsumeAnimationShorthand(
+      const StylePropertyShorthand&,
+      HeapVector<CSSValueList*, kMaxNumAnimationLonghands>&,
+      ConsumeAnimationItemValue,
+      CSSParserTokenRange&,
+      const CSSParserContext&,
+      bool use_legacy_parsing);
+};
+
+}  // namespace blink
+
+#endif  // CSSPropertyAnimationUtils_h
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIAnimation.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIAnimation.cpp
new file mode 100644
index 0000000..c77923d3
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIAnimation.cpp
@@ -0,0 +1,85 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSShorthandPropertyAPIAnimation.h"
+
+#include "core/StylePropertyShorthand.h"
+#include "core/css/CSSIdentifierValue.h"
+#include "core/css/parser/CSSParserContext.h"
+#include "core/css/parser/CSSParserLocalContext.h"
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+#include "core/css/properties/CSSPropertyAnimationIterationCountUtils.h"
+#include "core/css/properties/CSSPropertyAnimationNameUtils.h"
+#include "core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h"
+#include "core/css/properties/CSSPropertyAnimationUtils.h"
+
+namespace blink {
+
+namespace {
+
+// Legacy parsing allows <string>s for animation-name.
+CSSValue* ConsumeAnimationValue(CSSPropertyID property,
+                                CSSParserTokenRange& range,
+                                const CSSParserContext& context,
+                                bool use_legacy_parsing) {
+  switch (property) {
+    case CSSPropertyAnimationDelay:
+      return CSSPropertyParserHelpers::ConsumeTime(range, kValueRangeAll);
+    case CSSPropertyAnimationDirection:
+      return CSSPropertyParserHelpers::ConsumeIdent<
+          CSSValueNormal, CSSValueAlternate, CSSValueReverse,
+          CSSValueAlternateReverse>(range);
+    case CSSPropertyAnimationDuration:
+      return CSSPropertyParserHelpers::ConsumeTime(range,
+                                                   kValueRangeNonNegative);
+    case CSSPropertyAnimationFillMode:
+      return CSSPropertyParserHelpers::ConsumeIdent<
+          CSSValueNone, CSSValueForwards, CSSValueBackwards, CSSValueBoth>(
+          range);
+    case CSSPropertyAnimationIterationCount:
+      return CSSPropertyAnimationIterationCountUtils::
+          ConsumeAnimationIterationCount(range);
+    case CSSPropertyAnimationName:
+      return CSSPropertyAnimationNameUtils::ConsumeAnimationName(
+          range, &context, use_legacy_parsing);
+    case CSSPropertyAnimationPlayState:
+      return CSSPropertyParserHelpers::ConsumeIdent<CSSValueRunning,
+                                                    CSSValuePaused>(range);
+    case CSSPropertyAnimationTimingFunction:
+      return CSSPropertyAnimationTimingFunctionUtils::
+          ConsumeAnimationTimingFunction(range);
+    default:
+      NOTREACHED();
+      return nullptr;
+  }
+}
+
+}  // namespace
+
+bool CSSShorthandPropertyAPIAnimation::parseShorthand(
+    bool important,
+    CSSParserTokenRange& range,
+    const CSSParserContext& context,
+    bool use_legacy_parsing,
+    HeapVector<CSSProperty, 256>& properties) {
+  const StylePropertyShorthand shorthand = animationShorthandForParsing();
+  const unsigned longhand_count = shorthand.length();
+
+  HeapVector<CSSValueList*, kMaxNumAnimationLonghands> longhands(
+      longhand_count);
+  if (!CSSPropertyAnimationUtils::ConsumeAnimationShorthand(
+          shorthand, longhands, ConsumeAnimationValue, range, context,
+          use_legacy_parsing)) {
+    return false;
+  }
+
+  for (size_t i = 0; i < longhand_count; ++i) {
+    CSSPropertyParserHelpers::AddProperty(
+        shorthand.properties()[i], shorthand.id(), *longhands[i], important,
+        CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties);
+  }
+  return range.AtEnd();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITransition.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITransition.cpp
new file mode 100644
index 0000000..cb09dc0
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITransition.cpp
@@ -0,0 +1,76 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSShorthandPropertyAPITransition.h"
+
+#include "core/StylePropertyShorthand.h"
+#include "core/css/CSSIdentifierValue.h"
+#include "core/css/parser/CSSParserContext.h"
+#include "core/css/parser/CSSParserLocalContext.h"
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+#include "core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h"
+#include "core/css/properties/CSSPropertyAnimationUtils.h"
+#include "core/css/properties/CSSPropertyTransitionPropertyUtils.h"
+
+namespace blink {
+
+namespace {
+
+CSSValue* ConsumeTransitionValue(CSSPropertyID property,
+                                 CSSParserTokenRange& range,
+                                 const CSSParserContext&,
+                                 bool use_legacy_parsing) {
+  switch (property) {
+    case CSSPropertyTransitionDelay:
+      return CSSPropertyParserHelpers::ConsumeTime(range, kValueRangeAll);
+    case CSSPropertyTransitionDuration:
+      return CSSPropertyParserHelpers::ConsumeTime(range,
+                                                   kValueRangeNonNegative);
+    case CSSPropertyTransitionProperty:
+      return CSSPropertyTransitionPropertyUtils::ConsumeTransitionProperty(
+          range);
+    case CSSPropertyTransitionTimingFunction:
+      return CSSPropertyAnimationTimingFunctionUtils::
+          ConsumeAnimationTimingFunction(range);
+    default:
+      NOTREACHED();
+      return nullptr;
+  }
+}
+
+}  // namespace
+
+bool CSSShorthandPropertyAPITransition::parseShorthand(
+    bool important,
+    CSSParserTokenRange& range,
+    const CSSParserContext& context,
+    bool use_legacy_parsing,
+    HeapVector<CSSProperty, 256>& properties) {
+  const StylePropertyShorthand shorthand = transitionShorthandForParsing();
+  const unsigned longhand_count = shorthand.length();
+
+  HeapVector<CSSValueList*, kMaxNumAnimationLonghands> longhands(
+      longhand_count);
+  if (!CSSPropertyAnimationUtils::ConsumeAnimationShorthand(
+          shorthand, longhands, ConsumeTransitionValue, range, context,
+          use_legacy_parsing)) {
+    return false;
+  }
+
+  for (size_t i = 0; i < longhand_count; ++i) {
+    if (shorthand.properties()[i] == CSSPropertyTransitionProperty &&
+        !CSSPropertyTransitionPropertyUtils::IsValidPropertyList(*longhands[i]))
+      return false;
+  }
+
+  for (size_t i = 0; i < longhand_count; ++i) {
+    CSSPropertyParserHelpers::AddProperty(
+        shorthand.properties()[i], shorthand.id(), *longhands[i], important,
+        CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties);
+  }
+
+  return range.AtEnd();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 993e77b..b128210c 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -3704,10 +3704,12 @@
 void Document::DidLoadAllScriptBlockingResources() {
   // Use wrapWeakPersistent because the task should not keep this Document alive
   // just for executing scripts.
-  TaskRunnerHelper::Get(TaskType::kNetworking, this)
-      ->PostTask(BLINK_FROM_HERE,
-                 WTF::Bind(&Document::ExecuteScriptsWaitingForResources,
-                           WrapWeakPersistent(this)));
+  execute_scripts_waiting_for_resources_task_handle_ =
+      TaskRunnerHelper::Get(TaskType::kNetworking, this)
+          ->PostCancellableTask(
+              BLINK_FROM_HERE,
+              WTF::Bind(&Document::ExecuteScriptsWaitingForResources,
+                        WrapWeakPersistent(this)));
 
   if (IsHTMLDocument() && body()) {
     // For HTML if we have no more stylesheets to load and we're past the body
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 8d81940..99baff5 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1497,6 +1497,8 @@
   // This is cheaper than making setCompatibilityMode virtual.
   bool compatibility_mode_locked_;
 
+  TaskHandle execute_scripts_waiting_for_resources_task_handle_;
+
   bool has_autofocused_;
   TaskRunnerTimer<Document> clear_focused_element_timer_;
   Member<Element> autofocus_element_;
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
index 7e525d72..e8bae1a0 100644
--- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -37,6 +37,7 @@
 #include "core/frame/FrameConsole.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/LocalFrameClient.h"
+#include "core/inspector/ConsoleMessage.h"
 #include "core/inspector/InspectorNetworkAgent.h"
 #include "core/inspector/InspectorTraceEvents.h"
 #include "core/loader/BaseFetchContext.h"
@@ -380,10 +381,11 @@
           request.Url().Protocol())) {
     probe::documentThreadableLoaderFailedToStartLoadingForClient(GetDocument(),
                                                                  client_);
-    DispatchDidFailAccessControlCheck(ResourceError(
-        kErrorDomainBlinkInternal, 0, request.Url().GetString(),
-        "Cross origin requests are only supported for protocol schemes: " +
-            SchemeRegistry::ListOfCORSEnabledURLSchemes() + "."));
+    DispatchDidFailAccessControlCheck(
+        ResourceError::CancelledDueToAccessCheckError(
+            request.Url(), ResourceRequestBlockedReason::kOther,
+            "Cross origin requests are only supported for protocol schemes: " +
+                SchemeRegistry::ListOfCORSEnabledURLSchemes() + "."));
     return;
   }
 
@@ -394,11 +396,12 @@
           error_message) &&
       request.IsExternalRequest()) {
     DispatchDidFailAccessControlCheck(
-        ResourceError(kErrorDomainBlinkInternal, 0, request.Url().GetString(),
-                      "Requests to internal network resources are not allowed "
-                      "from non-secure contexts (see https://goo.gl/Y0ZkNV). "
-                      "This is an experimental restriction which is part of "
-                      "'https://mikewest.github.io/cors-rfc1918/'."));
+        ResourceError::CancelledDueToAccessCheckError(
+            request.Url(), ResourceRequestBlockedReason::kOrigin,
+            "Requests to internal network resources are not allowed "
+            "from non-secure contexts (see https://goo.gl/Y0ZkNV). "
+            "This is an experimental restriction which is part of "
+            "'https://mikewest.github.io/cors-rfc1918/'."));
     return;
   }
 
@@ -656,9 +659,10 @@
   }
 
   if (!allow_redirect) {
-    DispatchDidFailAccessControlCheck(ResourceError(
-        kErrorDomainBlinkInternal, 0, redirect_response.Url().GetString(),
-        access_control_error_description));
+    DispatchDidFailAccessControlCheck(
+        ResourceError::CancelledDueToAccessCheckError(
+            redirect_response.Url(), ResourceRequestBlockedReason::kOther,
+            access_control_error_description));
     return false;
   }
 
@@ -889,8 +893,9 @@
           builder, CrossOriginAccessControl::kInvalidResponse, response,
           GetSecurityOrigin(), request_context_);
       DispatchDidFailAccessControlCheck(
-          ResourceError(kErrorDomainBlinkInternal, 0,
-                        response.Url().GetString(), builder.ToString()));
+          ResourceError::CancelledDueToAccessCheckError(
+              response.Url(), ResourceRequestBlockedReason::kOther,
+              builder.ToString()));
       return;
     }
 
@@ -924,8 +929,9 @@
           builder, cors_status, response, GetSecurityOrigin(),
           request_context_);
       DispatchDidFailAccessControlCheck(
-          ResourceError(kErrorDomainBlinkInternal, 0,
-                        response.Url().GetString(), builder.ToString()));
+          ResourceError::CancelledDueToAccessCheckError(
+              response.Url(), ResourceRequestBlockedReason::kOther,
+              builder.ToString()));
       return;
     }
   }
@@ -1048,19 +1054,24 @@
 void DocumentThreadableLoader::HandlePreflightFailure(
     const String& url,
     const String& error_description) {
-  ResourceError error(kErrorDomainBlinkInternal, 0, url, error_description);
-
   // Prevent handleSuccessfulFinish() from bypassing access check.
   actual_request_ = ResourceRequest();
 
-  DispatchDidFailAccessControlCheck(error);
+  DispatchDidFailAccessControlCheck(
+      ResourceError::CancelledDueToAccessCheckError(
+          url, ResourceRequestBlockedReason::kOther, error_description));
 }
 
 void DocumentThreadableLoader::DispatchDidFailAccessControlCheck(
     const ResourceError& error) {
+  const String message = "Failed to load " + error.FailingURL() + ": " +
+                         error.LocalizedDescription();
+  loading_context_->GetExecutionContext()->AddConsoleMessage(
+      ConsoleMessage::Create(kJSMessageSource, kErrorMessageLevel, message));
+
   ThreadableLoaderClient* client = client_;
   Clear();
-  client->DidFailAccessControlCheck(error);
+  client->DidFail(error);
 }
 
 void DocumentThreadableLoader::DispatchDidFail(const ResourceError& error) {
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoaderClient.h b/third_party/WebKit/Source/core/loader/ThreadableLoaderClient.h
index 1aea66c..29356b0 100644
--- a/third_party/WebKit/Source/core/loader/ThreadableLoaderClient.h
+++ b/third_party/WebKit/Source/core/loader/ThreadableLoaderClient.h
@@ -59,9 +59,6 @@
   virtual void DidFinishLoading(unsigned long /*identifier*/,
                                 double /*finishTime*/) {}
   virtual void DidFail(const ResourceError&) {}
-  virtual void DidFailAccessControlCheck(const ResourceError& error) {
-    DidFail(error);
-  }
   virtual void DidFailRedirectCheck() {}
   virtual void DidReceiveResourceTiming(const ResourceTimingInfo&) {}
 
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp
index 108af2e..4613a4d3 100644
--- a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp
+++ b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp
@@ -70,7 +70,6 @@
   MOCK_METHOD2(DidReceiveCachedMetadata, void(const char*, int));
   MOCK_METHOD2(DidFinishLoading, void(unsigned long, double));
   MOCK_METHOD1(DidFail, void(const ResourceError&));
-  MOCK_METHOD1(DidFailAccessControlCheck, void(const ResourceError&));
   MOCK_METHOD0(DidFailRedirectCheck, void());
   MOCK_METHOD1(DidReceiveResourceTiming, void(const ResourceTimingInfo&));
   MOCK_METHOD1(DidDownloadData, void(int));
@@ -699,8 +698,8 @@
   EXPECT_CALL(GetCheckpoint(), Call(2));
   EXPECT_CALL(
       *Client(),
-      DidFailAccessControlCheck(ResourceError(
-          kErrorDomainBlinkInternal, 0, SuccessURL().GetString(),
+      DidFail(ResourceError::CancelledDueToAccessCheckError(
+          SuccessURL(), ResourceRequestBlockedReason::kOther,
           "No 'Access-Control-Allow-Origin' header is present on the requested "
           "resource. Origin 'null' is therefore not allowed access.")));
 
@@ -709,36 +708,6 @@
   ServeRequests();
 }
 
-TEST_P(ThreadableLoaderTest, CancelInDidFailAccessControlCheck) {
-  InSequence s;
-  EXPECT_CALL(GetCheckpoint(), Call(1));
-  CreateLoader();
-  CallCheckpoint(1);
-
-  EXPECT_CALL(GetCheckpoint(), Call(2));
-  EXPECT_CALL(*Client(), DidFailAccessControlCheck(_))
-      .WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::CancelLoader));
-
-  StartLoader(SuccessURL(), WebURLRequest::kFetchRequestModeCORS);
-  CallCheckpoint(2);
-  ServeRequests();
-}
-
-TEST_P(ThreadableLoaderTest, ClearInDidFailAccessControlCheck) {
-  InSequence s;
-  EXPECT_CALL(GetCheckpoint(), Call(1));
-  CreateLoader();
-  CallCheckpoint(1);
-
-  EXPECT_CALL(GetCheckpoint(), Call(2));
-  EXPECT_CALL(*Client(), DidFailAccessControlCheck(_))
-      .WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::ClearLoader));
-
-  StartLoader(SuccessURL(), WebURLRequest::kFetchRequestModeCORS);
-  CallCheckpoint(2);
-  ServeRequests();
-}
-
 TEST_P(ThreadableLoaderTest, RedirectDidFinishLoading) {
   InSequence s;
   EXPECT_CALL(GetCheckpoint(), Call(1));
@@ -844,7 +813,7 @@
   CreateLoader();
   CallCheckpoint(1);
 
-  EXPECT_CALL(*Client(), DidFailAccessControlCheck(_));
+  EXPECT_CALL(*Client(), DidFail(_));
   EXPECT_CALL(GetCheckpoint(), Call(2));
 
   // Currently didFailAccessControlCheck is dispatched synchronously. This
diff --git a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
index b5d1466..0fbb3102 100644
--- a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
@@ -391,17 +391,6 @@
   client->DidFail(error);
 }
 
-void WorkerThreadableLoader::DidFailAccessControlCheck(
-    const ResourceError& error) {
-  DCHECK(!IsMainThread());
-  if (!client_)
-    return;
-  auto* client = client_;
-  client_ = nullptr;
-  main_thread_loader_holder_ = nullptr;
-  client->DidFailAccessControlCheck(error);
-}
-
 void WorkerThreadableLoader::DidFailRedirectCheck() {
   DCHECK(!IsMainThread());
   if (!client_)
@@ -605,20 +594,6 @@
   forwarder_ = nullptr;
 }
 
-void WorkerThreadableLoader::MainThreadLoaderHolder::DidFailAccessControlCheck(
-    const ResourceError& error) {
-  DCHECK(IsMainThread());
-  CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
-      worker_loader_.Release();
-  if (!worker_loader || !forwarder_)
-    return;
-  forwarder_->ForwardTaskWithDoneSignal(
-      BLINK_FROM_HERE,
-      CrossThreadBind(&WorkerThreadableLoader::DidFailAccessControlCheck,
-                      worker_loader, error));
-  forwarder_ = nullptr;
-}
-
 void WorkerThreadableLoader::MainThreadLoaderHolder::DidFailRedirectCheck() {
   DCHECK(IsMainThread());
   CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
diff --git a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h
index 5b5acf64a..c221d98 100644
--- a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h
+++ b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h
@@ -165,7 +165,6 @@
     void DidFinishLoading(unsigned long identifier,
                           double finish_time) override;
     void DidFail(const ResourceError&) override;
-    void DidFailAccessControlCheck(const ResourceError&) override;
     void DidFailRedirectCheck() override;
     void DidReceiveResourceTiming(const ResourceTimingInfo&) override;
 
@@ -204,7 +203,6 @@
   void DidReceiveCachedMetadata(std::unique_ptr<Vector<char>> data);
   void DidFinishLoading(unsigned long identifier, double finish_time);
   void DidFail(const ResourceError&);
-  void DidFailAccessControlCheck(const ResourceError&);
   void DidFailRedirectCheck();
   void DidDownloadData(int data_length);
   void DidReceiveResourceTiming(
diff --git a/third_party/WebKit/Source/core/paint/BUILD.gn b/third_party/WebKit/Source/core/paint/BUILD.gn
index 6119167..fafd0630 100644
--- a/third_party/WebKit/Source/core/paint/BUILD.gn
+++ b/third_party/WebKit/Source/core/paint/BUILD.gn
@@ -25,6 +25,8 @@
     "BoxClipper.h",
     "BoxDecorationData.cpp",
     "BoxDecorationData.h",
+    "BoxModelObjectPainter.cpp",
+    "BoxModelObjectPainter.h",
     "BoxPaintInvalidator.cpp",
     "BoxPaintInvalidator.h",
     "BoxPainter.cpp",
diff --git a/third_party/WebKit/Source/core/paint/BoxModelObjectPainter.cpp b/third_party/WebKit/Source/core/paint/BoxModelObjectPainter.cpp
new file mode 100644
index 0000000..2569f7d
--- /dev/null
+++ b/third_party/WebKit/Source/core/paint/BoxModelObjectPainter.cpp
@@ -0,0 +1,366 @@
+// 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 "core/paint/BoxModelObjectPainter.h"
+
+#include "core/layout/BackgroundBleedAvoidance.h"
+#include "core/layout/LayoutBoxModelObject.h"
+#include "core/layout/LayoutObject.h"
+#include "core/layout/line/RootInlineBox.h"
+#include "core/paint/BackgroundImageGeometry.h"
+#include "core/paint/ObjectPainter.h"
+#include "core/paint/PaintInfo.h"
+#include "core/paint/PaintLayer.h"
+#include "platform/geometry/LayoutPoint.h"
+#include "platform/geometry/LayoutRectOutsets.h"
+#include "platform/graphics/GraphicsContextStateSaver.h"
+#include "platform/wtf/Optional.h"
+
+namespace blink {
+
+bool BoxModelObjectPainter::
+    IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+        const LayoutBoxModelObject* box_model_,
+        const PaintInfo& paint_info) {
+  return paint_info.PaintFlags() & kPaintLayerPaintingOverflowContents &&
+         !(paint_info.PaintFlags() &
+           kPaintLayerPaintingCompositingBackgroundPhase) &&
+         box_model_ == paint_info.PaintContainer();
+}
+
+namespace {
+
+class InterpolationQualityContext {
+ public:
+  InterpolationQualityContext(const ComputedStyle& style,
+                              GraphicsContext& context)
+      : context_(context),
+        previous_interpolation_quality_(context.ImageInterpolationQuality()) {
+    interpolation_quality_ = style.GetInterpolationQuality();
+    if (interpolation_quality_ != previous_interpolation_quality_)
+      context.SetImageInterpolationQuality(interpolation_quality_);
+  }
+
+  ~InterpolationQualityContext() {
+    if (interpolation_quality_ != previous_interpolation_quality_)
+      context_.SetImageInterpolationQuality(previous_interpolation_quality_);
+  }
+
+ private:
+  GraphicsContext& context_;
+  InterpolationQuality interpolation_quality_;
+  InterpolationQuality previous_interpolation_quality_;
+};
+
+inline bool PaintFastBottomLayer(const DisplayItemClient& image_client,
+                                 Node* node,
+                                 const PaintInfo& paint_info,
+                                 const BoxPainterBase::FillLayerInfo& info,
+                                 const LayoutRect& rect,
+                                 const FloatRoundedRect& border_rect,
+                                 BackgroundImageGeometry& geometry,
+                                 Image* image,
+                                 SkBlendMode composite_op) {
+  // Painting a background image from an ancestor onto a cell is a complex case.
+  if (geometry.CellUsingContainerBackground())
+    return false;
+  // Complex cases not handled on the fast path.
+  if (!info.is_bottom_layer || !info.is_border_fill ||
+      info.is_clipped_with_local_scrolling)
+    return false;
+
+  // Transparent layer, nothing to paint.
+  if (!info.should_paint_color && !info.should_paint_image)
+    return true;
+
+  // When the layer has an image, figure out whether it is covered by a single
+  // tile.
+  FloatRect image_tile;
+  if (info.should_paint_image) {
+    // Avoid image shaders when printing (poorly supported in PDF).
+    if (info.is_rounded_fill && paint_info.IsPrinting())
+      return false;
+
+    if (!geometry.DestRect().IsEmpty()) {
+      // The tile is too small.
+      if (geometry.TileSize().Width() < rect.Width() ||
+          geometry.TileSize().Height() < rect.Height())
+        return false;
+
+      image_tile = Image::ComputeTileContaining(
+          FloatPoint(geometry.DestRect().Location()),
+          FloatSize(geometry.TileSize()), FloatPoint(geometry.Phase()),
+          FloatSize(geometry.SpaceSize()));
+
+      // The tile is misaligned.
+      if (!image_tile.Contains(FloatRect(rect)))
+        return false;
+    }
+  }
+
+  // At this point we're committed to the fast path: the destination (r)rect
+  // fits within a single tile, and we can paint it using direct draw(R)Rect()
+  // calls.
+  GraphicsContext& context = paint_info.context;
+  FloatRoundedRect border = info.is_rounded_fill
+                                ? border_rect
+                                : FloatRoundedRect(PixelSnappedIntRect(rect));
+  Optional<RoundedInnerRectClipper> clipper;
+  if (info.is_rounded_fill && !border.IsRenderable()) {
+    // When the rrect is not renderable, we resort to clipping.
+    // RoundedInnerRectClipper handles this case via discrete, corner-wise
+    // clipping.
+    clipper.emplace(image_client, paint_info, rect, border, kApplyToContext);
+    border.SetRadii(FloatRoundedRect::Radii());
+  }
+
+  // Paint the color if needed.
+  if (info.should_paint_color)
+    context.FillRoundedRect(border, info.color);
+
+  // Paint the image if needed.
+  if (!info.should_paint_image || image_tile.IsEmpty())
+    return true;
+
+  if (!image)
+    return true;
+
+  const FloatSize intrinsic_tile_size =
+      image->HasRelativeSize() ? image_tile.Size() : FloatSize(image->Size());
+  const FloatRect src_rect = Image::ComputeSubsetForTile(
+      image_tile, border.Rect(), intrinsic_tile_size);
+
+  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage",
+               "data", InspectorPaintImageEvent::Data(node, *info.image));
+  context.DrawImageRRect(image, border, src_rect, composite_op);
+
+  return true;
+}
+
+void PaintFillLayerBackground(GraphicsContext& context,
+                              const BoxPainterBase::FillLayerInfo& info,
+                              Image* image,
+                              SkBlendMode composite_op,
+                              const BackgroundImageGeometry& geometry,
+                              Node* node,
+                              LayoutRect scrolled_paint_rect) {
+  // Paint the color first underneath all images, culled if background image
+  // occludes it.
+  // TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the
+  // culling test by verifying whether the background image covers the entire
+  // painting area.
+  if (info.is_bottom_layer && info.color.Alpha() && info.should_paint_color) {
+    IntRect background_rect(PixelSnappedIntRect(scrolled_paint_rect));
+    context.FillRect(background_rect, info.color);
+  }
+
+  // No progressive loading of the background image.
+  if (info.should_paint_image && !geometry.DestRect().IsEmpty()) {
+    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage",
+                 "data", InspectorPaintImageEvent::Data(node, *info.image));
+    context.DrawTiledImage(image, FloatRect(geometry.DestRect()),
+                           FloatPoint(geometry.Phase()),
+                           FloatSize(geometry.TileSize()), composite_op,
+                           FloatSize(geometry.SpaceSize()));
+  }
+}
+
+void PaintFillLayerTextFillBox(GraphicsContext& context,
+                               const BoxPainterBase::FillLayerInfo& info,
+                               Image* image,
+                               SkBlendMode composite_op,
+                               const BackgroundImageGeometry& geometry,
+                               Node* node,
+                               const LayoutRect& rect,
+                               LayoutRect scrolled_paint_rect,
+                               const LayoutBoxModelObject& box_model_,
+                               const InlineFlowBox* box) {
+  // First figure out how big the mask has to be. It should be no bigger
+  // than what we need to actually render, so we should intersect the dirty
+  // rect with the border box of the background.
+  IntRect mask_rect = PixelSnappedIntRect(rect);
+
+  // We draw the background into a separate layer, to be later masked with
+  // yet another layer holding the text content.
+  GraphicsContextStateSaver background_clip_state_saver(context, false);
+  background_clip_state_saver.Save();
+  context.Clip(mask_rect);
+  context.BeginLayer();
+
+  PaintFillLayerBackground(context, info, image, composite_op, geometry,
+                           box_model_.GeneratingNode(), scrolled_paint_rect);
+
+  // Create the text mask layer and draw the text into the mask. We do this by
+  // painting using a special paint phase that signals to InlineTextBoxes that
+  // they should just add their contents to the clip.
+  context.BeginLayer(1, SkBlendMode::kDstIn);
+  PaintInfo paint_info(context, mask_rect, kPaintPhaseTextClip,
+                       kGlobalPaintNormalPhase, 0);
+  if (box) {
+    const RootInlineBox& root = box->Root();
+    box->Paint(paint_info,
+               LayoutPoint(scrolled_paint_rect.X() - box->X(),
+                           scrolled_paint_rect.Y() - box->Y()),
+               root.LineTop(), root.LineBottom());
+  } else {
+    // FIXME: this should only have an effect for the line box list within
+    // |box_model_|. Change this to create a LineBoxListPainter directly.
+    LayoutSize local_offset = box_model_.IsBox()
+                                  ? ToLayoutBox(&box_model_)->LocationOffset()
+                                  : LayoutSize();
+    box_model_.Paint(paint_info, scrolled_paint_rect.Location() - local_offset);
+  }
+
+  context.EndLayer();  // Text mask layer.
+  context.EndLayer();  // Background layer.
+}
+
+}  // anonymous namespace
+
+LayoutRectOutsets BoxModelObjectPainter::BorderOutsets(
+    const BoxPainterBase::FillLayerInfo& info) const {
+  return LayoutRectOutsets(
+      box_model_.BorderTop(),
+      info.include_right_edge ? box_model_.BorderRight() : LayoutUnit(),
+      box_model_.BorderBottom(),
+      info.include_left_edge ? box_model_.BorderLeft() : LayoutUnit());
+}
+
+LayoutRectOutsets BoxModelObjectPainter::PaddingOutsets(
+    const BoxPainterBase::FillLayerInfo& info) const {
+  return LayoutRectOutsets(
+      box_model_.PaddingTop(),
+      info.include_right_edge ? box_model_.PaddingRight() : LayoutUnit(),
+      box_model_.PaddingBottom(),
+      info.include_left_edge ? box_model_.PaddingLeft() : LayoutUnit());
+}
+
+void BoxModelObjectPainter::PaintFillLayer(
+    const PaintInfo& paint_info,
+    const Color& color,
+    const FillLayer& bg_layer,
+    const LayoutRect& rect,
+    BackgroundBleedAvoidance bleed_avoidance,
+    BackgroundImageGeometry& geometry,
+    const InlineFlowBox* box,
+    const LayoutSize& box_size,
+    SkBlendMode op) {
+  GraphicsContext& context = paint_info.context;
+  if (rect.IsEmpty())
+    return;
+
+  const BoxPainterBase::FillLayerInfo info(
+      box_model_.GetDocument(), box_model_.StyleRef(),
+      box_model_.HasOverflowClip(), color, bg_layer, bleed_avoidance,
+      (box ? box->IncludeLogicalLeftEdge() : true),
+      (box ? box->IncludeLogicalRightEdge() : true));
+
+  bool has_line_box_sibling = box && (box->NextLineBox() || box->PrevLineBox());
+  LayoutRectOutsets border = BorderOutsets(info);
+
+  GraphicsContextStateSaver clip_with_scrolling_state_saver(
+      context, info.is_clipped_with_local_scrolling);
+  LayoutRect scrolled_paint_rect = rect;
+  if (info.is_clipped_with_local_scrolling &&
+      !IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+          &box_model_, paint_info)) {
+    // Clip to the overflow area.
+    const LayoutBox& this_box = ToLayoutBox(box_model_);
+    // TODO(chrishtr): this should be pixel-snapped.
+    context.Clip(FloatRect(this_box.OverflowClipRect(rect.Location())));
+
+    // Adjust the paint rect to reflect a scrolled content box with borders at
+    // the ends.
+    IntSize offset = this_box.ScrolledContentOffset();
+    scrolled_paint_rect.Move(-offset);
+    scrolled_paint_rect.SetWidth(border.Left() + this_box.ScrollWidth() +
+                                 border.Right());
+    scrolled_paint_rect.SetHeight(this_box.BorderTop() +
+                                  this_box.ScrollHeight() +
+                                  this_box.BorderBottom());
+  }
+
+  RefPtr<Image> image;
+  SkBlendMode composite_op = op;
+  Optional<InterpolationQualityContext> interpolation_quality_context;
+  if (info.should_paint_image) {
+    geometry.Calculate(paint_info.PaintContainer(),
+                       paint_info.GetGlobalPaintFlags(), bg_layer,
+                       scrolled_paint_rect);
+    image = info.image->GetImage(
+        geometry.ImageClient(), geometry.ImageDocument(), geometry.ImageStyle(),
+        FlooredIntSize(geometry.TileSize()));
+    interpolation_quality_context.emplace(geometry.ImageStyle(), context);
+
+    if (bg_layer.MaskSourceType() == kMaskLuminance)
+      context.SetColorFilter(kColorFilterLuminanceToAlpha);
+
+    // If op != SkBlendMode::kSrcOver, a mask is being painted.
+    SkBlendMode bg_op = WebCoreCompositeToSkiaComposite(bg_layer.Composite(),
+                                                        bg_layer.BlendMode());
+    composite_op = (op == SkBlendMode::kSrcOver) ? bg_op : op;
+  }
+
+  FloatRoundedRect border_rect = RoundedBorderRectForClip(
+      box_model_.StyleRef(), info, bg_layer, rect, bleed_avoidance,
+      has_line_box_sibling, box_size, box_model_.BorderPaddingInsets());
+
+  // Fast path for drawing simple color backgrounds.
+  if (PaintFastBottomLayer(box_model_, box_model_.GeneratingNode(), paint_info,
+                           info, rect, border_rect, geometry, image.Get(),
+                           composite_op)) {
+    return;
+  }
+
+  Optional<RoundedInnerRectClipper> clip_to_border;
+  if (info.is_rounded_fill) {
+    clip_to_border.emplace(box_model_, paint_info, rect, border_rect,
+                           kApplyToContext);
+  }
+  if (bg_layer.Clip() == kTextFillBox) {
+    PaintFillLayerTextFillBox(context, info, image.Get(), composite_op,
+                              geometry, box_model_.GeneratingNode(), rect,
+                              scrolled_paint_rect, box_model_, box);
+    return;
+  }
+
+  GraphicsContextStateSaver background_clip_state_saver(context, false);
+  switch (bg_layer.Clip()) {
+    case kPaddingFillBox:
+    case kContentFillBox: {
+      if (info.is_rounded_fill)
+        break;
+
+      // Clip to the padding or content boxes as necessary.
+      LayoutRect clip_rect = scrolled_paint_rect;
+      clip_rect.Contract(border);
+      if (bg_layer.Clip() == kContentFillBox)
+        clip_rect.Contract(PaddingOutsets(info));
+      background_clip_state_saver.Save();
+      // TODO(chrishtr): this should be pixel-snapped.
+      context.Clip(FloatRect(clip_rect));
+      break;
+    }
+    case kBorderFillBox:
+      break;
+    case kTextFillBox:  // fall through
+    default:
+      NOTREACHED();
+      break;
+  }
+
+  PaintFillLayerBackground(context, info, image.Get(), composite_op, geometry,
+                           box_model_.GeneratingNode(), scrolled_paint_rect);
+}
+
+Node* BoxModelObjectPainter::GetNode() const {
+  Node* node = nullptr;
+  const LayoutObject* layout_object = &box_model_;
+  for (; layout_object && !node; layout_object = layout_object->Parent()) {
+    node = layout_object->GeneratingNode();
+  }
+  return node;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/BoxModelObjectPainter.h b/third_party/WebKit/Source/core/paint/BoxModelObjectPainter.h
new file mode 100644
index 0000000..95b3f8a
--- /dev/null
+++ b/third_party/WebKit/Source/core/paint/BoxModelObjectPainter.h
@@ -0,0 +1,57 @@
+// 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 BoxModelObjectPainter_h
+#define BoxModelObjectPainter_h
+
+#include "core/layout/BackgroundBleedAvoidance.h"
+#include "core/paint/BoxPainterBase.h"
+#include "core/paint/RoundedInnerRectClipper.h"
+#include "platform/geometry/LayoutSize.h"
+#include "platform/graphics/GraphicsTypes.h"
+#include "platform/wtf/Allocator.h"
+
+namespace blink {
+
+class FillLayer;
+class InlineFlowBox;
+class LayoutRect;
+struct PaintInfo;
+class LayoutBoxModelObject;
+class BackgroundImageGeometry;
+
+// BoxModelObjectPainter is a class that can paint either a LayoutBox or a
+// LayoutInline and allows code sharing between block and inline block painting.
+class BoxModelObjectPainter : public BoxPainterBase {
+  STACK_ALLOCATED();
+
+ public:
+  BoxModelObjectPainter(const LayoutBoxModelObject& box_model)
+      : box_model_(box_model) {}
+
+  void PaintFillLayer(const PaintInfo&,
+                      const Color&,
+                      const FillLayer&,
+                      const LayoutRect&,
+                      BackgroundBleedAvoidance,
+                      BackgroundImageGeometry&,
+                      const InlineFlowBox* = nullptr,
+                      const LayoutSize& = LayoutSize(),
+                      SkBlendMode = SkBlendMode::kSrcOver);
+
+  static bool IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+      const LayoutBoxModelObject*,
+      const PaintInfo&);
+
+ private:
+  Node* GetNode() const;
+  LayoutRectOutsets BorderOutsets(const BoxPainterBase::FillLayerInfo&) const;
+  LayoutRectOutsets PaddingOutsets(const BoxPainterBase::FillLayerInfo&) const;
+
+  const LayoutBoxModelObject& box_model_;
+};
+
+}  // namespace blink
+
+#endif  // BoxModelObjectPainter_h
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.cpp b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
index b22a424..67ba419 100644
--- a/third_party/WebKit/Source/core/paint/BoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
@@ -4,23 +4,16 @@
 
 #include "core/paint/BoxPainter.h"
 
-#include "core/HTMLNames.h"
-#include "core/frame/LocalFrame.h"
-#include "core/frame/LocalFrameView.h"
-#include "core/frame/Settings.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/layout/BackgroundBleedAvoidance.h"
 #include "core/layout/LayoutBox.h"
-#include "core/layout/LayoutBoxModelObject.h"
 #include "core/layout/LayoutObject.h"
 #include "core/layout/LayoutTable.h"
 #include "core/layout/LayoutTheme.h"
 #include "core/layout/compositing/CompositedLayerMapping.h"
-#include "core/layout/line/RootInlineBox.h"
-#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
 #include "core/paint/BackgroundImageGeometry.h"
 #include "core/paint/BoxDecorationData.h"
+#include "core/paint/BoxModelObjectPainter.h"
 #include "core/paint/LayoutObjectDrawingRecorder.h"
 #include "core/paint/NinePieceImagePainter.h"
 #include "core/paint/ObjectPainter.h"
@@ -31,22 +24,11 @@
 #include "core/style/ShadowList.h"
 #include "platform/LengthFunctions.h"
 #include "platform/geometry/LayoutPoint.h"
-#include "platform/geometry/LayoutRectOutsets.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
-#include "platform/graphics/paint/CompositingDisplayItem.h"
 #include "platform/wtf/Optional.h"
 
 namespace blink {
 
-bool BoxPainter::IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
-    const LayoutBoxModelObject* obj,
-    const PaintInfo& paint_info) {
-  return paint_info.PaintFlags() & kPaintLayerPaintingOverflowContents &&
-         !(paint_info.PaintFlags() &
-           kPaintLayerPaintingCompositingBackgroundPhase) &&
-         obj == paint_info.PaintContainer();
-}
-
 void BoxPainter::Paint(const PaintInfo& paint_info,
                        const LayoutPoint& paint_offset) {
   ObjectPainter(layout_box_).CheckPaintOffset(paint_info, paint_offset);
@@ -66,8 +48,9 @@
                                               const LayoutPoint& paint_offset) {
   LayoutRect paint_rect;
   Optional<ScrollRecorder> scroll_recorder;
-  if (IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
-          &layout_box_, paint_info)) {
+  if (BoxModelObjectPainter::
+          IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+              &layout_box_, paint_info)) {
     // For the case where we are painting the background into the scrolling
     // contents layer of a composited scroller we need to include the entire
     // overflow rect.
@@ -91,8 +74,9 @@
     const PaintInfo& paint_info,
     const LayoutPoint& adjusted_paint_offset) {
   LayoutRect bounds =
-      IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
-          &layout_box_, paint_info)
+      BoxModelObjectPainter::
+              IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+                  &layout_box_, paint_info)
           ? layout_box_.LayoutOverflowRect()
           : layout_box_.SelfVisualOverflowRect();
   bounds.MoveBy(adjusted_paint_offset);
@@ -103,15 +87,17 @@
     const PaintInfo& paint_info,
     const LayoutPoint& paint_offset,
     const LayoutRect& paint_rect) {
-  bool painting_overflow_contents =
+  bool painting_overflow_contents = BoxModelObjectPainter::
       IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
           &layout_box_, paint_info);
+  const ComputedStyle& style = layout_box_.StyleRef();
+
   Optional<DisplayItemCacheSkipper> cache_skipper;
   // Disable cache in under-invalidation checking mode for MediaSliderPart
   // because we always paint using the latest data (buffered ranges, current
   // time and duration) which may be different from the cached data.
   if ((RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() &&
-       layout_box_.StyleRef().Appearance() == kMediaSliderPart)
+       style.Appearance() == kMediaSliderPart)
       // We may paint a delayed-invalidation object before it's actually
       // invalidated. Note this would be handled for us by
       // LayoutObjectDrawingRecorder but we have to use DrawingRecorder as we
@@ -143,12 +129,11 @@
     // FIXME: Should eventually give the theme control over whether the box
     // shadow should paint, since controls could have custom shadows of their
     // own.
-    PaintNormalBoxShadow(paint_info, paint_rect, layout_box_.StyleRef());
+    PaintNormalBoxShadow(paint_info, paint_rect, style);
 
     if (BleedAvoidanceIsClipping(box_decoration_data.bleed_avoidance)) {
       state_saver.Save();
-      FloatRoundedRect border =
-          layout_box_.StyleRef().GetRoundedBorderFor(paint_rect);
+      FloatRoundedRect border = style.GetRoundedBorderFor(paint_rect);
       paint_info.context.ClipRoundedRect(border);
 
       if (box_decoration_data.bleed_avoidance == kBackgroundBleedClipLayer)
@@ -178,7 +163,7 @@
   }
 
   if (!painting_overflow_contents) {
-    PaintInsetBoxShadow(paint_info, paint_rect, layout_box_.StyleRef());
+    PaintInsetBoxShadow(paint_info, paint_rect, style);
 
     // The theme will tell us whether or not we should also paint the CSS
     // border.
@@ -190,8 +175,7 @@
         !(layout_box_.IsTable() &&
           ToLayoutTable(&layout_box_)->ShouldCollapseBorders())) {
       PaintBorder(layout_box_, layout_box_.GetDocument(), GetNode(), paint_info,
-                  paint_rect, layout_box_.StyleRef(),
-                  box_decoration_data.bleed_avoidance);
+                  paint_rect, style, box_decoration_data.bleed_avoidance);
     }
   }
 
@@ -235,332 +219,17 @@
   if (should_draw_background_in_separate_buffer)
     context.BeginLayer();
 
+  BoxModelObjectPainter box_model_painter(layout_box_);
   for (auto it = reversed_paint_list.rbegin(); it != reversed_paint_list.rend();
        ++it) {
-    PaintFillLayer(layout_box_, paint_info, c, **it, rect, bleed_avoidance,
-                   geometry, 0, LayoutSize(), op);
+    box_model_painter.PaintFillLayer(paint_info, c, **it, rect, bleed_avoidance,
+                                     geometry, 0, LayoutSize(), op);
   }
 
   if (should_draw_background_in_separate_buffer)
     context.EndLayer();
 }
 
-namespace {
-
-class InterpolationQualityContext {
- public:
-  InterpolationQualityContext(const ComputedStyle& style,
-                              GraphicsContext& context)
-      : context_(context),
-        previous_interpolation_quality_(context.ImageInterpolationQuality()) {
-    interpolation_quality_ = style.GetInterpolationQuality();
-    if (interpolation_quality_ != previous_interpolation_quality_)
-      context.SetImageInterpolationQuality(interpolation_quality_);
-  }
-
-  ~InterpolationQualityContext() {
-    if (interpolation_quality_ != previous_interpolation_quality_)
-      context_.SetImageInterpolationQuality(previous_interpolation_quality_);
-  }
-
- private:
-  GraphicsContext& context_;
-  InterpolationQuality interpolation_quality_;
-  InterpolationQuality previous_interpolation_quality_;
-};
-
-inline bool PaintFastBottomLayer(const DisplayItemClient& image_client,
-                                 Node* node,
-                                 const PaintInfo& paint_info,
-                                 const BoxPainterBase::FillLayerInfo& info,
-                                 const LayoutRect& rect,
-                                 const FloatRoundedRect& border_rect,
-                                 BackgroundImageGeometry& geometry,
-                                 Image* image,
-                                 SkBlendMode composite_op) {
-  // Painting a background image from an ancestor onto a cell is a complex case.
-  if (geometry.CellUsingContainerBackground())
-    return false;
-  // Complex cases not handled on the fast path.
-  if (!info.is_bottom_layer || !info.is_border_fill ||
-      info.is_clipped_with_local_scrolling)
-    return false;
-
-  // Transparent layer, nothing to paint.
-  if (!info.should_paint_color && !info.should_paint_image)
-    return true;
-
-  // When the layer has an image, figure out whether it is covered by a single
-  // tile.
-  FloatRect image_tile;
-  if (info.should_paint_image) {
-    // Avoid image shaders when printing (poorly supported in PDF).
-    if (info.is_rounded_fill && paint_info.IsPrinting())
-      return false;
-
-    if (!geometry.DestRect().IsEmpty()) {
-      // The tile is too small.
-      if (geometry.TileSize().Width() < rect.Width() ||
-          geometry.TileSize().Height() < rect.Height())
-        return false;
-
-      image_tile = Image::ComputeTileContaining(
-          FloatPoint(geometry.DestRect().Location()),
-          FloatSize(geometry.TileSize()), FloatPoint(geometry.Phase()),
-          FloatSize(geometry.SpaceSize()));
-
-      // The tile is misaligned.
-      if (!image_tile.Contains(FloatRect(rect)))
-        return false;
-    }
-  }
-
-  // At this point we're committed to the fast path: the destination (r)rect
-  // fits within a single tile, and we can paint it using direct draw(R)Rect()
-  // calls.
-  GraphicsContext& context = paint_info.context;
-  FloatRoundedRect border = info.is_rounded_fill
-                                ? border_rect
-                                : FloatRoundedRect(PixelSnappedIntRect(rect));
-  Optional<RoundedInnerRectClipper> clipper;
-  if (info.is_rounded_fill && !border.IsRenderable()) {
-    // When the rrect is not renderable, we resort to clipping.
-    // RoundedInnerRectClipper handles this case via discrete, corner-wise
-    // clipping.
-    clipper.emplace(image_client, paint_info, rect, border, kApplyToContext);
-    border.SetRadii(FloatRoundedRect::Radii());
-  }
-
-  // Paint the color if needed.
-  if (info.should_paint_color)
-    context.FillRoundedRect(border, info.color);
-
-  // Paint the image if needed.
-  if (!info.should_paint_image || image_tile.IsEmpty())
-    return true;
-
-  if (!image)
-    return true;
-
-  const FloatSize intrinsic_tile_size =
-      image->HasRelativeSize() ? image_tile.Size() : FloatSize(image->Size());
-  const FloatRect src_rect = Image::ComputeSubsetForTile(
-      image_tile, border.Rect(), intrinsic_tile_size);
-
-  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage",
-               "data", InspectorPaintImageEvent::Data(node, *info.image));
-  context.DrawImageRRect(image, border, src_rect, composite_op);
-
-  return true;
-}
-
-void PaintFillLayerBackground(GraphicsContext& context,
-                              const BoxPainterBase::FillLayerInfo& info,
-                              Image* image,
-                              SkBlendMode composite_op,
-                              const BackgroundImageGeometry& geometry,
-                              Node* node,
-                              LayoutRect scrolled_paint_rect) {
-  // Paint the color first underneath all images, culled if background image
-  // occludes it.
-  // TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the
-  // culling test by verifying whether the background image covers the entire
-  // painting area.
-  if (info.is_bottom_layer && info.color.Alpha() && info.should_paint_color) {
-    IntRect background_rect(PixelSnappedIntRect(scrolled_paint_rect));
-    context.FillRect(background_rect, info.color);
-  }
-
-  // No progressive loading of the background image.
-  if (info.should_paint_image && !geometry.DestRect().IsEmpty()) {
-    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage",
-                 "data", InspectorPaintImageEvent::Data(node, *info.image));
-    context.DrawTiledImage(image, FloatRect(geometry.DestRect()),
-                           FloatPoint(geometry.Phase()),
-                           FloatSize(geometry.TileSize()), composite_op,
-                           FloatSize(geometry.SpaceSize()));
-  }
-}
-
-void PaintFillLayerTextFillBox(GraphicsContext& context,
-                               const BoxPainterBase::FillLayerInfo& info,
-                               Image* image,
-                               SkBlendMode composite_op,
-                               const BackgroundImageGeometry& geometry,
-                               Node* node,
-                               const LayoutRect& rect,
-                               LayoutRect scrolled_paint_rect,
-                               const LayoutBoxModelObject& obj,
-                               const InlineFlowBox* box) {
-  // First figure out how big the mask has to be. It should be no bigger
-  // than what we need to actually render, so we should intersect the dirty
-  // rect with the border box of the background.
-  IntRect mask_rect = PixelSnappedIntRect(rect);
-
-  // We draw the background into a separate layer, to be later masked with
-  // yet another layer holding the text content.
-  GraphicsContextStateSaver background_clip_state_saver(context, false);
-  background_clip_state_saver.Save();
-  context.Clip(mask_rect);
-  context.BeginLayer();
-
-  PaintFillLayerBackground(context, info, image, composite_op, geometry,
-                           obj.GeneratingNode(), scrolled_paint_rect);
-
-  // Create the text mask layer and draw the text into the mask. We do this by
-  // painting using a special paint phase that signals to InlineTextBoxes that
-  // they should just add their contents to the clip.
-  context.BeginLayer(1, SkBlendMode::kDstIn);
-  PaintInfo paint_info(context, mask_rect, kPaintPhaseTextClip,
-                       kGlobalPaintNormalPhase, 0);
-  if (box) {
-    const RootInlineBox& root = box->Root();
-    box->Paint(paint_info,
-               LayoutPoint(scrolled_paint_rect.X() - box->X(),
-                           scrolled_paint_rect.Y() - box->Y()),
-               root.LineTop(), root.LineBottom());
-  } else {
-    // FIXME: this should only have an effect for the line box list within
-    // |obj|. Change this to create a LineBoxListPainter directly.
-    LayoutSize local_offset =
-        obj.IsBox() ? ToLayoutBox(&obj)->LocationOffset() : LayoutSize();
-    obj.Paint(paint_info, scrolled_paint_rect.Location() - local_offset);
-  }
-
-  context.EndLayer();  // Text mask layer.
-  context.EndLayer();  // Background layer.
-}
-
-}  // anonymous namespace
-
-void BoxPainter::PaintFillLayer(const LayoutBoxModelObject& obj,
-                                const PaintInfo& paint_info,
-                                const Color& color,
-                                const FillLayer& bg_layer,
-                                const LayoutRect& rect,
-                                BackgroundBleedAvoidance bleed_avoidance,
-                                BackgroundImageGeometry& geometry,
-                                const InlineFlowBox* box,
-                                const LayoutSize& box_size,
-                                SkBlendMode op) {
-  GraphicsContext& context = paint_info.context;
-  if (rect.IsEmpty())
-    return;
-
-  const BoxPainterBase::FillLayerInfo info(
-      obj.GetDocument(), obj.StyleRef(), obj.HasOverflowClip(), color, bg_layer,
-      bleed_avoidance, (box ? box->IncludeLogicalLeftEdge() : true),
-      (box ? box->IncludeLogicalRightEdge() : true));
-
-  bool has_line_box_sibling = box && (box->NextLineBox() || box->PrevLineBox());
-  LayoutRectOutsets border(
-      obj.BorderTop(),
-      info.include_right_edge ? obj.BorderRight() : LayoutUnit(),
-      obj.BorderBottom(),
-      info.include_left_edge ? obj.BorderLeft() : LayoutUnit());
-
-  GraphicsContextStateSaver clip_with_scrolling_state_saver(
-      context, info.is_clipped_with_local_scrolling);
-  LayoutRect scrolled_paint_rect = rect;
-  if (info.is_clipped_with_local_scrolling &&
-      !IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
-          &obj, paint_info)) {
-    // Clip to the overflow area.
-    const LayoutBox& this_box = ToLayoutBox(obj);
-    // TODO(chrishtr): this should be pixel-snapped.
-    context.Clip(FloatRect(this_box.OverflowClipRect(rect.Location())));
-
-    // Adjust the paint rect to reflect a scrolled content box with borders at
-    // the ends.
-    IntSize offset = this_box.ScrolledContentOffset();
-    scrolled_paint_rect.Move(-offset);
-    scrolled_paint_rect.SetWidth(border.Left() + this_box.ScrollWidth() +
-                                 border.Right());
-    scrolled_paint_rect.SetHeight(this_box.BorderTop() +
-                                  this_box.ScrollHeight() +
-                                  this_box.BorderBottom());
-  }
-
-  RefPtr<Image> image;
-  SkBlendMode composite_op = op;
-  Optional<InterpolationQualityContext> interpolation_quality_context;
-  if (info.should_paint_image) {
-    geometry.Calculate(paint_info.PaintContainer(),
-                       paint_info.GetGlobalPaintFlags(), bg_layer,
-                       scrolled_paint_rect);
-    image = info.image->GetImage(
-        geometry.ImageClient(), geometry.ImageDocument(), geometry.ImageStyle(),
-        FlooredIntSize(geometry.TileSize()));
-    interpolation_quality_context.emplace(geometry.ImageStyle(), context);
-
-    if (bg_layer.MaskSourceType() == kMaskLuminance)
-      context.SetColorFilter(kColorFilterLuminanceToAlpha);
-
-    // If op != SkBlendMode::kSrcOver, a mask is being painted.
-    SkBlendMode bg_op = WebCoreCompositeToSkiaComposite(bg_layer.Composite(),
-                                                        bg_layer.BlendMode());
-    composite_op = (op == SkBlendMode::kSrcOver) ? bg_op : op;
-  }
-
-  FloatRoundedRect border_rect =
-      info.is_rounded_fill
-          ? RoundedBorderRectForClip(obj.StyleRef(), info, bg_layer, rect,
-                                     bleed_avoidance, has_line_box_sibling,
-                                     box_size, obj.BorderPaddingInsets())
-          : FloatRoundedRect();
-
-  // Fast path for drawing simple color backgrounds.
-  if (PaintFastBottomLayer(obj, obj.GeneratingNode(), paint_info, info, rect,
-                           border_rect, geometry, image.Get(), composite_op)) {
-    return;
-  }
-
-  Optional<RoundedInnerRectClipper> clip_to_border;
-  if (info.is_rounded_fill)
-    clip_to_border.emplace(obj, paint_info, rect, border_rect, kApplyToContext);
-
-  if (bg_layer.Clip() == kTextFillBox) {
-    PaintFillLayerTextFillBox(context, info, image.Get(), composite_op,
-                              geometry, obj.GeneratingNode(), rect,
-                              scrolled_paint_rect, obj, box);
-    return;
-  }
-
-  GraphicsContextStateSaver background_clip_state_saver(context, false);
-  switch (bg_layer.Clip()) {
-    case kPaddingFillBox:
-    case kContentFillBox: {
-      if (info.is_rounded_fill)
-        break;
-
-      // Clip to the padding or content boxes as necessary.
-      LayoutRect clip_rect = scrolled_paint_rect;
-      clip_rect.Contract(border);
-      if (bg_layer.Clip() == kContentFillBox) {
-        LayoutRectOutsets padding(
-            obj.PaddingTop(),
-            info.include_right_edge ? obj.PaddingRight() : LayoutUnit(),
-            obj.PaddingBottom(),
-            info.include_left_edge ? obj.PaddingLeft() : LayoutUnit());
-        clip_rect.Contract(padding);
-      }
-      background_clip_state_saver.Save();
-      // TODO(chrishtr): this should be pixel-snapped.
-      context.Clip(FloatRect(clip_rect));
-      break;
-    }
-    case kBorderFillBox:
-      break;
-    case kTextFillBox:  // fall through
-    default:
-      NOTREACHED();
-      break;
-  }
-
-  PaintFillLayerBackground(context, info, image.Get(), composite_op, geometry,
-                           obj.GeneratingNode(), scrolled_paint_rect);
-}
-
 void BoxPainter::PaintMask(const PaintInfo& paint_info,
                            const LayoutPoint& paint_offset) {
   if (layout_box_.Style()->Visibility() != EVisibility::kVisible ||
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.h b/third_party/WebKit/Source/core/paint/BoxPainter.h
index eb82e04..acf2901 100644
--- a/third_party/WebKit/Source/core/paint/BoxPainter.h
+++ b/third_party/WebKit/Source/core/paint/BoxPainter.h
@@ -15,12 +15,10 @@
 namespace blink {
 
 class FillLayer;
-class InlineFlowBox;
 class LayoutPoint;
 class LayoutRect;
 struct PaintInfo;
 class LayoutBox;
-class LayoutBoxModelObject;
 class BackgroundImageGeometry;
 
 class BoxPainter : public BoxPainterBase {
@@ -46,23 +44,9 @@
   void PaintBoxDecorationBackgroundWithRect(const PaintInfo&,
                                             const LayoutPoint&,
                                             const LayoutRect&);
-  static void PaintFillLayer(const LayoutBoxModelObject&,
-                             const PaintInfo&,
-                             const Color&,
-                             const FillLayer&,
-                             const LayoutRect&,
-                             BackgroundBleedAvoidance,
-                             BackgroundImageGeometry&,
-                             const InlineFlowBox* = nullptr,
-                             const LayoutSize& = LayoutSize(),
-                             SkBlendMode = SkBlendMode::kSrcOver);
   LayoutRect BoundsForDrawingRecorder(const PaintInfo&,
                                       const LayoutPoint& adjusted_paint_offset);
 
-  static bool IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
-      const LayoutBoxModelObject*,
-      const PaintInfo&);
-
  private:
   void PaintBackground(const PaintInfo&,
                        const LayoutRect&,
diff --git a/third_party/WebKit/Source/core/paint/BoxPainterBase.cpp b/third_party/WebKit/Source/core/paint/BoxPainterBase.cpp
index 996ea46..5d3820d 100644
--- a/third_party/WebKit/Source/core/paint/BoxPainterBase.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxPainterBase.cpp
@@ -358,6 +358,9 @@
     bool has_line_box_sibling,
     const LayoutSize& box_size,
     LayoutRectOutsets border_padding_insets) {
+  if (!info.is_rounded_fill)
+    return FloatRoundedRect();
+
   FloatRoundedRect border =
       info.is_border_fill
           ? BackgroundRoundedRectAdjustedForBleedAvoidance(
diff --git a/third_party/WebKit/Source/core/paint/InlineFlowBoxPainter.cpp b/third_party/WebKit/Source/core/paint/InlineFlowBoxPainter.cpp
index 8c3e80bda..7ae3538 100644
--- a/third_party/WebKit/Source/core/paint/InlineFlowBoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/InlineFlowBoxPainter.cpp
@@ -7,6 +7,7 @@
 #include "core/layout/api/LineLayoutAPIShim.h"
 #include "core/layout/line/RootInlineBox.h"
 #include "core/paint/BackgroundImageGeometry.h"
+#include "core/paint/BoxModelObjectPainter.h"
 #include "core/paint/BoxPainter.h"
 #include "core/paint/NinePieceImagePainter.h"
 #include "core/paint/PaintInfo.h"
@@ -81,21 +82,22 @@
   BackgroundImageGeometry geometry(*box_model);
   StyleImage* img = fill_layer.GetImage();
   bool has_fill_image = img && img->CanRender();
+  BoxModelObjectPainter box_model_painter(*box_model);
   if ((!has_fill_image &&
        !inline_flow_box_.GetLineLayoutItem().Style()->HasBorderRadius()) ||
       (!inline_flow_box_.PrevLineBox() && !inline_flow_box_.NextLineBox()) ||
       !inline_flow_box_.Parent()) {
-    BoxPainter::PaintFillLayer(*box_model, paint_info, c, fill_layer, rect,
-                               kBackgroundBleedNone, geometry,
-                               &inline_flow_box_, rect.Size(), op);
+    box_model_painter.PaintFillLayer(paint_info, c, fill_layer, rect,
+                                     kBackgroundBleedNone, geometry,
+                                     &inline_flow_box_, rect.Size(), op);
   } else if (inline_flow_box_.GetLineLayoutItem()
                  .Style()
                  ->BoxDecorationBreak() == EBoxDecorationBreak::kClone) {
     GraphicsContextStateSaver state_saver(paint_info.context);
     paint_info.context.Clip(PixelSnappedIntRect(rect));
-    BoxPainter::PaintFillLayer(*box_model, paint_info, c, fill_layer, rect,
-                               kBackgroundBleedNone, geometry,
-                               &inline_flow_box_, rect.Size(), op);
+    box_model_painter.PaintFillLayer(paint_info, c, fill_layer, rect,
+                                     kBackgroundBleedNone, geometry,
+                                     &inline_flow_box_, rect.Size(), op);
   } else {
     // We have a fill image that spans multiple lines.
     // FIXME: frameSize ought to be the same as rect.size().
@@ -106,9 +108,9 @@
     GraphicsContextStateSaver state_saver(paint_info.context);
     // TODO(chrishtr): this should likely be pixel-snapped.
     paint_info.context.Clip(PixelSnappedIntRect(rect));
-    BoxPainter::PaintFillLayer(*box_model, paint_info, c, fill_layer,
-                               image_strip_paint_rect, kBackgroundBleedNone,
-                               geometry, &inline_flow_box_, rect.Size(), op);
+    box_model_painter.PaintFillLayer(
+        paint_info, c, fill_layer, image_strip_paint_rect, kBackgroundBleedNone,
+        geometry, &inline_flow_box_, rect.Size(), op);
   }
 }
 
diff --git a/third_party/WebKit/Source/core/paint/MediaControlsPainter.cpp b/third_party/WebKit/Source/core/paint/MediaControlsPainter.cpp
index 41170e5e..9c418f77 100644
--- a/third_party/WebKit/Source/core/paint/MediaControlsPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/MediaControlsPainter.cpp
@@ -20,7 +20,7 @@
  * 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 CONTRACTg, STRICT LIABILITY, OR TORT
+ * 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/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
index 9ee9c82..8408f9f 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -582,11 +582,6 @@
                                                 FloatRoundedRect(mask_clip));
         local_clip_added_or_removed |= result.NewNodeCreated();
         output_clip = properties.MaskClip();
-
-        // TODO(crbug.com/683425): PaintArtifactCompositor does not handle
-        // grouping (i.e. descendant-dependent compositing reason) properly
-        // yet. This forces masked subtree always create a layer for now.
-        compositing_reasons |= kCompositingReasonIsolateCompositedDescendants;
       } else {
         force_subtree_update |= properties.ClearMaskClip();
       }
@@ -607,15 +602,10 @@
               object.UniqueId(), CompositorElementIdNamespace::kPrimary));
       force_subtree_update |= result.NewNodeCreated();
       if (has_mask) {
-        // TODO(crbug.com/683425): PaintArtifactCompositor does not handle
-        // grouping (i.e. descendant-dependent compositing reason) properly
-        // yet. Adding CompositingReasonSquashingDisallowed forces mask not
-        // getting squashed into a child effect. Have no compositing reason
-        // otherwise.
         auto result = properties.UpdateMask(
             properties.Effect(), context.current.transform, output_clip,
             mask_color_filter, CompositorFilterOperations(), 1.f,
-            SkBlendMode::kDstIn, kCompositingReasonSquashingDisallowed,
+            SkBlendMode::kDstIn, kCompositingReasonNone,
             CompositorElementIdFromLayoutObjectId(
                 object.UniqueId(), CompositorElementIdNamespace::kEffectMask));
         force_subtree_update |= result.NewNodeCreated();
diff --git a/third_party/WebKit/Source/core/paint/ViewPainter.cpp b/third_party/WebKit/Source/core/paint/ViewPainter.cpp
index ef48b2e..8597c23 100644
--- a/third_party/WebKit/Source/core/paint/ViewPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ViewPainter.cpp
@@ -11,6 +11,7 @@
 #include "core/layout/compositing/CompositedLayerMapping.h"
 #include "core/paint/BackgroundImageGeometry.h"
 #include "core/paint/BlockPainter.h"
+#include "core/paint/BoxModelObjectPainter.h"
 #include "core/paint/BoxPainter.h"
 #include "core/paint/LayoutObjectDrawingRecorder.h"
 #include "core/paint/PaintInfo.h"
@@ -67,7 +68,7 @@
   const DisplayItemClient* display_item_client = &layout_view_;
 
   Optional<ScrollRecorder> scroll_recorder;
-  if (BoxPainter::
+  if (BoxModelObjectPainter::
           IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
               &layout_view_, paint_info)) {
     // Layout overflow, combined with the visible content size.
@@ -211,6 +212,7 @@
   }
 
   BackgroundImageGeometry geometry(layout_view_);
+  BoxModelObjectPainter box_model_painter(layout_view_);
   for (auto it = reversed_paint_list.rbegin(); it != reversed_paint_list.rend();
        ++it) {
     DCHECK((*it)->Clip() == kBorderFillBox);
@@ -218,17 +220,17 @@
     bool should_paint_in_viewport_space =
         (*it)->Attachment() == kFixedBackgroundAttachment;
     if (should_paint_in_viewport_space) {
-      BoxPainter::PaintFillLayer(layout_view_, paint_info, Color(), **it,
-                                 LayoutRect(LayoutRect::InfiniteIntRect()),
-                                 kBackgroundBleedNone, geometry);
+      box_model_painter.PaintFillLayer(
+          paint_info, Color(), **it, LayoutRect(LayoutRect::InfiniteIntRect()),
+          kBackgroundBleedNone, geometry);
     } else {
       context.Save();
       // TODO(trchen): We should be able to handle 3D-transformed root
       // background with slimming paint by using transform display items.
       context.ConcatCTM(transform.ToAffineTransform());
-      BoxPainter::PaintFillLayer(layout_view_, paint_info, Color(), **it,
-                                 LayoutRect(paint_rect), kBackgroundBleedNone,
-                                 geometry);
+      box_model_painter.PaintFillLayer(paint_info, Color(), **it,
+                                       LayoutRect(paint_rect),
+                                       kBackgroundBleedNone, geometry);
       context.Restore();
     }
   }
diff --git a/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h b/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
index 58493f303..d9b38ba5 100644
--- a/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
+++ b/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
@@ -59,26 +59,32 @@
                                     SourceLocation*) {}
   virtual void PostMessageToPageInspector(int session_id, const String&) {}
 
-  // Invoked when the new WorkerGlobalScope is created. This is called after
-  // didLoadWorkerScript().
+  // Invoked when the new WorkerGlobalScope is created on
+  // WorkerThread::InitializeOnWorkerThread.
   virtual void DidCreateWorkerGlobalScope(WorkerOrWorkletGlobalScope*) {}
 
-  // Invoked when the WorkerGlobalScope is initialized. This is called after
-  // didCreateWorkerGlobalScope().
+  // Invoked when the WorkerGlobalScope is initialized on
+  // WorkerThread::InitializeOnWorkerThread.
   virtual void DidInitializeWorkerContext() {}
 
-  // Invoked when the worker script is about to be evaluated. This is called
-  // after didInitializeWorkerContext().
+  // Invoked when the worker's main script is loaded on
+  // WorkerThread::InitializeOnWorkerThread. Only invoked when the script was
+  // loaded on the worker thread, i.e., via InstalledScriptsManager rather than
+  // via ResourceLoader.
+  virtual void DidLoadInstalledScript() {}
+
+  // Invoked when the worker script is about to be evaluated on
+  // WorkerThread::InitializeOnWorkerThread.
   virtual void WillEvaluateWorkerScript(size_t script_size,
                                         size_t cached_metadata_size) {}
 
-  // Invoked when an imported script is about to be evaluated. This is called
-  // after willEvaluateWorkerScript().
+  // Invoked when an imported script is about to be evaluated.
   virtual void WillEvaluateImportedScript(size_t script_size,
                                           size_t cached_metadata_size) {}
 
-  // Invoked when the worker script is evaluated. |success| is true if the
-  // evaluation completed with no uncaught exception.
+  // Invoked when the worker script is evaluated on
+  // WorkerThread::InitializeOnWorkerThread. |success| is true if the evaluation
+  // completed with no uncaught exception.
   virtual void DidEvaluateWorkerScript(bool success) {}
 
   // Invoked when close() is invoked on the worker context.
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
index b47f4891..aa4aed9b 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -453,12 +453,15 @@
     // OriginTrialTokens to |startup_data|.
     // TODO(shimazu): Add a post task to the main thread for setting
     // ContentSecurityPolicy and ReferrerPolicy.
+
+    // GetScriptData blocks until the script is received from the browser.
     auto script_data = GetInstalledScriptsManager()->GetScriptData(script_url);
     DCHECK(script_data);
     DCHECK(source_code.IsEmpty());
     DCHECK(!cached_meta_data);
     source_code = std::move(script_data->source_text);
     cached_meta_data = std::move(script_data->meta_data);
+    worker_reporting_proxy_.DidLoadInstalledScript();
   } else {
     source_code = std::move(given_source_code);
     cached_meta_data = std::move(given_cached_meta_data);
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
index 4d2efab..235ce67 100644
--- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
+++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
@@ -1491,8 +1491,6 @@
   if (!final_type.IsEmpty())
     return final_type;
 
-  // FIXME: This fallback is not specified in the final MIME type algorithm
-  // of the XHR spec. Move this to more appropriate place.
   return AtomicString("text/xml");
 }
 
@@ -1656,11 +1654,8 @@
   if (!file_path.IsEmpty() && length_downloaded_to_file_) {
     blob_data->AppendFile(file_path, 0, length_downloaded_to_file_,
                           InvalidFileTime());
-    // FIXME: finalResponseMIMETypeWithFallback() defaults to
-    // text/xml which may be incorrect. Replace it with
-    // finalResponseMIMEType() after compatibility investigation.
-    blob_data->SetContentType(FinalResponseMIMETypeWithFallback().LowerASCII());
   }
+  blob_data->SetContentType(FinalResponseMIMETypeWithFallback().LowerASCII());
   return BlobDataHandle::Create(std::move(blob_data),
                                 length_downloaded_to_file_);
 }
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index eb3bdaf..c1827848 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -127,7 +127,6 @@
   "front_end/common/Trie.js",
   "front_end/common/UIString.js",
   "front_end/common/Worker.js",
-  "front_end/components/DataSaverInfobar.js",
   "front_end/components/DockController.js",
   "front_end/components/domBreakpointsSidebarPane.css",
   "front_end/components/DOMBreakpointsSidebarPane.js",
@@ -254,6 +253,9 @@
   "front_end/gonzales/gonzales-scss.js",
   "front_end/gonzales/module.json",
   "front_end/gonzales/SCSSParser.js",
+  "front_end/har_importer/HARFormat.js",
+  "front_end/har_importer/HARImporter.js",
+  "front_end/har_importer/module.json",
   "front_end/heap_snapshot_model/HeapSnapshotModel.js",
   "front_end/heap_snapshot_model/module.json",
   "front_end/heap_snapshot_worker.js",
@@ -902,6 +904,7 @@
   "$resources_out_dir/elements/elements_module.js",
   "$resources_out_dir/event_listeners/event_listeners_module.js",
   "$resources_out_dir/formatter/formatter_module.js",
+  "$resources_out_dir/har_importer/har_importer_module.js",
   "$resources_out_dir/heap_snapshot_model/heap_snapshot_model_module.js",
   "$resources_out_dir/inline_editor/inline_editor_module.js",
   "$resources_out_dir/layer_viewer/layer_viewer_module.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/Runtime.js b/third_party/WebKit/Source/devtools/front_end/Runtime.js
index 32b192d..b3123ed4 100644
--- a/third_party/WebKit/Source/devtools/front_end/Runtime.js
+++ b/third_party/WebKit/Source/devtools/front_end/Runtime.js
@@ -737,6 +737,7 @@
       'ui': 'UI',
       'object_ui': 'ObjectUI',
       'perf_ui': 'PerfUI',
+      'har_importer': 'HARImporter',
     };
     var namespace = specialCases[this._name] || this._name.split('_').map(a => a.substring(0, 1).toUpperCase() + a.substring(1)).join('');
     self[namespace] = self[namespace] || {};
diff --git a/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js b/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js
index 4124bdb..48d7d106 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js
@@ -45,6 +45,33 @@
   }
 
   /**
+   * @param {?string} mimeType
+   * @return {!Common.ResourceType}
+   */
+  static fromMimeType(mimeType) {
+    var contentTypeAndTopLevelType = mimeType.match(/(\w*)\/\w*/);
+    if (!contentTypeAndTopLevelType)
+      return Common.resourceTypes.Other;
+
+    var resourceType = Common.ResourceType._resourceTypeByMimeType.get(contentTypeAndTopLevelType[0]);
+    if (resourceType)
+      return resourceType;
+
+    resourceType = Common.ResourceType._resourceTypeByMimeType.get(contentTypeAndTopLevelType[1]);
+    if (resourceType)
+      return resourceType;
+    return Common.resourceTypes.Other;
+  }
+
+  /**
+   * @param {string} url
+   * @return {?Common.ResourceType}
+   */
+  static fromURL(url) {
+    return Common.ResourceType._resourceTypeByExtension.get(Common.ParsedURL.extractExtension(url)) || null;
+  }
+
+  /**
    * @param {string} url
    * @return {string|undefined}
    */
@@ -206,6 +233,21 @@
   ['Cakefile', 'text/x-coffeescript']
 ]);
 
+Common.ResourceType._resourceTypeByExtension = new Map([
+  ['js', Common.resourceTypes.Script],
+
+  ['css', Common.resourceTypes.Stylesheet], ['xsl', Common.resourceTypes.Stylesheet],
+
+  ['jpeg', Common.resourceTypes.Image], ['jpg', Common.resourceTypes.Image], ['svg', Common.resourceTypes.Image],
+  ['gif', Common.resourceTypes.Image], ['png', Common.resourceTypes.Image], ['ico', Common.resourceTypes.Image],
+  ['tiff', Common.resourceTypes.Image], ['tif', Common.resourceTypes.Image], ['bmp', Common.resourceTypes.Image],
+
+  ['webp', Common.resourceTypes.Media],
+
+  ['ttf', Common.resourceTypes.Font], ['otf', Common.resourceTypes.Font], ['ttc', Common.resourceTypes.Font],
+  ['woff', Common.resourceTypes.Font]
+]);
+
 Common.ResourceType._mimeTypeByExtension = new Map([
   // Web extensions
   ['js', 'text/javascript'], ['css', 'text/css'], ['html', 'text/html'], ['htm', 'text/html'],
@@ -273,3 +315,15 @@
   // Font
   ['ttf', 'font/opentype'], ['otf', 'font/opentype'], ['ttc', 'font/opentype'], ['woff', 'application/font-woff']
 ]);
+
+Common.ResourceType._resourceTypeByMimeType = new Map([
+  // Web types
+  ['text/javascript', Common.resourceTypes.Script], ['text/css', Common.resourceTypes.Stylesheet],
+  ['text/html', Common.resourceTypes.Document],
+
+  // Image
+  ['image', Common.resourceTypes.Image],
+
+  // Font
+  ['font', Common.resourceTypes.Font], ['application/font-woff', Common.resourceTypes.Font]
+]);
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/components/DataSaverInfobar.js b/third_party/WebKit/Source/devtools/front_end/components/DataSaverInfobar.js
deleted file mode 100644
index 2de8315..0000000
--- a/third_party/WebKit/Source/devtools/front_end/components/DataSaverInfobar.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Components.DataSaverInfobar = class extends UI.Infobar {
-  constructor() {
-    super(
-        UI.Infobar.Type.Warning, Common.UIString('Consider disabling Chrome Data Saver while debugging.'),
-        Common.settings.moduleSetting('disableDataSaverInfobar'));
-    var message = this.createDetailsRowMessage();
-    message.createTextChild('More information about  ');
-    message.appendChild(UI.createExternalLink(
-        'https://support.google.com/chrome/answer/2392284?hl=en', Common.UIString('Chrome Data Saver')));
-    message.createTextChild('.');
-  }
-
-  /**
-   * @param {!UI.Panel} panel
-   */
-  static maybeShowInPanel(panel) {
-    if (Runtime.queryParam('remoteFrontend')) {
-      var infobar = new Components.DataSaverInfobar();
-      Components.DataSaverInfobar._infobars.push(infobar);
-      panel.showInfobar(infobar);
-    }
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    for (var infobar of Components.DataSaverInfobar._infobars)
-      UI.Infobar.prototype.dispose.call(infobar);
-  }
-};
-
-Components.DataSaverInfobar._infobars = [];
diff --git a/third_party/WebKit/Source/devtools/front_end/components/module.json b/third_party/WebKit/Source/devtools/front_end/components/module.json
index f7ffb0a5..03a5e3a 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/components/module.json
@@ -47,7 +47,6 @@
         "network_log"
     ],
     "scripts": [
-        "DataSaverInfobar.js",
         "DOMBreakpointsSidebarPane.js",
         "DOMPresentationUtils.js",
         "DockController.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/har_importer/HARFormat.js b/third_party/WebKit/Source/devtools/front_end/har_importer/HARFormat.js
new file mode 100644
index 0000000..fb0eb0f
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/har_importer/HARFormat.js
@@ -0,0 +1,315 @@
+// 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.
+
+HARImporter.HARBase = class {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    if (!data || typeof data !== 'object')
+      throw 'First parameter is expected to be an object';
+  }
+
+  /**
+   * @param {*} data
+   * @return {!Date}
+   */
+  static _safeDate(data) {
+    var date = new Date(data);
+    if (!Number.isNaN(date.getTime()))
+      return date;
+    throw 'Invalid date format';
+  }
+
+  /**
+   * @param {*} data
+   * @return {number}
+   */
+  static _safeNumber(data) {
+    var result = Number(data);
+    if (!Number.isNaN(result))
+      return result;
+    throw 'Casting to number results in NaN';
+  }
+
+  /**
+   * @param {*} data
+   * @return {number|undefined}
+   */
+  static _optionalNumber(data) {
+    return data !== undefined ? HARImporter.HARBase._safeNumber(data) : undefined;
+  }
+
+  /**
+   * @param {*} data
+   * @return {string|undefined}
+   */
+  static _optionalString(data) {
+    return data !== undefined ? String(data) : undefined;
+  }
+
+  /**
+   * @param {string} name
+   * @return {string|undefined}
+   */
+  customAsString(name) {
+    // Har specification says starting with '_' is a custom property, but closure uses '_' as a private property.
+    var value = /** @type {!Object} */ (this)['_' + name];
+    return value !== undefined ? String(value) : undefined;
+  }
+
+  /**
+   * @param {string} name
+   * @return {number|undefined}
+   */
+  customAsNumber(name) {
+    // Har specification says starting with '_' is a custom property, but closure uses '_' as a private property.
+    var value = /** @type {!Object} */ (this)['_' + name];
+    if (value === undefined)
+      return;
+    value = Number(value);
+    if (Number.isNaN(value))
+      return;
+    return value;
+  }
+};
+
+// Using any of these classes may throw.
+HARImporter.HARRoot = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.log = new HARImporter.HARLog(data['log']);
+  }
+};
+
+HARImporter.HARLog = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.version = String(data['version']);
+    this.creator = new HARImporter.HARCreator(data['creator']);
+    this.browser = data['browser'] ? new HARImporter.HARCreator(data['browser']) : undefined;
+    this.pages = Array.isArray(data['pages']) ? data['pages'].map(page => new HARImporter.HARPage(page)) : [];
+    if (!Array.isArray(data['entries']))
+      throw 'log.entries is expected to be an array';
+    this.entries = data['entries'].map(entry => new HARImporter.HAREntry(entry));
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARCreator = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.name = String(data['name']);
+    this.version = String(data['version']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARPage = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.startedDateTime = HARImporter.HARBase._safeDate(data['startedDateTime']);
+    this.id = String(data['id']);
+    this.title = String(data['title']);
+    this.pageTimings = new HARImporter.HARPageTimings(data['pageTimings']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARPageTimings = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.onContentLoad = HARImporter.HARBase._optionalNumber(data['onContentLoad']);
+    this.onLoad = HARImporter.HARBase._optionalNumber(data['onLoad']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HAREntry = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.pageref = HARImporter.HARBase._optionalString(data['pageref']);
+    this.startedDateTime = HARImporter.HARBase._safeDate(data['startedDateTime']);
+    this.time = HARImporter.HARBase._safeNumber(data['time']);
+    this.request = new HARImporter.HARRequest(data['request']);
+    this.response = new HARImporter.HARResponse(data['response']);
+    this.cache = {};  // Not yet implemented.
+    this.timings = new HARImporter.HARTimings(data['timings']);
+    this.serverIPAddress = HARImporter.HARBase._optionalString(data['serverIPAddress']);
+    this.connection = HARImporter.HARBase._optionalString(data['connection']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+
+    // Chrome specific.
+    this._fromCache = HARImporter.HARBase._optionalString(data['_fromCache']);
+  }
+};
+
+HARImporter.HARRequest = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.method = String(data['method']);
+    this.url = String(data['url']);
+    this.httpVersion = String(data['httpVersion']);
+    this.cookies =
+        Array.isArray(data['cookies']) ? data['cookies'].map(cookie => new HARImporter.HARCookie(cookie)) : [];
+    this.headers =
+        Array.isArray(data['headers']) ? data['headers'].map(header => new HARImporter.HARHeader(header)) : [];
+    this.queryString =
+        Array.isArray(data['queryString']) ? data['queryString'].map(qs => new HARImporter.HARQueryString(qs)) : [];
+    this.postData = data['postData'] ? new HARImporter.HARPostData(data['postData']) : undefined;
+    this.headersSize = HARImporter.HARBase._safeNumber(data['headersSize']);
+    this.bodySize = HARImporter.HARBase._safeNumber(data['bodySize']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARResponse = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.status = HARImporter.HARBase._safeNumber(data['status']);
+    this.statusText = String(data['statusText']);
+    this.httpVersion = String(data['httpVersion']);
+    this.cookies =
+        Array.isArray(data['cookies']) ? data['cookies'].map(cookie => new HARImporter.HARCookie(cookie)) : [];
+    this.headers =
+        Array.isArray(data['headers']) ? data['headers'].map(header => new HARImporter.HARHeader(header)) : [];
+    this.content = new HARImporter.HARContent(data['content']);
+    this.redirectURL = String(data['redirectURL']);
+    this.headersSize = HARImporter.HARBase._safeNumber(data['headersSize']);
+    this.bodySize = HARImporter.HARBase._safeNumber(data['bodySize']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+
+    // Chrome specific.
+    this._transferSize = HARImporter.HARBase._optionalNumber(data['_transferSize']);
+    this._error = HARImporter.HARBase._optionalString(data['_error']);
+  }
+};
+
+HARImporter.HARCookie = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.name = String(data['name']);
+    this.value = String(data['value']);
+    this.path = HARImporter.HARBase._optionalString(data['path']);
+    this.domain = HARImporter.HARBase._optionalString(data['domain']);
+    this.expires = data['expires'] ? HARImporter.HARBase._safeDate(data['expires']) : undefined;
+    this.httpOnly = data['httpOnly'] !== undefined ? !!data['httpOnly'] : undefined;
+    this.secure = data['secure'] !== undefined ? !!data['secure'] : undefined;
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARHeader = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.name = String(data['name']);
+    this.value = String(data['value']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARQueryString = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.name = String(data['name']);
+    this.value = String(data['value']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARPostData = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.mimeType = String(data['mimeType']);
+    this.params = Array.isArray(data['params']) ? data['params'].map(param => new HARImporter.HARParam(param)) : [];
+    this.text = String(data['text']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARParam = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.name = String(data['name']);
+    this.value = HARImporter.HARBase._optionalString(data['value']);
+    this.fileName = HARImporter.HARBase._optionalString(data['fileName']);
+    this.contentType = HARImporter.HARBase._optionalString(data['contentType']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARContent = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.size = HARImporter.HARBase._safeNumber(data['size']);
+    this.compression = HARImporter.HARBase._optionalNumber(data['compression']);
+    this.mimeType = String(data['mimeType']);
+    this.text = HARImporter.HARBase._optionalString(data['text']);
+    this.encoding = HARImporter.HARBase._optionalString(data['encoding']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+  }
+};
+
+HARImporter.HARTimings = class extends HARImporter.HARBase {
+  /**
+   * @param {*} data
+   */
+  constructor(data) {
+    super(data);
+    this.blocked = HARImporter.HARBase._optionalNumber(data['blocked']);
+    this.dns = HARImporter.HARBase._optionalNumber(data['dns']);
+    this.connect = HARImporter.HARBase._optionalNumber(data['connect']);
+    this.send = HARImporter.HARBase._safeNumber(data['send']);
+    this.wait = HARImporter.HARBase._safeNumber(data['wait']);
+    this.receive = HARImporter.HARBase._safeNumber(data['receive']);
+    this.ssl = HARImporter.HARBase._optionalNumber(data['ssl']);
+    this.comment = HARImporter.HARBase._optionalString(data['comment']);
+
+    // Chrome specific.
+    this._blocked_queueing = HARImporter.HARBase._optionalNumber(data['_blocked_queueing']);
+    this._blocked_proxy = HARImporter.HARBase._optionalNumber(data['_blocked_proxy']);
+  }
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/har_importer/HARImporter.js b/third_party/WebKit/Source/devtools/front_end/har_importer/HARImporter.js
new file mode 100644
index 0000000..7a940210
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/har_importer/HARImporter.js
@@ -0,0 +1,170 @@
+// 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.
+
+HARImporter.Importer = class {
+  /**
+   * @param {!HARImporter.HARLog} log
+   * @return {!Array<!SDK.NetworkRequest>}
+   */
+  static requestsFromHARLog(log) {
+    /** @type {!Map<string, !HARImporter.HARPage>} */
+    var pages = new Map();
+    for (var page of log.pages)
+      pages.set(page.id, page);
+
+    log.entries.sort((a, b) => a.startedDateTime - b.startedDateTime);
+
+    /** @type {!Map<string, !NetworkLog.PageLoad>} */
+    var pageLoads = new Map();
+    /** @type {!Array<!SDK.NetworkRequest>} */
+    var requests = [];
+    for (var entry of log.entries) {
+      var pageLoad = pageLoads.get(entry.pageref);
+      var documentURL = pageLoad ? pageLoad.mainRequest.url() : entry.request.url;
+      var request = new SDK.NetworkRequest('har-' + requests.length, entry.request.url, documentURL, '', '', null);
+      var page = pages.get(entry.pageref);
+      if (!pageLoad && page) {
+        pageLoad = HARImporter.Importer._buildPageLoad(page, request);
+        pageLoads.set(entry.pageref, pageLoad);
+      }
+      HARImporter.Importer._fillRequestFromHAREntry(request, entry, pageLoad);
+      if (pageLoad)
+        pageLoad.bindRequest(request);
+      requests.push(request);
+    }
+    return requests;
+  }
+
+  /**
+   * @param {!HARImporter.HARPage} page
+   * @param {!SDK.NetworkRequest} mainRequest
+   * @return {!NetworkLog.PageLoad}
+   */
+  static _buildPageLoad(page, mainRequest) {
+    var pageLoad = new NetworkLog.PageLoad(mainRequest);
+    pageLoad.startTime = page.startedDateTime;
+    pageLoad.contentLoadTime = page.pageTimings.onContentLoad * 1000;
+    pageLoad.loadTime = page.pageTimings.onLoad * 1000;
+    return pageLoad;
+  }
+
+  /**
+   * @param {!SDK.NetworkRequest} request
+   * @param {!HARImporter.HAREntry} entry
+   * @param {?NetworkLog.PageLoad} pageLoad
+   */
+  static _fillRequestFromHAREntry(request, entry, pageLoad) {
+    // Request data.
+    if (entry.request.postData)
+      request.requestFormData = entry.request.postData.text;
+    request.connectionId = entry.connection || '';
+    request.requestMethod = entry.request.method;
+    request.setRequestHeaders(entry.request.headers);
+
+    // Response data.
+    if (entry.response.content.mimeType && entry.response.content.mimeType !== 'x-unknown')
+      request.mimeType = entry.response.content.mimeType;
+    request.responseHeaders = entry.response.headers;
+    request.statusCode = entry.response.status;
+    request.statusText = entry.response.statusText;
+    var protocol = entry.response.httpVersion.toLowerCase();
+    if (protocol === 'http/2.0')
+      protocol = 'h2';
+    request.protocol = protocol.replace(/^http\/2\.0?\+quic/, 'http/2+quic');
+
+    // Timing data.
+    var issueTime = entry.startedDateTime.getTime() / 1000;
+    request.setIssueTime(issueTime, issueTime);
+
+    // Content data.
+    var contentSize = entry.response.content.size > 0 ? entry.response.content.size : 0;
+    var headersSize = entry.response.headersSize > 0 ? entry.response.headersSize : 0;
+    var bodySize = entry.response.bodySize > 0 ? entry.response.bodySize : 0;
+    request.resourceSize = contentSize || (headersSize + bodySize);
+    var transferSize = entry.response.customAsNumber('transferSize');
+    if (transferSize === undefined)
+      transferSize = entry.response.headersSize + entry.response.bodySize;
+    request.setTransferSize(transferSize >= 0 ? transferSize : 0);
+
+    var fromCache = entry.customAsString('fromCache');
+    if (fromCache === 'memory')
+      request.setFromMemoryCache();
+    else if (fromCache === 'disk')
+      request.setFromDiskCache();
+
+    var contentData = {error: null, content: null, encoded: entry.response.content.encoding === 'base64'};
+    if (entry.response.content.text !== undefined)
+      contentData.content = entry.response.content.text;
+    request.setContentData(contentData);
+
+    // Timing data.
+    HARImporter.Importer._setupTiming(request, issueTime, entry.time, entry.timings);
+
+    // Meta data.
+    request.setRemoteAddress(entry.serverIPAddress || '', 80);  // Har does not support port numbers.
+    var resourceType = (pageLoad && pageLoad.mainRequest === request) ?
+        Common.resourceTypes.Document :
+        Common.ResourceType.fromMimeType(entry.response.content.mimeType);
+    if (!resourceType)
+      resourceType = Common.ResourceType.fromURL(entry.request.url) || Common.resourceTypes.Other;
+    request.setResourceType(resourceType);
+
+    request.finished = true;
+  }
+
+  /**
+   * @param {!SDK.NetworkRequest} request
+   * @param {number} issueTime
+   * @param {number} entryTotalDuration
+   * @param {!HARImporter.HARTimings} timings
+   */
+  static _setupTiming(request, issueTime, entryTotalDuration, timings) {
+    /**
+     * @param {number|undefined} timing
+     * @return {number}
+     */
+    function accumulateTime(timing) {
+      if (timing === undefined || timing < 0)
+        return -1;
+      lastEntry += timing;
+      return lastEntry;
+    }
+    var lastEntry = timings.blocked >= 0 ? timings.blocked : 0;
+
+    var proxy = timings.customAsNumber('blocked_proxy') || -1;
+    var queueing = timings.customAsNumber('blocked_queueing') || -1;
+
+    // SSL is part of connect for both HAR and Chrome's format so subtract it here.
+    var ssl = timings.ssl >= 0 ? timings.ssl : 0;
+    if (timings.connect > 0)
+      timings.connect -= ssl;
+    var timing = {
+      proxyStart: proxy > 0 ? lastEntry - proxy : -1,
+      proxyEnd: proxy > 0 ? lastEntry : -1,
+      requestTime: issueTime + (queueing > 0 ? queueing : 0) / 1000,
+      dnsStart: timings.dns >= 0 ? lastEntry : -1,
+      dnsEnd: accumulateTime(timings.dns),
+
+      // Add ssl to end time without modifying lastEntry (see comment above).
+      connectStart: timings.connect >= 0 ? lastEntry : -1,
+      connectEnd: accumulateTime(timings.connect) + ssl,
+
+      // Now update lastEntry to add ssl timing back in (see comment above).
+      sslStart: timings.ssl >= 0 ? lastEntry : -1,
+      sslEnd: accumulateTime(timings.ssl),
+
+      workerStart: -1,
+      workerReady: -1,
+      sendStart: timings.send >= 0 ? lastEntry : -1,
+      sendEnd: accumulateTime(timings.send),
+      pushStart: 0,
+      pushEnd: 0,
+      receiveHeadersEnd: accumulateTime(timings.wait)
+    };
+    accumulateTime(timings.receive);
+
+    request.timing = timing;
+    request.endTime = issueTime + Math.max(entryTotalDuration, lastEntry) / 1000;
+  }
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/har_importer/module.json b/third_party/WebKit/Source/devtools/front_end/har_importer/module.json
new file mode 100644
index 0000000..007d9aad
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/har_importer/module.json
@@ -0,0 +1,11 @@
+{
+    "dependencies": [
+        "common",
+        "network_log",
+        "sdk"
+    ],
+    "scripts": [
+        "HARFormat.js",
+        "HARImporter.js"
+    ]
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/inspector.json b/third_party/WebKit/Source/devtools/front_end/inspector.json
index ad011bc4..b79af4fb 100644
--- a/third_party/WebKit/Source/devtools/front_end/inspector.json
+++ b/third_party/WebKit/Source/devtools/front_end/inspector.json
@@ -17,6 +17,7 @@
         { "name": "services", "type": "autostart" },
         { "name": "elements", "condition": "!v8only" },
         { "name": "network", "condition": "!v8only" },
+        { "name": "har_importer", "condition": "!v8only" },
         { "name": "sources" },
         { "name": "timeline", "condition": "!v8only" },
         { "name": "timeline_model", "condition": "!v8only" },
diff --git a/third_party/WebKit/Source/devtools/front_end/integration_test_runner.json b/third_party/WebKit/Source/devtools/front_end/integration_test_runner.json
index 3e3dc51a..0cdd95a8 100644
--- a/third_party/WebKit/Source/devtools/front_end/integration_test_runner.json
+++ b/third_party/WebKit/Source/devtools/front_end/integration_test_runner.json
@@ -16,6 +16,7 @@
     { "name": "host", "type": "autostart" },
     { "name": "common", "type": "autostart" },
     { "name": "emulation", "type": "autostart" },
+    { "name": "har_importer", "condition": "!v8only" },
     { "name": "workspace", "type": "autostart" },
     { "name": "bindings", "type": "autostart" },
     { "name": "persistence", "type": "autostart" },
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
index 5764ffc0..7a281d3 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
@@ -108,6 +108,9 @@
     this._resetSuggestionBuilder();
     this._initializeView();
 
+    new UI.DropTarget(
+        this.element, [UI.DropTarget.Types.Files], Common.UIString('Drop HAR files here'), this._handleDrop.bind(this));
+
     Common.moduleSetting('networkColorCodeResourceTypes')
         .addChangeListener(this._invalidateAllItems.bind(this, false), this);
 
@@ -382,6 +385,48 @@
   }
 
   /**
+   * @param {!DataTransfer} dataTransfer
+   */
+  _handleDrop(dataTransfer) {
+    var items = dataTransfer.items;
+    if (!items.length)
+      return;
+    var entry = items[0].webkitGetAsEntry();
+    if (entry.isDirectory)
+      return;
+
+    entry.file(this._onLoadFromFile.bind(this));
+  }
+
+  /**
+   * @param {!File} file
+   */
+  async _onLoadFromFile(file) {
+    var outputStream = new Common.StringOutputStream();
+    var reader = new Bindings.ChunkedFileReader(file, /* chunkSize */ 10000000);
+    var success = await reader.read(outputStream);
+    if (!success) {
+      this._harLoadFailed(reader.error().message);
+      return;
+    }
+    try {
+      // HARRoot and JSON.parse might throw.
+      var harRoot = new HARImporter.HARRoot(JSON.parse(outputStream.data()));
+    } catch (e) {
+      this._harLoadFailed(e);
+      return;
+    }
+    NetworkLog.networkLog.importRequests(HARImporter.Importer.requestsFromHARLog(harRoot.log));
+  }
+
+  /**
+   * @param {string} message
+   */
+  _harLoadFailed(message) {
+    Common.console.error('Failed to load HAR file with following error: ' + message);
+  }
+
+  /**
    * @param {?string} groupKey
    */
   _setGrouping(groupKey) {
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
index ccecb2c..c3c291ae 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
@@ -119,8 +119,6 @@
     NetworkLog.networkLog.addEventListener(NetworkLog.NetworkLog.Events.RequestAdded, this._onUpdateRequest, this);
     NetworkLog.networkLog.addEventListener(NetworkLog.NetworkLog.Events.RequestUpdated, this._onUpdateRequest, this);
     NetworkLog.networkLog.addEventListener(NetworkLog.NetworkLog.Events.Reset, this._onNetworkLogReset, this);
-
-    Components.DataSaverInfobar.maybeShowInPanel(this);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js b/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js
index 25f63fb..f59605c 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js
@@ -148,20 +148,23 @@
     if (issueTime < startTime)
       addRange(Network.RequestTimeRangeNames.Queueing, issueTime, startTime);
 
+    var responseReceived = (request.responseReceivedTime - startTime) * 1000;
     if (request.fetchedViaServiceWorker) {
       addOffsetRange(Network.RequestTimeRangeNames.Blocking, 0, timing.workerStart);
       addOffsetRange(Network.RequestTimeRangeNames.ServiceWorkerPreparation, timing.workerStart, timing.workerReady);
       addOffsetRange(Network.RequestTimeRangeNames.ServiceWorker, timing.workerReady, timing.sendEnd);
-      addOffsetRange(Network.RequestTimeRangeNames.Waiting, timing.sendEnd, timing.receiveHeadersEnd);
+      addOffsetRange(Network.RequestTimeRangeNames.Waiting, timing.sendEnd, responseReceived);
     } else if (!timing.pushStart) {
-      var blocking = firstPositive([timing.dnsStart, timing.connectStart, timing.sendStart]) || 0;
-      addOffsetRange(Network.RequestTimeRangeNames.Blocking, 0, blocking);
+      var blockingEnd = firstPositive([timing.dnsStart, timing.connectStart, timing.sendStart, responseReceived]) || 0;
+      addOffsetRange(Network.RequestTimeRangeNames.Blocking, 0, blockingEnd);
       addOffsetRange(Network.RequestTimeRangeNames.Proxy, timing.proxyStart, timing.proxyEnd);
       addOffsetRange(Network.RequestTimeRangeNames.DNS, timing.dnsStart, timing.dnsEnd);
       addOffsetRange(Network.RequestTimeRangeNames.Connecting, timing.connectStart, timing.connectEnd);
       addOffsetRange(Network.RequestTimeRangeNames.SSL, timing.sslStart, timing.sslEnd);
       addOffsetRange(Network.RequestTimeRangeNames.Sending, timing.sendStart, timing.sendEnd);
-      addOffsetRange(Network.RequestTimeRangeNames.Waiting, timing.sendEnd, timing.receiveHeadersEnd);
+      addOffsetRange(
+          Network.RequestTimeRangeNames.Waiting,
+          Math.max(timing.sendEnd, timing.connectEnd, timing.dnsEnd, timing.proxyEnd, blockingEnd), responseReceived);
     }
 
     if (request.endTime !== -1) {
diff --git a/third_party/WebKit/Source/devtools/front_end/network/module.json b/third_party/WebKit/Source/devtools/front_end/network/module.json
index 8ea43af..3f822eb2 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/network/module.json
@@ -122,6 +122,7 @@
         "network_log",
         "product_registry",
         "mobile_throttling",
+        "har_importer",
         "network_priorities"
     ],
     "scripts": [
diff --git a/third_party/WebKit/Source/devtools/front_end/network_log/HAREntry.js b/third_party/WebKit/Source/devtools/front_end/network_log/HAREntry.js
index 8fbc832..8cf0c1b 100644
--- a/third_party/WebKit/Source/devtools/front_end/network_log/HAREntry.js
+++ b/third_party/WebKit/Source/devtools/front_end/network_log/HAREntry.js
@@ -61,16 +61,25 @@
     if (portPositionInString !== -1)
       ipAddress = ipAddress.substr(0, portPositionInString);
 
+    var timings = this._buildTimings();
+    // "ssl" is included in the connect field, so do not double count it.
+    var time = timings.blocked + timings.dns + timings.connect + timings.send + timings.wait + timings.receive;
+
     var entry = {
-      startedDateTime: NetworkLog.HARLog.pseudoWallTime(this._request, this._request.startTime),
-      time: this._request.timing ? NetworkLog.HAREntry._toMilliseconds(this._request.duration) : 0,
+      startedDateTime: NetworkLog.HARLog.pseudoWallTime(this._request, this._request.issueTime()),
+      time: time,
       request: this._buildRequest(),
       response: this._buildResponse(),
       cache: {},  // Not supported yet.
-      timings: this._buildTimings(),
-      serverIPAddress: ipAddress
+      timings: timings,
+      // IPv6 address should not have square brackets per (https://tools.ietf.org/html/rfc2373#section-2.2).
+      serverIPAddress: ipAddress.replace(/\[\]/g, '')
     };
 
+    // Chrome specific.
+    if (this._request.cached())
+      entry._fromCache = this._request.cachedInMemory() ? 'memory' : 'disk';
+
     if (this._request.connectionId !== '0')
       entry.connection = this._request.connectionId;
     var page = NetworkLog.PageLoad.forRequest(this._request);
@@ -136,43 +145,79 @@
   }
 
   /**
-   * @return {!Object}
+   * @return {!NetworkLog.HAREntry.Timing}
    */
   _buildTimings() {
-    // Order of events: request_start = 0, [proxy], [dns], [connect [ssl]], [send], receive_headers_end
-    // HAR 'blocked' time is time before first network activity.
-
+    // Order of events: request_start = 0, [proxy], [dns], [connect [ssl]], [send], duration
     var timing = this._request.timing;
-    if (!timing)
-      return {blocked: -1, dns: -1, connect: -1, send: 0, wait: 0, receive: 0, ssl: -1};
+    var issueTime = this._request.issueTime();
+    var startTime = this._request.startTime;
 
-    function firstNonNegative(values) {
-      for (var i = 0; i < values.length; ++i) {
-        if (values[i] >= 0)
-          return values[i];
-      }
-      console.assert(false, 'Incomplete request timing information.');
+    var result = {blocked: -1, dns: -1, ssl: -1, connect: -1, send: 0, wait: 0, receive: -1, _blocked_queueing: -1};
+
+    var queuedTime = (issueTime < startTime) ? startTime - issueTime : -1;
+    result.blocked = queuedTime;
+    result._blocked_queueing = NetworkLog.HAREntry._toMilliseconds(queuedTime);
+
+    var highestTime = 0;
+    if (timing) {
+      // "blocked" here represents both queued + blocked/stalled + proxy (ie: anything before request was started).
+      // We pick the better of when the network request start was reported and pref timing.
+      var blockedStart = leastNonNegative([timing.dnsStart, timing.connectStart, timing.sendStart]);
+      if (blockedStart !== Infinity)
+        result.blocked += blockedStart;
+
+      // Proxy is part of blocked but sometimes (like quic) blocked is -1 but has proxy timings.
+      if (timing.proxyEnd !== -1)
+        result._blocked_proxy = timing.proxyEnd - timing.proxyStart;
+      if (result._blocked_proxy && result._blocked_proxy > result.blocked)
+        result.blocked = result._blocked_proxy;
+
+      var dnsStart = timing.dnsEnd >= 0 ? blockedStart : 0;
+      var dnsEnd = timing.dnsEnd >= 0 ? timing.dnsEnd : -1;
+      result.dns = dnsEnd - dnsStart;
+
+      // SSL timing is included in connection timing.
+      var sslStart = timing.sslEnd > 0 ? timing.sslStart : 0;
+      var sslEnd = timing.sslEnd > 0 ? timing.sslEnd : -1;
+      result.ssl = sslEnd - sslStart;
+
+      var connectStart = timing.connectEnd >= 0 ? leastNonNegative([dnsEnd, blockedStart]) : 0;
+      var connectEnd = timing.connectEnd >= 0 ? timing.connectEnd : -1;
+      result.connect = connectEnd - connectStart;
+
+      // Send should not be -1 for legacy reasons even if it is served from cache.
+      var sendStart = timing.sendEnd >= 0 ? Math.max(connectEnd, dnsEnd, blockedStart) : 0;
+      var sendEnd = timing.sendEnd >= 0 ? timing.sendEnd : 0;
+      result.send = sendEnd - sendStart;
+      // Quic sometimes says that sendStart is before connectionEnd (see: crbug.com/740792)
+      if (result.send < 0)
+        result.send = 0;
+      highestTime = Math.max(sendEnd, connectEnd, sslEnd, dnsEnd, blockedStart, 0);
+    } else if (this._request.responseReceivedTime === -1) {
+      // Means that we don't have any more details after blocked, so attribute all to blocked.
+      result.blocked = this._request.endTime - issueTime;
+      return result;
     }
 
-    var blocked = firstNonNegative([timing.dnsStart, timing.connectStart, timing.sendStart]);
+    var requestTime = timing ? timing.requestTime : startTime;
+    var waitStart = highestTime;
+    var waitEnd = NetworkLog.HAREntry._toMilliseconds(this._request.responseReceivedTime - requestTime);
+    result.wait = waitEnd - waitStart;
 
-    var dns = -1;
-    if (timing.dnsStart >= 0)
-      dns = firstNonNegative([timing.connectStart, timing.sendStart]) - timing.dnsStart;
+    var receiveStart = waitEnd;
+    var receiveEnd = NetworkLog.HAREntry._toMilliseconds(this._request.endTime - issueTime);
+    result.receive = Math.max(receiveEnd - receiveStart, 0);
 
-    var connect = -1;
-    if (timing.connectStart >= 0)
-      connect = timing.sendStart - timing.connectStart;
+    return result;
 
-    var send = timing.sendEnd - timing.sendStart;
-    var wait = timing.receiveHeadersEnd - timing.sendEnd;
-    var receive = NetworkLog.HAREntry._toMilliseconds(this._request.duration) - timing.receiveHeadersEnd;
-
-    var ssl = -1;
-    if (timing.sslStart >= 0 && timing.sslEnd >= 0)
-      ssl = timing.sslEnd - timing.sslStart;
-
-    return {blocked: blocked, dns: dns, connect: connect, send: send, wait: wait, receive: receive, ssl: ssl};
+    /**
+     * @param {!Array<number>} values
+     * @return {number}
+     */
+    function leastNonNegative(values) {
+      return values.reduce((best, value) => (value >= 0 && value < best) ? value : best, Infinity);
+    }
   }
 
   /**
@@ -258,6 +303,19 @@
   }
 };
 
+/** @typedef {!{
+  blocked: number,
+  dns: number,
+  ssl: number,
+  connect: number,
+  send: number,
+  wait: number,
+  receive: number,
+  _blocked_queueing: number,
+  _blocked_proxy: (number|undefined)
+}} */
+NetworkLog.HAREntry.Timing;
+
 
 /**
  * @unrestricted
diff --git a/third_party/WebKit/Source/devtools/front_end/network_log/NetworkLog.js b/third_party/WebKit/Source/devtools/front_end/network_log/NetworkLog.js
index 7d1df3b..2d636c0 100644
--- a/third_party/WebKit/Source/devtools/front_end/network_log/NetworkLog.js
+++ b/third_party/WebKit/Source/devtools/front_end/network_log/NetworkLog.js
@@ -323,6 +323,20 @@
   }
 
   /**
+   * @param {!Array<!SDK.NetworkRequest>} requests
+   */
+  importRequests(requests) {
+    this.reset();
+    this._requests = [];
+    this._requestsSet.clear();
+    for (var request of requests) {
+      this._requests.push(request);
+      this._requestsSet.add(request);
+      this.dispatchEventToListeners(NetworkLog.NetworkLog.Events.RequestAdded, request);
+    }
+  }
+
+  /**
    * @param {!Common.Event} event
    */
   _onRequestStarted(event) {
@@ -401,6 +415,26 @@
     /** @type {number} */
     this.contentLoadTime;
     this.mainRequest = mainRequest;
+
+    this._showDataSaverWarningIfNeeded();
+  }
+
+  async _showDataSaverWarningIfNeeded() {
+    var manager = SDK.NetworkManager.forRequest(this.mainRequest);
+    if (!manager)
+      return;
+    if (!this.mainRequest.finished)
+      await this.mainRequest.once(SDK.NetworkRequest.Events.FinishedLoading);
+    var saveDataHeader = this.mainRequest.requestHeaderValue('Save-Data');
+    if (!NetworkLog.PageLoad._dataSaverMessageWasShown && saveDataHeader && saveDataHeader === 'on') {
+      var message = Common.UIString(
+          'Consider disabling %s while debugging. For more info see: %s', Common.UIString('Chrome Data Saver'),
+          'https://support.google.com/chrome/?p=datasaver');
+      manager.dispatchEventToListeners(
+          SDK.NetworkManager.Events.MessageGenerated,
+          {message: message, requestId: this.mainRequest.requestId(), warning: true});
+      NetworkLog.PageLoad._dataSaverMessageWasShown = true;
+    }
   }
 
   /**
@@ -422,6 +456,8 @@
 NetworkLog.PageLoad._lastIdentifier = 0;
 NetworkLog.PageLoad._pageLoadForRequestSymbol = Symbol('PageLoadForRequest');
 
+NetworkLog.PageLoad._dataSaverMessageWasShown = false;
+
 /** @typedef {!{initiators: !Set<!SDK.NetworkRequest>, initiated: !Set<!SDK.NetworkRequest>}} */
 NetworkLog.NetworkLog.InitiatorGraph;
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js
index a5661f15..f77d6924 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js
@@ -80,7 +80,14 @@
     /** @type {!Array.<!SDK.NetworkRequest.EventSourceMessage>} */
     this._eventSourceMessages = [];
 
+    /** @type {!Object<string, (string|undefined)>} */
     this._responseHeaderValues = {};
+    this._responseHeadersText = '';
+
+    /** @type {!Array<!SDK.NetworkRequest.NameValue>} */
+    this._requestHeaders = [];
+    /** @type {!Object<string, (string|undefined)>} */
+    this._requestHeaderValues = {};
 
     this._remoteAddress = '';
 
@@ -608,7 +615,7 @@
    * @return {!Array.<!SDK.NetworkRequest.NameValue>}
    */
   requestHeaders() {
-    return this._requestHeaders || [];
+    return this._requestHeaders;
   }
 
   /**
@@ -642,7 +649,10 @@
    * @return {string|undefined}
    */
   requestHeaderValue(headerName) {
-    return this._headerValue(this.requestHeaders(), headerName);
+    if (headerName in this._requestHeaderValues)
+      return this._requestHeaderValues[headerName];
+    this._requestHeaderValues[headerName] = this._computeHeaderValue(this.requestHeaders(), headerName);
+    return this._requestHeaderValues[headerName];
   }
 
   /**
@@ -750,12 +760,10 @@
    * @return {string|undefined}
    */
   responseHeaderValue(headerName) {
-    var value = this._responseHeaderValues[headerName];
-    if (value === undefined) {
-      value = this._headerValue(this.responseHeaders, headerName);
-      this._responseHeaderValues[headerName] = (value !== undefined) ? value : null;
-    }
-    return (value !== null) ? value : undefined;
+    if (headerName in this._responseHeaderValues)
+      return this._responseHeaderValues[headerName];
+    this._responseHeaderValues[headerName] = this._computeHeaderValue(this.responseHeaders, headerName);
+    return this._responseHeaderValues[headerName];
   }
 
   /**
@@ -867,7 +875,7 @@
    * @param {string} headerName
    * @return {string|undefined}
    */
-  _headerValue(headers, headerName) {
+  _computeHeaderValue(headers, headerName) {
     headerName = headerName.toLowerCase();
 
     var values = [];
@@ -894,6 +902,14 @@
   }
 
   /**
+   * @param {!SDK.NetworkRequest.ContentData} data
+   */
+  setContentData(data) {
+    console.assert(!this._contentData, 'contentData can only be set once.');
+    this._contentData = Promise.resolve(data);
+  }
+
+  /**
    * @override
    * @return {string}
    */
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
index 78168992..e3ca021 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -119,7 +119,6 @@
     new Sources.WorkspaceMappingTip(this, this._workspace);
     Extensions.extensionServer.addEventListener(
         Extensions.ExtensionServer.Events.SidebarPaneAdded, this._extensionSidebarPaneAdded, this);
-    Components.DataSaverInfobar.maybeShowInPanel(this);
     SDK.targetManager.observeTargets(this);
   }
 
diff --git a/third_party/WebKit/Source/devtools/scripts/npm_test.js b/third_party/WebKit/Source/devtools/scripts/npm_test.js
index 5cb2e39..d1b3238 100644
--- a/third_party/WebKit/Source/devtools/scripts/npm_test.js
+++ b/third_party/WebKit/Source/devtools/scripts/npm_test.js
@@ -264,16 +264,19 @@
   var flagValues = Object.keys(Flags).map(key => Flags[key]);
   return process.argv.slice(2).filter(arg => {
     var flagName = utils.includes(arg, '=') ? arg.slice(0, arg.indexOf('=')) : arg;
-    return !utils.includes(flagValues, flagName) && !utils.includes(arg, 'inspector');
+    return !utils.includes(flagValues, flagName) && !utils.includes(arg, 'inspector') &&
+        !utils.includes(arg, 'http/tests/devtools');
   });
 }
 
 function getInspectorTests() {
-  var specificTests = process.argv.filter(arg => utils.includes(arg, 'inspector'));
+  var specificTests =
+      process.argv.filter(arg => utils.includes(arg, 'inspector') || utils.includes(arg, 'http/tests/devtools'));
   if (specificTests.length)
     return specificTests;
   return [
     'inspector*',
     'http/tests/inspector*',
+    'http/tests/devtools',
   ];
 }
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/scripts/special_case_namespaces.json b/third_party/WebKit/Source/devtools/scripts/special_case_namespaces.json
index 897ebb00..a973224 100644
--- a/third_party/WebKit/Source/devtools/scripts/special_case_namespaces.json
+++ b/third_party/WebKit/Source/devtools/scripts/special_case_namespaces.json
@@ -3,5 +3,6 @@
   "ui": "UI",
   "object_ui": "ObjectUI",
   "perf_ui": "PerfUI",
-  "css_tracker": "CSSTracker"
+  "css_tracker": "CSSTracker",
+  "har_importer": "HARImporter"
 }
\ No newline at end of file
diff --git a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
index 2fefaf0c..0713ded 100644
--- a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
+++ b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
@@ -306,7 +306,7 @@
   DCHECK(loader_);
 
   if (error.IsAccessCheck()) {
-    DidFailAccessControlCheck(error);
+    AbortConnectionAttempt();
     return;
   }
 
@@ -315,17 +315,6 @@
   NetworkRequestEnded();
 }
 
-void EventSource::DidFailAccessControlCheck(const ResourceError& error) {
-  DCHECK(loader_);
-
-  String message = "EventSource cannot load " + error.FailingURL() + ". " +
-                   error.LocalizedDescription();
-  GetExecutionContext()->AddConsoleMessage(
-      ConsoleMessage::Create(kJSMessageSource, kErrorMessageLevel, message));
-
-  AbortConnectionAttempt();
-}
-
 void EventSource::DidFailRedirectCheck() {
   DCHECK(loader_);
 
diff --git a/third_party/WebKit/Source/modules/eventsource/EventSource.h b/third_party/WebKit/Source/modules/eventsource/EventSource.h
index 1a950f4..1576ca3 100644
--- a/third_party/WebKit/Source/modules/eventsource/EventSource.h
+++ b/third_party/WebKit/Source/modules/eventsource/EventSource.h
@@ -111,7 +111,6 @@
   void DidReceiveData(const char*, unsigned) override;
   void DidFinishLoading(unsigned long, double) override;
   void DidFail(const ResourceError&) override;
-  void DidFailAccessControlCheck(const ResourceError&) override;
   void DidFailRedirectCheck() override;
 
   void OnMessageEvent(const AtomicString& event,
diff --git a/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp b/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp
index 7b03a17..3bda0da 100644
--- a/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp
@@ -343,16 +343,10 @@
   // Kickstart the worker before loading the script when the script has been
   // installed.
   if (RuntimeEnabledFeatures::ServiceWorkerScriptStreamingEnabled() &&
+      installed_scripts_manager_ &&
       installed_scripts_manager_->IsScriptInstalled(
           worker_start_data_.script_url)) {
-    // TODO(shimazu): Move WorkerScriptLoaded to the correct place which is
-    // after InstalledScriptsManager::GetScriptData() called at
-    // WorkerThread::InitializeOnWorkerThread().
-    worker_context_client_->WorkerScriptLoaded();
-    if (pause_after_download_state_ == kDoPauseAfterDownload) {
-      pause_after_download_state_ = kIsPausedAfterDownload;
-      return;
-    }
+    DCHECK_EQ(pause_after_download_state_, kDontPauseAfterDownload);
     StartWorkerThread();
     return;
   }
diff --git a/third_party/WebKit/Source/modules/fetch/BlobBytesConsumerTest.cpp b/third_party/WebKit/Source/modules/fetch/BlobBytesConsumerTest.cpp
index 5c44df05..184f14c 100644
--- a/third_party/WebKit/Source/modules/fetch/BlobBytesConsumerTest.cpp
+++ b/third_party/WebKit/Source/modules/fetch/BlobBytesConsumerTest.cpp
@@ -235,7 +235,7 @@
   EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
 
   int num_on_state_change_called = client->NumOnStateChangeCalled();
-  consumer->DidFailAccessControlCheck(ResourceError());
+  consumer->DidFail(ResourceError());
   EXPECT_EQ(num_on_state_change_called + 1, client->NumOnStateChangeCalled());
 
   EXPECT_EQ(PublicState::kErrored, consumer->GetPublicState());
diff --git a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
index 00d31537..b0cc7f6 100644
--- a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
+++ b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
@@ -163,7 +163,6 @@
                           std::unique_ptr<WebDataConsumerHandle>) override;
   void DidFinishLoading(unsigned long, double) override;
   void DidFail(const ResourceError&) override;
-  void DidFailAccessControlCheck(const ResourceError&) override;
   void DidFailRedirectCheck() override;
 
   void Start();
@@ -522,16 +521,6 @@
            error.LocalizedDescription());
 }
 
-void FetchManager::Loader::DidFailAccessControlCheck(
-    const ResourceError& error) {
-  if (error.IsCancellation() || error.IsTimeout() ||
-      error.Domain() != kErrorDomainBlinkInternal)
-    Failed(String());
-  else
-    Failed("Fetch API cannot load " + error.FailingURL() + ". " +
-           error.LocalizedDescription());
-}
-
 void FetchManager::Loader::DidFailRedirectCheck() {
   Failed("Fetch API cannot load " + request_->Url().GetString() +
          ". Redirect failed.");
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.cpp
index da0052e8..d8d5acc 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.cpp
@@ -545,6 +545,10 @@
       WorkerGlobalScope()->ScriptController()->GetContext());
 }
 
+void ServiceWorkerGlobalScopeProxy::DidLoadInstalledScript() {
+  Client().WorkerScriptLoaded();
+}
+
 void ServiceWorkerGlobalScopeProxy::WillEvaluateWorkerScript(
     size_t script_size,
     size_t cached_metadata_size) {
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.h
index 482e0f9..bf244b7 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.h
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.h
@@ -150,6 +150,7 @@
   void PostMessageToPageInspector(int session_id, const String&) override;
   void DidCreateWorkerGlobalScope(WorkerOrWorkletGlobalScope*) override;
   void DidInitializeWorkerContext() override;
+  void DidLoadInstalledScript() override;
   void WillEvaluateWorkerScript(size_t script_size,
                                 size_t cached_metadata_size) override;
   void WillEvaluateImportedScript(size_t script_size,
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerInstalledScriptsManager.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerInstalledScriptsManager.cpp
index d705994..7a095ca4 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerInstalledScriptsManager.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerInstalledScriptsManager.cpp
@@ -6,12 +6,15 @@
 
 #include "core/html/parser/TextResourceDecoder.h"
 #include "modules/serviceworkers/ServiceWorkerThread.h"
+#include "platform/wtf/text/StringBuilder.h"
 
 namespace blink {
 
 ServiceWorkerInstalledScriptsManager::ServiceWorkerInstalledScriptsManager(
     std::unique_ptr<WebServiceWorkerInstalledScriptsManager> manager)
-    : manager_(std::move(manager)) {}
+    : manager_(std::move(manager)) {
+  DCHECK(manager_);
+}
 
 bool ServiceWorkerInstalledScriptsManager::IsScriptInstalled(
     const KURL& script_url) const {
@@ -24,7 +27,6 @@
   // This blocks until the script is received from the browser.
   std::unique_ptr<WebServiceWorkerInstalledScriptsManager::RawScriptData>
       raw_script_data = manager_->GetRawScriptData(script_url);
-
   if (!raw_script_data)
     return WTF::nullopt;
 
@@ -42,9 +44,11 @@
   InstalledScriptsManager::ScriptData script_data;
   // TODO(shimazu): Read the headers for ContentSecurityPolicy, ReferrerPolicy,
   // and OriginTrialTokens and set them to |script_data|.
-  for (const auto& chunk : raw_script_data->ScriptTextChunks()) {
-    script_data.source_text.append(decoder->Decode(chunk.Data(), chunk.size()));
-  }
+  StringBuilder source_text_builder;
+  for (const auto& chunk : raw_script_data->ScriptTextChunks())
+    source_text_builder.Append(decoder->Decode(chunk.Data(), chunk.size()));
+  script_data.source_text = source_text_builder.ToString();
+
   if (raw_script_data->MetaDataChunks().size() > 0) {
     size_t total_metadata_size = 0;
     for (const auto& chunk : raw_script_data->MetaDataChunks())
@@ -54,6 +58,7 @@
     for (const auto& chunk : raw_script_data->MetaDataChunks())
       script_data.meta_data->Append(chunk.Data(), chunk.size());
   }
+
   script_data.headers.Adopt(raw_script_data->TakeHeaders());
   return Optional<ScriptData>(std::move(script_data));
 }
diff --git a/third_party/WebKit/Source/modules/websockets/README.md b/third_party/WebKit/Source/modules/websockets/README.md
new file mode 100644
index 0000000..efb600a13
--- /dev/null
+++ b/third_party/WebKit/Source/modules/websockets/README.md
@@ -0,0 +1,9 @@
+# WebSocket API
+
+This directory contains:
+- the implementation of
+  [the WebSocket API](https://html.spec.whatwg.org/multipage/web-sockets.html).
+- the Pepper implementation of the WebSocket API
+
+They use DocumentWebSocketChannel to connect to the WebSocket service i.e. the
+blink::mojom::WebSocket implementation in content/browser/websockets/.
diff --git a/third_party/WebKit/Source/platform/exported/WebURLError.cpp b/third_party/WebKit/Source/platform/exported/WebURLError.cpp
index 2898c00..d58d3d0 100644
--- a/third_party/WebKit/Source/platform/exported/WebURLError.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebURLError.cpp
@@ -58,7 +58,7 @@
     stale_copy_in_cache = error.StaleCopyInCache();
     localized_description = error.LocalizedDescription();
     was_ignored_by_handler = error.WasIgnoredByHandler();
-    is_cache_miss = error.IsCacheMiss();
+    is_web_security_violation = error.IsAccessCheck();
   }
   return *this;
 }
@@ -71,7 +71,7 @@
   resource_error.SetIsCancellation(is_cancellation);
   resource_error.SetStaleCopyInCache(stale_copy_in_cache);
   resource_error.SetWasIgnoredByHandler(was_ignored_by_handler);
-  resource_error.SetIsCacheMiss(is_cache_miss);
+  resource_error.SetIsAccessCheck(is_web_security_violation);
   return resource_error;
 }
 
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp
index 5082bf71..03aac72 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp
@@ -407,6 +407,7 @@
 
   EXPECT_EQ(result->NumCharacters(), composite_result->NumCharacters());
   EXPECT_EQ(result->SnappedWidth(), composite_result->SnappedWidth());
+  EXPECT_EQ(result->Bounds(), composite_result->Bounds());
   EXPECT_EQ(result->SnappedStartPositionForOffset(0),
             composite_result->SnappedStartPositionForOffset(0));
   EXPECT_EQ(result->SnappedStartPositionForOffset(15),
@@ -432,6 +433,7 @@
 
   EXPECT_EQ(result->NumCharacters(), composite_result->NumCharacters());
   EXPECT_EQ(result->SnappedWidth(), composite_result->SnappedWidth());
+  EXPECT_EQ(result->Bounds(), composite_result->Bounds());
   EXPECT_EQ(result->SnappedStartPositionForOffset(0),
             composite_result->SnappedStartPositionForOffset(0));
   EXPECT_EQ(result->SnappedStartPositionForOffset(1),
@@ -468,4 +470,22 @@
   EXPECT_EQ(2u, target->NumCharacters());
 }
 
+TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeSegmentGlyphBoundingBox) {
+  String string(u"THello worldL");
+  TextDirection direction = TextDirection::kLtr;
+
+  HarfBuzzShaper shaper(string.Characters16(), string.length());
+  RefPtr<ShapeResult> result1 = shaper.Shape(&font, direction, 0, 6);
+  RefPtr<ShapeResult> result2 =
+      shaper.Shape(&font, direction, 6, string.length());
+
+  RefPtr<ShapeResult> composite_result =
+      ShapeResult::Create(&font, 0, direction);
+  result1->CopyRange(0, 6, composite_result.Get());
+  result2->CopyRange(6, string.length(), composite_result.Get());
+
+  RefPtr<ShapeResult> result = shaper.Shape(&font, direction);
+  EXPECT_EQ(result->Bounds(), composite_result->Bounds());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
index 1ebfad4..f690efd 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
@@ -456,6 +456,7 @@
                             unsigned end_offset,
                             ShapeResult* target) const {
   unsigned index = target->num_characters_;
+  float total_width = 0;
   for (const auto& run : runs_) {
     unsigned run_start = (*run).start_index_;
     unsigned run_end = run_start + (*run).num_characters_;
@@ -467,12 +468,37 @@
 
       auto sub_run = (*run).CreateSubRun(start, end);
       sub_run->start_index_ = index;
-      target->width_ += sub_run->width_;
+      total_width += sub_run->width_;
       index += sub_run->num_characters_;
       target->runs_.push_back(std::move(sub_run));
     }
   }
 
+  // Compute new glyph bounding box.
+  // If |start_offset| or |end_offset| are the start/end of |this|, use
+  // |glyph_bounding_box_| from |this| for the side. Otherwise, we cannot
+  // compute accurate glyph bounding box; approximate by assuming there are no
+  // glyph overflow nor underflow.
+  // TODO(kojii): This is not correct for vertical flow since glyphs are in
+  // physical coordinates.
+  float left = target->width_;
+  target->width_ += total_width;
+  float right = target->width_;
+  if (start_offset <= StartIndexForResult())
+    left += glyph_bounding_box_.X();
+  if (end_offset >= EndIndexForResult())
+    right += glyph_bounding_box_.MaxX() - width_;
+  if (right >= left) {
+    FloatRect adjusted_box(left, glyph_bounding_box_.Y(), right - left,
+                           glyph_bounding_box_.Height());
+    target->glyph_bounding_box_.UniteIfNonZero(adjusted_box);
+  } else {
+    FloatRect adjusted_box(left, glyph_bounding_box_.Y(), 0,
+                           glyph_bounding_box_.Height());
+    target->glyph_bounding_box_.UniteIfNonZero(adjusted_box);
+    target->glyph_bounding_box_.ShiftMaxXEdgeTo(right);
+  }
+
   DCHECK_EQ(index - target->num_characters_,
             std::min(end_offset, EndIndexForResult()) -
                 std::max(start_offset, StartIndexForResult()));
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceError.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceError.cpp
index 8b4c9691..be298b58 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceError.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceError.cpp
@@ -59,12 +59,21 @@
   return error;
 }
 
-ResourceError ResourceError::CacheMissError(const String& failing_url) {
-  ResourceError error(kErrorDomainBlinkInternal, 0, failing_url, String());
-  error.SetIsCacheMiss(true);
+ResourceError ResourceError::CancelledDueToAccessCheckError(
+    const String& failing_url,
+    ResourceRequestBlockedReason blocked_reason,
+    const String& localized_description) {
+  ResourceError error =
+      CancelledDueToAccessCheckError(failing_url, blocked_reason);
+  error.localized_description_ = localized_description;
   return error;
 }
 
+ResourceError ResourceError::CacheMissError(const String& failing_url) {
+  return WebURLError(KURL(kParsedURLString, failing_url), false,
+                     net::ERR_CACHE_MISS);
+}
+
 ResourceError ResourceError::Copy() const {
   ResourceError error_copy;
   error_copy.domain_ = domain_.IsolatedCopy();
@@ -75,9 +84,7 @@
   error_copy.is_cancellation_ = is_cancellation_;
   error_copy.is_access_check_ = is_access_check_;
   error_copy.is_timeout_ = is_timeout_;
-  error_copy.stale_copy_in_cache_ = stale_copy_in_cache_;
   error_copy.was_ignored_by_handler_ = was_ignored_by_handler_;
-  error_copy.is_cache_miss_ = is_cache_miss_;
   return error_copy;
 }
 
@@ -115,9 +122,6 @@
   if (a.WasIgnoredByHandler() != b.WasIgnoredByHandler())
     return false;
 
-  if (a.IsCacheMiss() != b.IsCacheMiss())
-    return false;
-
   return true;
 }
 
@@ -131,8 +135,6 @@
   error->unreachable_url = url;
   if (reason == net::ERR_ABORTED) {
     error->is_cancellation = true;
-  } else if (reason == net::ERR_CACHE_MISS) {
-    error->is_cache_miss = true;
   } else if (reason == net::ERR_TEMPORARILY_THROTTLED) {
     error->localized_description =
         WebString::FromASCII(kThrottledErrorDescription);
@@ -142,4 +144,9 @@
   }
 }
 
+bool ResourceError::IsCacheMiss() const {
+  return domain_ == String(net::kErrorDomain) &&
+         error_code_ == net::ERR_CACHE_MISS;
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceError.h b/third_party/WebKit/Source/platform/loader/fetch/ResourceError.h
index ad9a0a89..00e88b14 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceError.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceError.h
@@ -56,8 +56,11 @@
   static ResourceError CancelledDueToAccessCheckError(
       const String& failing_url,
       ResourceRequestBlockedReason);
+  static ResourceError CancelledDueToAccessCheckError(
+      const String& failing_url,
+      ResourceRequestBlockedReason,
+      const String& localized_description);
 
-  // Only for Blink internal usage.
   static ResourceError CacheMissError(const String& failing_url);
 
   ResourceError()
@@ -68,7 +71,6 @@
         is_timeout_(false),
         stale_copy_in_cache_(false),
         was_ignored_by_handler_(false),
-        is_cache_miss_(false),
         should_collapse_initiator_(false) {}
 
   ResourceError(const String& domain,
@@ -85,7 +87,6 @@
         is_timeout_(false),
         stale_copy_in_cache_(false),
         was_ignored_by_handler_(false),
-        is_cache_miss_(false),
         should_collapse_initiator_(false) {}
 
   // Makes a deep copy. Useful for when you need to use a ResourceError on
@@ -121,8 +122,7 @@
   }
   bool WasIgnoredByHandler() const { return was_ignored_by_handler_; }
 
-  void SetIsCacheMiss(bool is_cache_miss) { is_cache_miss_ = is_cache_miss; }
-  bool IsCacheMiss() const { return is_cache_miss_; }
+  bool IsCacheMiss() const;
   bool WasBlockedByResponse() const {
     return error_code_ == net::ERR_BLOCKED_BY_RESPONSE;
   }
@@ -150,7 +150,6 @@
   bool is_timeout_;
   bool stale_copy_in_cache_;
   bool was_ignored_by_handler_;
-  bool is_cache_miss_;
   bool should_collapse_initiator_;
 };
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
index 1fab56b7..5f54ea9 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -735,10 +735,13 @@
             else:
                 path_in_wpt = filename
             return self._wpt_manifest().is_test_file(path_in_wpt)
-        if 'inspector-protocol' in dirname and filesystem.splitext(filename)[1] == '.js':
+        extension = filesystem.splitext(filename)[1]
+        if 'inspector-protocol' in dirname and extension == '.js':
             return True
-        if 'inspector-unit' in dirname or 'devtools-js' in dirname:
-            return filesystem.splitext(filename)[1] == '.js'
+        if 'devtools' in dirname and extension == '.js':
+            return True
+        if 'inspector-unit' in dirname:
+            return extension == '.js'
         return Port._has_supported_extension(
             filesystem, filename) and not Port.is_reference_html_file(filesystem, dirname, filename)
 
diff --git a/third_party/WebKit/public/platform/WebURLError.h b/third_party/WebKit/public/platform/WebURLError.h
index 1415ff4..e62ccfa 100644
--- a/third_party/WebKit/public/platform/WebURLError.h
+++ b/third_party/WebKit/public/platform/WebURLError.h
@@ -62,9 +62,8 @@
   // ignored (e.g. through shouldOverrideUrlLoading).
   bool was_ignored_by_handler = false;
 
-  // A flag showing whether this error is a disk cache miss by requesting to
-  // load only from disk cache.
-  bool is_cache_miss = false;
+  // True if this error is created for a web security violation.
+  bool is_web_security_violation = false;
 
   // The url that failed to load.
   WebURL unreachable_url;
diff --git a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h
index 3ed7f9623..8b10a31 100644
--- a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h
+++ b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h
@@ -73,7 +73,9 @@
   virtual void WorkerReadyForInspection() {}
 
   // The worker script is successfully loaded and a new thread is about to
-  // be started. Called on the main thread.
+  // be started. Called on the main thread when the script is served from
+  // ResourceLoader or on the worker thread when the script is served via
+  // WebServiceWorkerInstalledScriptsManager.
   virtual void WorkerScriptLoaded() {}
 
   virtual bool HasAssociatedRegistration() { return false; }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 274215c..384afdb 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -3471,6 +3471,11 @@
   <int value="1" label="Registration is a duplicate"/>
 </enum>
 
+<enum name="BooleanRenamed">
+  <int value="0" label="Not Renamed"/>
+  <int value="1" label="Renamed"/>
+</enum>
+
 <enum name="BooleanReported">
   <int value="0" label="Not reported"/>
   <int value="1" label="Reported"/>
@@ -8358,6 +8363,84 @@
   <int value="3" label="Touch"/>
 </enum>
 
+<enum name="Download.Service.BatteryRequirements">
+  <int value="0" label="BATTERY_INSENSITIVE"/>
+  <int value="1" label="BATTERY_SENSITIVE"/>
+</enum>
+
+<enum name="Download.Service.CompletionType">
+  <int value="0" label="SUCCEED"/>
+  <int value="1" label="FAIL"/>
+  <int value="2" label="ABORT"/>
+  <int value="3" label="TIMEOUT"/>
+  <int value="4" label="UNKNOWN"/>
+  <int value="5" label="CANCEL"/>
+</enum>
+
+<enum name="Download.Service.EntryStates">
+  <int value="0" label="NEW"/>
+  <int value="1" label="AVAILABLE"/>
+  <int value="2" label="ACTIVE"/>
+  <int value="3" label="PAUSED"/>
+  <int value="4" label="COMPLETE"/>
+</enum>
+
+<enum name="Download.Service.ModelAction">
+  <int value="0" label="INITIALIZE"/>
+  <int value="1" label="ADD"/>
+  <int value="2" label="UPDATE"/>
+  <int value="3" label="REMOVE"/>
+</enum>
+
+<enum name="Download.Service.NetworkRequirements">
+  <int value="0" label="NONE"/>
+  <int value="1" label="OPTIMISTIC"/>
+  <int value="2" label="UNMETERED"/>
+</enum>
+
+<enum name="Download.Service.Priority">
+  <int value="0" label="LOW"/>
+  <int value="1" label="NORMAL"/>
+  <int value="2" label="HIGH"/>
+  <int value="3" label="UI"/>
+</enum>
+
+<enum name="Download.Service.ScheduledTaskStatus">
+  <int value="0" label="ABORTED_ON_FAILED_INIT"/>
+  <int value="1" label="CANCELLED_ON_STOP"/>
+  <int value="2" label="COMPLETED_NORMALLY"/>
+</enum>
+
+<enum name="Download.Service.ServiceApiAction">
+  <int value="0" label="START_DOWNLOAD"/>
+  <int value="1" label="PAUSE_DOWNLOAD"/>
+  <int value="2" label="RESUME_DOWNLOAD"/>
+  <int value="3" label="CANCEL_DOWNLOAD"/>
+  <int value="4" label="CHANGE_CRITERIA"/>
+</enum>
+
+<enum name="Download.Service.ShouldDownload">
+  <int value="0" label="CONTINUE"/>
+  <int value="1" label="ABORT"/>
+</enum>
+
+<enum name="Download.Service.StartResult">
+  <int value="0" label="ACCEPTED"/>
+  <int value="1" label="BACKOFF"/>
+  <int value="2" label="UNEXPECTED_CLIENT"/>
+  <int value="3" label="UNEXPECTED_GUID"/>
+  <int value="4" label="CLIENT_CANCELLED"/>
+  <int value="5" label="INTERNAL_ERROR"/>
+</enum>
+
+<enum name="Download.Service.StartUpResult">
+  <int value="0" label="SUCCESS"/>
+  <int value="1" label="FAILURE"/>
+  <int value="2" label="FAILURE_REASON_DRIVER"/>
+  <int value="3" label="FAILURE_REASON_MODEL"/>
+  <int value="4" label="FAILURE_REASON_FILE_MONITOR"/>
+</enum>
+
 <enum name="DownloadConnectionSecurity">
   <int value="0"
       label="Final download url and the redirects before it all use https"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 561132c..fc5e0624 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -15223,6 +15223,209 @@
   </summary>
 </histogram>
 
+<histogram name="Download.Service.Db.Operation.Failure"
+    enum="Download.Service.ModelAction">
+  <owner>xingliu@chromium.org</owner>
+  <summary>Records a failed database operation.</summary>
+</histogram>
+
+<histogram name="Download.Service.Db.Operation.Success"
+    enum="Download.Service.ModelAction">
+  <owner>xingliu@chromium.org</owner>
+  <summary>Records a successful database operation.</summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.Db.Records" units="records">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.EntryState" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The total number of database records used by download service, and the
+    number of records in each entry state.
+  </summary>
+</histogram>
+
+<histogram name="Download.Service.Driver.InterruptReason"
+    enum="InterruptReason">
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The interrupt reason for failed downloads in download service.
+  </summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.Files.CleanUp.External"
+    units="files">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.CleanupReason" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The number of files that have been deleted by external application or the
+    user, when performing clean up tasks in download service.
+  </summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.Files.CleanUp.Failure"
+    units="attempts">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.CleanupReason" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The number of failed file deletion attempts, when performing clean up tasks
+    in download service.
+  </summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.Files.CleanUp.Success"
+    units="files">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.CleanupReason" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The number of files successfully deleted, when performing clean up tasks in
+    download service.
+  </summary>
+</histogram>
+
+<histogram name="Download.Service.Files.DirCreationError"
+    enum="PlatformFileError">
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The error code when failed to create the download directory.
+  </summary>
+</histogram>
+
+<histogram name="Download.Service.Files.DiskUsed" units="%">
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The percentage of disk space used by download service files. Recorded during
+    initialization of the file monitor.
+  </summary>
+</histogram>
+
+<histogram name="Download.Service.Files.FreeDiskSpace" units="%">
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The percentage of free disk space to total disk space. Recorded during
+    initialization of the file monitor.
+  </summary>
+</histogram>
+
+<histogram name="Download.Service.Files.LifeTime" units="ms">
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The lifestime of a download file, which begins from the download completion
+    to the file being deleted by the clean up task.
+  </summary>
+</histogram>
+
+<histogram name="Download.Service.Files.PathRenamed" enum="BooleanRenamed">
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    Records if the final file path has been renamed by low level download
+    library after the download is successfully completed.
+  </summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.Finish.FileSize" units="KB">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.CompletionType" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The file size of completed download, including failed downloads.
+  </summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.Finish.Time" units="ms">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.CompletionType" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>The time to complete the download in download service.</summary>
+</histogram>
+
+<histogram name="Download.Service.Finish.Type"
+    enum="Download.Service.CompletionType">
+  <owner>xingliu@chromium.org</owner>
+  <summary>The completion type for downloads in download service.</summary>
+</histogram>
+
+<histogram name="Download.Service.Recovery" enum="Download.Service.EntryStates">
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The state that the entry transitions to when recovery operation happens.
+  </summary>
+</histogram>
+
+<histogram name="Download.Service.Request.BatteryRequirement"
+    enum="Download.Service.BatteryRequirements">
+  <owner>xingliu@chromium.org</owner>
+  <summary>The battery requirement of the download request.</summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.Request.ClientAction"
+    enum="Download.Service.ServiceApiAction">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.Client" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>Records the API calls on download service.</summary>
+</histogram>
+
+<histogram name="Download.Service.Request.NetworkRequirement"
+    enum="Download.Service.NetworkRequirements">
+  <owner>xingliu@chromium.org</owner>
+  <summary>The network requirement of the download request.</summary>
+</histogram>
+
+<histogram name="Download.Service.Request.Priority"
+    enum="Download.Service.Priority">
+  <owner>xingliu@chromium.org</owner>
+  <summary>The priority of the download request.</summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.Request.StartResponse"
+    enum="Download.Service.ShouldDownload">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.Client" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>The start response of download attempts.</summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.Request.StartResult"
+    enum="Download.Service.StartResult">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.Client" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>The start result of download attempts.</summary>
+</histogram>
+
+<histogram name="Download.Service.StartUpStatus"
+    enum="Download.Service.StartUpResult">
+  <owner>xingliu@chromium.org</owner>
+  <summary>The start up result of the download service.</summary>
+</histogram>
+
+<histogram base="true" name="Download.Service.TaskScheduler.Status"
+    enum="Download.Service.ScheduledTaskStatus">
+<!-- Name completed by histogram_suffixes
+     name="Download.Service.TaskType" -->
+
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    The platform background tasks used by download service will invoke native
+    functions after being scheduled. The tasks may be aborted or canceled. This
+    metric records the status of background tasks when native functions are
+    invoked.
+  </summary>
+</histogram>
+
 <histogram name="Download.ShelfInProgressSizeOnAutoClose">
   <owner>asanka@chromium.org</owner>
   <summary>
@@ -90947,6 +91150,48 @@
   <affected-histogram name="Cookie.ReinstatedCookies"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="Download.Service.CleanUpReason" separator=".">
+  <suffix name="Timeout" label="File is deleted after timeout."/>
+  <suffix name="Orphaned" label="No client associated with the file."/>
+  <suffix name="Unknown" label="No database entry associated with the file."/>
+  <suffix name="HardRecovery" label="File is deleted in hard recovery."/>
+  <affected-histogram name="Download.Service.Files.CleanUp.External"/>
+  <affected-histogram name="Download.Service.Files.CleanUp.Failure"/>
+  <affected-histogram name="Download.Service.Files.CleanUp.Success"/>
+</histogram_suffixes>
+
+<histogram_suffixes name="Download.Service.Client" separator=".">
+  <suffix name="OfflinePage" label="Offline page prefetch."/>
+  <affected-histogram name="Download.Service.Request.ClientAction"/>
+  <affected-histogram name="Download.Service.Request.StartResponse"/>
+  <affected-histogram name="Download.Service.Request.StartResult"/>
+</histogram_suffixes>
+
+<histogram_suffixes name="Download.Service.CompletionType" separator=".">
+  <suffix name="Succeed" label="Succeed."/>
+  <suffix name="Fail" label="Fail."/>
+  <suffix name="Abort" label="Abort."/>
+  <suffix name="Timeout" label="Timeout."/>
+  <suffix name="Unknown" label="Unknown."/>
+  <suffix name="Cancel" label="Cancel."/>
+  <affected-histogram name="Download.Service.Finish.FileSize"/>
+</histogram_suffixes>
+
+<histogram_suffixes name="Download.Service.EntryState" separator=".">
+  <suffix name="New" label="The initial state."/>
+  <suffix name="Available" label="The available state."/>
+  <suffix name="Active" label="The active state."/>
+  <suffix name="Paused" label="The paused state."/>
+  <suffix name="Complete" label="The complte state."/>
+  <affected-histogram name="Download.Service.Db.Records"/>
+</histogram_suffixes>
+
+<histogram_suffixes name="Download.Service.TaskType" separator=".">
+  <suffix name="DownloadTask" label="Download task."/>
+  <suffix name="CleanUpTask" label="Clean up task."/>
+  <affected-histogram name="Download.Service.TaskScheduler.Status"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="DownloadDangerPromptResponse" separator=".">
   <suffix name="Proceed"
       label="The user clicked through and recovered the download."/>
diff --git a/tools/traffic_annotation/auditor/tests/gn_list_negative.txt b/tools/traffic_annotation/auditor/tests/gn_list_negative.txt
new file mode 100644
index 0000000..a0dd485
--- /dev/null
+++ b/tools/traffic_annotation/auditor/tests/gn_list_negative.txt
@@ -0,0 +1,12 @@
+//:All
+//:gn_all
+//chrome/test:browser_tests
+//chrome/test/media_router:media_router_tests
+//remoting:remoting_all
+//remoting:remoting_perftests
+//remoting:remoting_unittests
+//remoting:test_support
+//remoting/host:all
+//remoting/host:all_tests
+//remoting/host:host
+
diff --git a/tools/traffic_annotation/auditor/tests/gn_list_positive.txt b/tools/traffic_annotation/auditor/tests/gn_list_positive.txt
new file mode 100644
index 0000000..bda21ab0
--- /dev/null
+++ b/tools/traffic_annotation/auditor/tests/gn_list_positive.txt
@@ -0,0 +1,27 @@
+//:All
+//:blink_tests
+//:chromium_builder_asan
+//:chromium_builder_perf
+//:gn_all
+//:run_webkit_tests
+//:webkit_layout_tests
+//:webkit_layout_tests_exparchive
+//apps:apps
+//apps:test_support
+//apps/ui/views:views
+//chrome:assert_no_deps
+//chrome:browser_dependencies
+//chrome:child_dependencies
+//chrome:chrome
+//chrome:chrome_initial
+//chrome/app:test_support
+//chrome/browser:browser
+//chrome/browser:test_support
+//chrome/browser/apps:apps
+//chrome/browser/devtools:devtools
+//chrome/browser/extensions:extensions
+//chrome/browser/media/router:router
+//chrome/browser/media/router:test_support
+//chrome/browser/media/router/discovery:discovery
+//chrome/browser/safe_browsing:safe_browsing
+
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
index cbe0120d..d18da34 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
+++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -7,6 +7,7 @@
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/process/launch.h"
+#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -160,10 +161,20 @@
       error_text.pop_back();
       error_text.pop_back();
       error_text += ".";
-
       return error_text;
     }
 
+    case AuditorResult::ResultType::ERROR_UNIQUE_ID_INVALID_CHARACTER:
+      DCHECK(details_.size());
+      return base::StringPrintf(
+          "Unique id '%s' in '%s:%i' contains an invalid character.",
+          details_[0].c_str(), file_path_.c_str(), line_);
+
+    case AuditorResult::ResultType::ERROR_MISSING_ANNOTATION:
+      DCHECK(details_.size());
+      return base::StringPrintf("Function '%s' in '%s:%i' requires annotation.",
+                                details_[0].c_str(), file_path_.c_str(), line_);
+
     default:
       return std::string();
   }
@@ -520,7 +531,7 @@
     AnnotationInstance& instance = extracted_annotations_[index];
 
     // If unique id's hash code is similar to a reserved id, add an error.
-    if (reserved_ids.find(instance.unique_id_hash_code) != reserved_ids.end()) {
+    if (base::ContainsKey(reserved_ids, instance.unique_id_hash_code)) {
       errors_.push_back(AuditorResult(
           AuditorResult::ResultType::ERROR_RESERVED_UNIQUE_ID_HASH_CODE,
           instance.proto.unique_id(), instance.proto.source().file(),
@@ -529,7 +540,7 @@
     }
 
     // Find unique ids with similar hash codes.
-    if (unique_ids.find(instance.unique_id_hash_code) == unique_ids.end()) {
+    if (!base::ContainsKey(unique_ids, instance.unique_id_hash_code)) {
       std::vector<unsigned> empty_list;
       unique_ids.insert(
           std::make_pair(instance.unique_id_hash_code, empty_list));
@@ -554,6 +565,84 @@
   }
 }
 
+void TrafficAnnotationAuditor::CheckUniqueIDsFormat() {
+  for (const AnnotationInstance& instance : extracted_annotations_) {
+    if (!base::ContainsOnlyChars(base::ToLowerASCII(instance.proto.unique_id()),
+                                 "0123456789_abcdefghijklmnopqrstuvwxyz")) {
+      errors_.push_back(AuditorResult(
+          AuditorResult::ResultType::ERROR_UNIQUE_ID_INVALID_CHARACTER,
+          instance.proto.unique_id(), instance.proto.source().file(),
+          instance.proto.source().line()));
+    }
+  }
+}
+
+void TrafficAnnotationAuditor::CheckAllRequiredFunctionsAreAnnotated() {
+  for (const CallInstance& call : extracted_calls_) {
+    if (!call.is_annotated && !CheckIfCallCanBeUnannotated(call)) {
+      errors_.push_back(
+          AuditorResult(AuditorResult::ResultType::ERROR_MISSING_ANNOTATION,
+                        call.function_name, call.file_path, call.line_number));
+    }
+  }
+}
+
+bool TrafficAnnotationAuditor::CheckIfCallCanBeUnannotated(
+    const CallInstance& call) {
+  // At this stage we do not enforce annotation on native network requests,
+  // hence all calls except those to 'net::URLRequestContext::CreateRequest' and
+  // 'net::URLFetcher::Create' are ignored.
+  if (call.function_name != "net::URLFetcher::Create" &&
+      call.function_name != "net::URLRequestContext::CreateRequest") {
+    return true;
+  }
+
+  // Is in whitelist?
+  if (IsWhitelisted(call.file_path, AuditorException::ExceptionType::MISSING))
+    return true;
+
+  // Already checked?
+  if (base::ContainsKey(checked_dependencies_, call.file_path))
+    return checked_dependencies_[call.file_path];
+
+  std::string gn_output;
+  if (gn_file_for_test_.empty()) {
+    // Check if the file including this function is part of Chrome build.
+    const base::CommandLine::CharType* args[] = {FILE_PATH_LITERAL("gn"),
+                                                 FILE_PATH_LITERAL("refs"),
+                                                 FILE_PATH_LITERAL("--all")};
+
+    base::CommandLine cmdline(3, args);
+    cmdline.AppendArgPath(build_path_);
+    cmdline.AppendArg(call.file_path);
+
+    base::FilePath original_path;
+    base::GetCurrentDirectory(&original_path);
+    base::SetCurrentDirectory(source_path_);
+
+    if (!base::GetAppOutput(cmdline, &gn_output)) {
+      LOG(ERROR) << "Could not run gn to get dependencies.";
+      gn_output.clear();
+    }
+
+    base::SetCurrentDirectory(original_path);
+  } else {
+    if (!base::ReadFileToString(gn_file_for_test_, &gn_output)) {
+      LOG(ERROR) << "Could not load mock gn output file from "
+                 << gn_file_for_test_.MaybeAsASCII().c_str();
+      gn_output.clear();
+    }
+  }
+
+  checked_dependencies_[call.file_path] =
+      gn_output.length() &&
+      gn_output.find("//chrome:chrome") == std::string::npos;
+
+  return checked_dependencies_[call.file_path];
+}
+
 void TrafficAnnotationAuditor::RunAllChecks() {
   CheckDuplicateHashes();
+  CheckUniqueIDsFormat();
+  CheckAllRequiredFunctionsAreAnnotated();
 }
\ No newline at end of file
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h
index 17b3516..dc3dc24 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h
+++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h
@@ -46,10 +46,15 @@
     ERROR_MISSING,        // A function is called without annotation.
     ERROR_NO_ANNOTATION,  // A function is called with NO_ANNOTATION tag.
     ERROR_SYNTAX,         // Annotation syntax is not right.
-    ERROR_RESERVED_UNIQUE_ID_HASH_CODE,  // A unique id has a hash code similar
-                                         // to a reserved word.
-    ERROR_DUPLICATE_UNIQUE_ID_HASH_CODE  // Two unique ids have similar hash
-                                         // codes.
+    ERROR_RESERVED_UNIQUE_ID_HASH_CODE,   // A unique id has a hash code similar
+                                          // to a reserved word.
+    ERROR_DUPLICATE_UNIQUE_ID_HASH_CODE,  // Two unique ids have similar hash
+                                          // codes.
+    ERROR_UNIQUE_ID_INVALID_CHARACTER,    // A unique id contanins a characer
+                                          // which is not alphanumeric or
+                                          // underline.
+    ERROR_MISSING_ANNOTATION  // A function that requires annotation is not
+                              // annotated.
   };
 
   static const int kNoCodeLineSpecified;
@@ -208,6 +213,16 @@
   // Checks to see if any unique id or its hash code is duplicated.
   void CheckDuplicateHashes();
 
+  // Checks to see if unique ids only include alphanumeric characters and
+  // underline.
+  void CheckUniqueIDsFormat();
+
+  // Checks to see if all functions that need annotations have one.
+  void CheckAllRequiredFunctionsAreAnnotated();
+
+  // Checks if a call instance can stay not annotated.
+  bool CheckIfCallCanBeUnannotated(const CallInstance& call);
+
   // Preforms all checks on extracted annotations and calls, and adds the
   // results to |errors_|.
   void RunAllChecks();
@@ -233,6 +248,10 @@
     extracted_annotations_ = annotations;
   }
 
+  void SetExtractedCallsForTest(const std::vector<CallInstance>& calls) {
+    extracted_calls_ = calls;
+  }
+
   const std::vector<CallInstance>& extracted_calls() const {
     return extracted_calls_;
   }
@@ -241,6 +260,14 @@
 
   void ClearErrorsForTest() { errors_.clear(); }
 
+  void ClearCheckedDependenciesForTest() { checked_dependencies_.clear(); }
+
+  // Sets the path to a file that would be used to mock the output of
+  // 'gn refs --all [build directory] [file path]' in tests.
+  void SetGnFileForTest(const base::FilePath& file_path) {
+    gn_file_for_test_ = file_path;
+  }
+
  private:
   const base::FilePath source_path_;
   const base::FilePath build_path_;
@@ -252,6 +279,9 @@
 
   std::vector<std::string> ignore_list_[static_cast<int>(
       AuditorException::ExceptionType::EXCEPTION_TYPE_LAST)];
+
+  base::FilePath gn_file_for_test_;
+  std::map<std::string, bool> checked_dependencies_;
 };
 
 #endif  // TOOLS_TRAFFIC_ANNOTATION_AUDITOR_TRAFFIC_ANNOTATION_AUDITOR_H_
\ No newline at end of file
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc
index c1eb252..970b7ffe 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc
+++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc
@@ -199,12 +199,12 @@
   }
 
   // Dump Errors and Warnings to stdout.
-  // TODO(rhalavati@): The outputs are now limited to syntax errors. Will be
-  // expanded when repository is full compatible.
   const std::vector<AuditorResult>& errors = auditor.errors();
   for (const auto& error : errors) {
-    if (error.type() == AuditorResult::ResultType::ERROR_SYNTAX)
-      printf("Error: %s\n", error.ToText().c_str());
+    printf("%s: %s\n",
+           error.type() == AuditorResult::ResultType::ERROR_SYNTAX ? "Error"
+                                                                   : "Warning",
+           error.ToText().c_str());
   }
 
   return 0;
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc
index 5241b1e..698e91f5 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc
+++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc
@@ -5,10 +5,13 @@
 #include "tools/traffic_annotation/auditor/traffic_annotation_auditor.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/memory/ptr_util.h"
 #include "base/path_service.h"
+#include "base/stl_util.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "tools/traffic_annotation/auditor/traffic_annotation_file_filter.h"
 
@@ -55,6 +58,9 @@
   AuditorResult::ResultType Deserialize(const std::string& file_name,
                                         InstanceBase* instance);
 
+  // Creates a complete annotation instance using sample files.
+  std::unique_ptr<AnnotationInstance> CreateAnnotationInstanceSample();
+
  private:
   base::FilePath source_path_;
   base::FilePath build_path_;  // Currently stays empty. Will be set if access
@@ -78,6 +84,17 @@
   return instance->Deserialize(lines, 0, static_cast<int>(lines.size())).type();
 }
 
+std::unique_ptr<AnnotationInstance>
+TrafficAnnotationAuditorTest::CreateAnnotationInstanceSample() {
+  std::unique_ptr<AnnotationInstance> instance =
+      base::MakeUnique<AnnotationInstance>();
+  if (Deserialize("good_complete_annotation.txt", instance.get()) !=
+      AuditorResult::ResultType::RESULT_OK) {
+    instance.reset();
+  }
+  return instance;
+}
+
 // Tests if the two hash computation functions have the same result.
 TEST_F(TrafficAnnotationAuditorTest, HashFunctionCheck) {
   TEST_HASH_CODE("test");
@@ -93,7 +110,7 @@
 // TrafficAnnotationFileFilter::IsFileRelevant.
 TEST_F(TrafficAnnotationAuditorTest, GetFilesFromGit) {
   TrafficAnnotationFileFilter filter;
-  filter.SetGitMockFileForTesting(
+  filter.SetGitFileForTest(
       tests_folder().Append(FILE_PATH_LITERAL("git_list.txt")));
   filter.GetFilesFromGit(source_path());
 
@@ -101,13 +118,11 @@
 
   EXPECT_EQ(git_files.size(), arraysize(kRelevantFiles));
   for (const char* filepath : kRelevantFiles) {
-    EXPECT_NE(std::find(git_files.begin(), git_files.end(), filepath),
-              git_files.end());
+    EXPECT_TRUE(base::ContainsValue(git_files, filepath));
   }
 
   for (const char* filepath : kIrrelevantFiles) {
-    EXPECT_EQ(std::find(git_files.begin(), git_files.end(), filepath),
-              git_files.end());
+    EXPECT_FALSE(base::ContainsValue(git_files, filepath));
   }
 }
 
@@ -115,7 +130,7 @@
 // of files, given a mock git list file.
 TEST_F(TrafficAnnotationAuditorTest, RelevantFilesReceived) {
   TrafficAnnotationFileFilter filter;
-  filter.SetGitMockFileForTesting(
+  filter.SetGitFileForTest(
       tests_folder().Append(FILE_PATH_LITERAL("git_list.txt")));
   filter.GetFilesFromGit(source_path());
 
@@ -133,8 +148,7 @@
   file_paths.clear();
   filter.GetRelevantFiles(base::FilePath(), ignore_list, "", &file_paths);
   EXPECT_EQ(file_paths.size(), git_files_count - 1);
-  EXPECT_EQ(std::find(file_paths.begin(), file_paths.end(), ignore_list[0]),
-            file_paths.end());
+  EXPECT_FALSE(base::ContainsValue(file_paths, ignore_list[0]));
 
   // Check if files are filtered based on given directory.
   ignore_list.clear();
@@ -265,12 +279,32 @@
   }
 }
 
+// Tests if TrafficAnnotationAuditor::GetReservedUniqueIDs has all known ids and
+// they have correct text.
+TEST_F(TrafficAnnotationAuditorTest, GetReservedUniqueIDs) {
+  int expected_ids[] = {
+      TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code,
+      PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code,
+      NO_TRAFFIC_ANNOTATION_YET.unique_id_hash_code,
+      NO_PARTIAL_TRAFFIC_ANNOTATION_YET.unique_id_hash_code,
+      MISSING_TRAFFIC_ANNOTATION.unique_id_hash_code};
+
+  std::map<int, std::string> reserved_words =
+      TrafficAnnotationAuditor::GetReservedUniqueIDs();
+
+  for (int id : expected_ids) {
+    EXPECT_TRUE(base::ContainsKey(reserved_words, id));
+    EXPECT_EQ(id, TrafficAnnotationAuditor::ComputeHashValue(
+                      reserved_words.find(id)->second));
+  }
+}
+
 // Tests if TrafficAnnotationAuditor::CheckDuplicateHashes works as expected.
 TEST_F(TrafficAnnotationAuditorTest, CheckDuplicateHashes) {
   // Load a valid annotation.
-  AnnotationInstance test_case;
-  EXPECT_EQ(Deserialize("good_complete_annotation.txt", &test_case),
-            AuditorResult::ResultType::RESULT_OK);
+  std::unique_ptr<AnnotationInstance> instance =
+      CreateAnnotationInstanceSample();
+  EXPECT_TRUE(instance != nullptr);
 
   const std::map<int, std::string>& reserved_words =
       TrafficAnnotationAuditor::GetReservedUniqueIDs();
@@ -280,8 +314,8 @@
 
   // Check for reserved words hash code duplication errors.
   for (const auto& reserved_word : reserved_words) {
-    test_case.unique_id_hash_code = reserved_word.first;
-    annotations.push_back(test_case);
+    instance->unique_id_hash_code = reserved_word.first;
+    annotations.push_back(*instance);
   }
 
   auditor.SetExtractedAnnotationsForTest(annotations);
@@ -296,9 +330,9 @@
   annotations.clear();
   for (int i = 0; i < 10; i++) {
     // Ensure that the test id is not a reserved hash code.
-    EXPECT_EQ(reserved_words.find(i), reserved_words.end());
-    test_case.unique_id_hash_code = i;
-    annotations.push_back(test_case);
+    EXPECT_FALSE(base::ContainsKey(reserved_words, i));
+    instance->unique_id_hash_code = i;
+    annotations.push_back(*instance);
   }
   auditor.SetExtractedAnnotationsForTest(annotations);
   auditor.ClearErrorsForTest();
@@ -308,9 +342,9 @@
   // Check if repeating the same hash codes results in errors.
   annotations.clear();
   for (int i = 0; i < 10; i++) {
-    test_case.unique_id_hash_code = i;
-    annotations.push_back(test_case);
-    annotations.push_back(test_case);
+    instance->unique_id_hash_code = i;
+    annotations.push_back(*instance);
+    annotations.push_back(*instance);
   }
   auditor.SetExtractedAnnotationsForTest(annotations);
   auditor.ClearErrorsForTest();
@@ -321,3 +355,90 @@
               AuditorResult::ResultType::ERROR_DUPLICATE_UNIQUE_ID_HASH_CODE);
   }
 }
+
+// Tests if TrafficAnnotationAuditor::CheckUniqueIDsFormat results are as
+// expected.
+TEST_F(TrafficAnnotationAuditorTest, CheckUniqueIDsFormat) {
+  std::map<std::string, bool> test_cases = {
+      {"ID1", true},   {"id2", true},   {"Id_3", true},
+      {"ID?4", false}, {"ID:5", false}, {"ID>>6", false},
+  };
+
+  TrafficAnnotationAuditor auditor(source_path(), build_path());
+  std::vector<AnnotationInstance> annotations;
+  std::vector<AnnotationInstance> all_annotations;
+  std::unique_ptr<AnnotationInstance> instance =
+      CreateAnnotationInstanceSample();
+  EXPECT_TRUE(instance != nullptr);
+  unsigned int false_samples_count = 0;
+
+  // Test cases one by one.
+  for (const auto& test_case : test_cases) {
+    instance->proto.set_unique_id(test_case.first);
+    annotations.clear();
+    annotations.push_back(*instance);
+    all_annotations.push_back(*instance);
+    auditor.SetExtractedAnnotationsForTest(annotations);
+    auditor.ClearErrorsForTest();
+    auditor.CheckUniqueIDsFormat();
+    EXPECT_EQ(auditor.errors().size(), test_case.second ? 0u : 1u);
+    if (!test_case.second)
+      false_samples_count++;
+  }
+
+  // Test all cases together.
+  auditor.SetExtractedAnnotationsForTest(all_annotations);
+  auditor.ClearErrorsForTest();
+  auditor.CheckUniqueIDsFormat();
+  EXPECT_EQ(auditor.errors().size(), false_samples_count);
+}
+
+// Tests if TrafficAnnotationAuditor::CheckAllRequiredFunctionsAreAnnotated
+// results are as expected. It also inherently checks
+// TrafficAnnotationAuditor::CheckIfCallCanBeUnannotated.
+TEST_F(TrafficAnnotationAuditorTest, CheckAllRequiredFunctionsAreAnnotated) {
+  std::string file_paths[] = {"net/url_request/url_fetcher.cc",
+                              "net/url_request/url_request_context.cc",
+                              "net/url_request/other_file.cc",
+                              "somewhere_else.cc"};
+  std::string function_names[] = {"net::URLFetcher::Create",
+                                  "net::URLRequestContext::CreateRequest",
+                                  "SSLClientSocket", "Something else", ""};
+
+  TrafficAnnotationAuditor auditor(source_path(), build_path());
+  std::vector<CallInstance> calls(1);
+  CallInstance& call = calls[0];
+
+  for (const std::string& file_path : file_paths) {
+    for (const std::string& function_name : function_names) {
+      for (int annotated = 0; annotated < 2; annotated++) {
+        for (int dependent = 0; dependent < 2; dependent++) {
+          call.file_path = file_path;
+          call.function_name = function_name;
+          call.is_annotated = annotated;
+          auditor.SetGnFileForTest(tests_folder().Append(
+              dependent ? FILE_PATH_LITERAL("gn_list_positive.txt")
+                        : FILE_PATH_LITERAL("gn_list_negative.txt")));
+
+          auditor.ClearErrorsForTest();
+          auditor.SetExtractedCallsForTest(calls);
+          auditor.ClearCheckedDependenciesForTest();
+          auditor.CheckAllRequiredFunctionsAreAnnotated();
+          // Error should be issued if a function is not annotated,
+          // chrome::chrome depends on it, the filepath is not whitelisted, and
+          // function name is either of the two specified ones.
+          EXPECT_EQ(
+              auditor.errors().size() == 1,
+              !annotated && dependent &&
+                  file_path != "net/url_request/url_fetcher.cc" &&
+                  file_path != "net/url_request/url_request_context.cc" &&
+                  (function_name == "net::URLFetcher::Create" ||
+                   function_name == "net::URLRequestContext::CreateRequest"))
+              << "The conditions for generating an error for missing "
+                 "annotation do not match the returned number of errors by "
+                 "auditor.";
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc b/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc
index 046330c6..216d8ea 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc
+++ b/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc
@@ -61,7 +61,7 @@
   base::SetCurrentDirectory(source_path);
 
   std::string git_list;
-  if (git_mock_file_for_testing_.empty()) {
+  if (git_file_for_test_.empty()) {
     const base::CommandLine::CharType* args[] =
 #if defined(OS_WIN)
         {FILE_PATH_LITERAL("git.bat"), FILE_PATH_LITERAL("ls-files")};
@@ -76,9 +76,9 @@
       git_list.clear();
     }
   } else {
-    if (!base::ReadFileToString(git_mock_file_for_testing_, &git_list)) {
+    if (!base::ReadFileToString(git_file_for_test_, &git_list)) {
       LOG(ERROR) << "Could not load mock git list file from "
-                 << git_mock_file_for_testing_.MaybeAsASCII().c_str();
+                 << git_file_for_test_.MaybeAsASCII().c_str();
       git_list.clear();
     }
   }
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_file_filter.h b/tools/traffic_annotation/auditor/traffic_annotation_file_filter.h
index 5b89eda..3f0d6b4 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_file_filter.h
+++ b/tools/traffic_annotation/auditor/traffic_annotation_file_filter.h
@@ -39,15 +39,15 @@
 
   // Sets the path to a file that would be used to mock the output of
   // 'git ls-files' in tests.
-  void SetGitMockFileForTesting(const base::FilePath& file_path) {
-    git_mock_file_for_testing_ = file_path;
+  void SetGitFileForTest(const base::FilePath& file_path) {
+    git_file_for_test_ = file_path;
   }
 
   const std::vector<std::string>& git_files() { return git_files_; }
 
  private:
   std::vector<std::string> git_files_;
-  base::FilePath git_mock_file_for_testing_;
+  base::FilePath git_file_for_test_;
 };
 
 #endif  // TRAFFIC_ANNOTATION_FILE_FILTER_H_
\ No newline at end of file
diff --git a/ui/android/display_android_manager.cc b/ui/android/display_android_manager.cc
index 6c68b47..4904bc8 100644
--- a/ui/android/display_android_manager.cc
+++ b/ui/android/display_android_manager.cc
@@ -84,7 +84,8 @@
     jfloat dipScale,
     jint rotationDegrees,
     jint bitsPerPixel,
-    jint bitsPerComponent) {
+    jint bitsPerComponent,
+    jboolean isWideColorGamut) {
   gfx::Rect bounds_in_pixels = gfx::Rect(width, height);
   const gfx::Rect bounds_in_dip = gfx::Rect(
       gfx::ScaleToCeiledSize(bounds_in_pixels.size(), 1.0f / dipScale));
@@ -92,10 +93,12 @@
   display::Display display(sdkDisplayId, bounds_in_dip);
   if (!Display::HasForceDeviceScaleFactor())
     display.set_device_scale_factor(dipScale);
-  // TODO(ccameron): Know the ideal color profile to use here.
-  // https://crbug.com/735658
-  if (!Display::HasForceColorProfile())
-    display.set_color_space(gfx::ColorSpace::CreateSRGB());
+  if (!Display::HasForceColorProfile()) {
+    if (isWideColorGamut)
+      display.set_color_space(gfx::ColorSpace::CreateDisplayP3D65());
+    else
+      display.set_color_space(gfx::ColorSpace::CreateSRGB());
+  }
 
   display.set_size_in_pixels(bounds_in_pixels.size());
   display.SetRotationAsDegree(rotationDegrees);
diff --git a/ui/android/display_android_manager.h b/ui/android/display_android_manager.h
index 77ded26..ff49096b 100644
--- a/ui/android/display_android_manager.h
+++ b/ui/android/display_android_manager.h
@@ -37,7 +37,8 @@
                      jfloat dipScale,
                      jint rotationDegrees,
                      jint bitsPerPixel,
-                     jint bitsPerComponent);
+                     jint bitsPerComponent,
+                     jboolean isWideColorGamut);
   void RemoveDisplay(JNIEnv* env,
                      const base::android::JavaParamRef<jobject>& jobject,
                      jint sdkDisplayId);
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
index aa15a9c..839c1e4 100644
--- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -14,11 +14,11 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Process;
-import android.util.Log;
 import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
@@ -26,8 +26,10 @@
 import android.view.accessibility.AccessibilityManager;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.BuildInfo;
 import org.chromium.base.Callback;
 import org.chromium.base.ContextUtils;
+import org.chromium.base.Log;
 import org.chromium.base.ObserverList;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
@@ -37,6 +39,8 @@
 import org.chromium.ui.widget.Toast;
 
 import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -211,6 +215,19 @@
         mAccessibilityManager = (AccessibilityManager) mApplicationContext.getSystemService(
                 Context.ACCESSIBILITY_SERVICE);
         mDisplayAndroid = display;
+        // Configuration.isDisplayServerWideColorGamut must be queried from the window's context.
+        // TODO(boliu): Observe configuration changes to update the value of isScreenWideColorGamut.
+        if (BuildInfo.isAtLeastO() && activityFromContext(context) != null) {
+            Configuration configuration = context.getResources().getConfiguration();
+            boolean isScreenWideColorGamut = false;
+            try {
+                Method method = configuration.getClass().getMethod("isScreenWideColorGamut");
+                isScreenWideColorGamut = (Boolean) method.invoke(configuration);
+            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+                Log.e(TAG, "Error invoking isScreenWideColorGamut:", e);
+            }
+            display.updateIsDisplayServerWideColorGamut(isScreenWideColorGamut);
+        }
     }
 
     @CalledByNative
diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java b/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java
index 7bb8990..28a6082 100644
--- a/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java
@@ -50,6 +50,8 @@
     private int mBitsPerPixel;
     private int mBitsPerComponent;
     private int mRotation;
+    protected boolean mIsDisplayWideColorGamut;
+    protected boolean mIsDisplayServerWideColorGamut;
 
     protected static DisplayAndroidManager getManager() {
         return DisplayAndroidManager.getInstance();
@@ -146,6 +148,13 @@
     }
 
     /**
+     * @return Whether or not it is possible to use wide color gamut rendering with this display.
+     */
+    public boolean getIsWideColorGamut() {
+        return mIsDisplayWideColorGamut && mIsDisplayServerWideColorGamut;
+    }
+
+    /**
      * Add observer. Note repeat observers will be called only one.
      * Observers are held only weakly by Display.
      */
@@ -187,11 +196,16 @@
         return mObservers.keySet().toArray(EMPTY_OBSERVER_ARRAY);
     }
 
+    public void updateIsDisplayServerWideColorGamut(Boolean isDisplayServerWideColorGamut) {
+        update(null, null, null, null, null, null, isDisplayServerWideColorGamut);
+    }
+
     /**
      * Update the display to the provided parameters. Null values leave the parameter unchanged.
      */
     protected void update(Point size, Float dipScale, Integer bitsPerPixel,
-            Integer bitsPerComponent, Integer rotation) {
+            Integer bitsPerComponent, Integer rotation, Boolean isDisplayWideColorGamut,
+            Boolean isDisplayServerWideColorGamut) {
         boolean sizeChanged = size != null && !mSize.equals(size);
         // Intentional comparison of floats: we assume that if scales differ, they differ
         // significantly.
@@ -200,9 +214,14 @@
         boolean bitsPerComponentChanged =
                 bitsPerComponent != null && mBitsPerComponent != bitsPerComponent;
         boolean rotationChanged = rotation != null && mRotation != rotation;
+        boolean isDisplayWideColorGamutChanged = isDisplayWideColorGamut != null
+                && mIsDisplayWideColorGamut != isDisplayWideColorGamut;
+        boolean isDisplayServerWideColorGamutChanged = isDisplayServerWideColorGamut != null
+                && mIsDisplayServerWideColorGamut != isDisplayServerWideColorGamut;
 
         boolean changed = sizeChanged || dipScaleChanged || bitsPerPixelChanged
-                || bitsPerComponentChanged || rotationChanged;
+                || bitsPerComponentChanged || rotationChanged || isDisplayWideColorGamutChanged
+                || isDisplayServerWideColorGamutChanged;
         if (!changed) return;
 
         if (sizeChanged) mSize = size;
@@ -210,6 +229,10 @@
         if (bitsPerPixelChanged) mBitsPerPixel = bitsPerPixel;
         if (bitsPerComponentChanged) mBitsPerComponent = bitsPerComponent;
         if (rotationChanged) mRotation = rotation;
+        if (isDisplayWideColorGamutChanged) mIsDisplayWideColorGamut = isDisplayWideColorGamut;
+        if (isDisplayServerWideColorGamutChanged) {
+            mIsDisplayServerWideColorGamut = isDisplayServerWideColorGamut;
+        }
 
         getManager().updateDisplayOnNativeSide(this);
         if (rotationChanged) {
diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java
index dc6abde9..4d57541 100644
--- a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java
+++ b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java
@@ -314,12 +314,13 @@
         nativeUpdateDisplay(mNativePointer, displayAndroid.getDisplayId(),
                 displayAndroid.getDisplayWidth(), displayAndroid.getDisplayHeight(),
                 displayAndroid.getDipScale(), displayAndroid.getRotationDegrees(),
-                displayAndroid.getBitsPerPixel(), displayAndroid.getBitsPerComponent());
+                displayAndroid.getBitsPerPixel(), displayAndroid.getBitsPerComponent(),
+                displayAndroid.getIsWideColorGamut());
     }
 
     private native void nativeUpdateDisplay(long nativeDisplayAndroidManager, int sdkDisplayId,
             int width, int height, float dipScale, int rotationDegrees, int bitsPerPixel,
-            int bitsPerComponent);
+            int bitsPerComponent, boolean isWideColorGamut);
     private native void nativeRemoveDisplay(long nativeDisplayAndroidManager, int sdkDisplayId);
     private native void nativeSetPrimaryDisplayId(
             long nativeDisplayAndroidManager, int sdkDisplayId);
diff --git a/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java b/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java
index 5ec32050..cc8a250 100644
--- a/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java
@@ -11,9 +11,13 @@
 import android.util.DisplayMetrics;
 import android.view.Display;
 
+import org.chromium.base.BuildInfo;
 import org.chromium.base.CommandLine;
 import org.chromium.base.Log;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
 /**
  * A DisplayAndroid implementation tied to a physical Display.
  */
@@ -101,6 +105,15 @@
             display.getMetrics(displayMetrics);
         }
         if (hasForcedDIPScale()) displayMetrics.density = sForcedDIPScale.floatValue();
+        boolean isWideColorGamut = false;
+        if (BuildInfo.isAtLeastO()) {
+            try {
+                Method method = display.getClass().getMethod("isWideColorGamut");
+                isWideColorGamut = (Boolean) method.invoke(display);
+            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+                Log.e(TAG, "Error invoking isWideColorGamut:", e);
+            }
+        }
 
         // JellyBean MR1 and later always uses RGBA_8888.
         int pixelFormatId = (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
@@ -108,6 +121,6 @@
                 : PixelFormat.RGBA_8888;
         PixelFormat.getPixelFormatInfo(pixelFormatId, pixelFormat);
         super.update(size, displayMetrics.density, pixelFormat.bitsPerPixel,
-                bitsPerComponent(pixelFormatId), display.getRotation());
+                bitsPerComponent(pixelFormatId), display.getRotation(), isWideColorGamut, null);
     }
 }
diff --git a/ui/android/java/src/org/chromium/ui/display/VirtualDisplayAndroid.java b/ui/android/java/src/org/chromium/ui/display/VirtualDisplayAndroid.java
index 2bfcb412..740087de 100644
--- a/ui/android/java/src/org/chromium/ui/display/VirtualDisplayAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/display/VirtualDisplayAndroid.java
@@ -23,13 +23,16 @@
      */
     public void setTo(DisplayAndroid other) {
         update(new Point(other.getDisplayWidth(), other.getDisplayHeight()), other.getDipScale(),
-                other.getBitsPerPixel(), other.getBitsPerComponent(), other.getRotation());
+                other.getBitsPerPixel(), other.getBitsPerComponent(), other.getRotation(),
+                other.mIsDisplayWideColorGamut, other.mIsDisplayServerWideColorGamut);
     }
 
     @Override
     public void update(Point size, Float dipScale, Integer bitsPerPixel, Integer bitsPerComponent,
-            Integer rotation) {
-        super.update(size, dipScale, bitsPerPixel, bitsPerComponent, rotation);
+            Integer rotation, Boolean isDisplayWideColorGamut,
+            Boolean isDisplayServerWideColorGamut) {
+        super.update(size, dipScale, bitsPerPixel, bitsPerComponent, rotation,
+                isDisplayWideColorGamut, isDisplayServerWideColorGamut);
     }
 
     /**
diff --git a/ui/aura/env.cc b/ui/aura/env.cc
index 0dd794a..4493d68 100644
--- a/ui/aura/env.cc
+++ b/ui/aura/env.cc
@@ -174,11 +174,7 @@
   // The ozone platform can provide its own event source. So initialize the
   // platform before creating the default event source. If running inside mus
   // let the mus process initialize ozone instead.
-  ui::OzonePlatform::InitParams params;
-  // TODO(kylechar): |params.single_process| should be set correctly here, but
-  // both tests and real code both use aura::Init::CreateInstance() identically.
-  params.single_process = false;
-  ui::OzonePlatform::InitializeForUI(params);
+  ui::OzonePlatform::InitializeForUI();
   gfx::ClientNativePixmapFactory::SetInstance(native_pixmap_factory_.get());
 #endif
   if (!ui::PlatformEventSource::GetInstance())
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc
index 1844a7de..48219f0 100644
--- a/ui/aura/window_tree_host.cc
+++ b/ui/aura/window_tree_host.cc
@@ -223,13 +223,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 // WindowTreeHost, protected:
 
-WindowTreeHost::WindowTreeHost() : WindowTreeHost(nullptr) {}
+WindowTreeHost::WindowTreeHost() : WindowTreeHost(nullptr) {
+  display::Screen::GetScreen()->AddObserver(this);
+}
 
 WindowTreeHost::WindowTreeHost(std::unique_ptr<WindowPort> window_port)
     : window_(new Window(nullptr, std::move(window_port))),
       last_cursor_(ui::CursorType::kNull),
       input_method_(nullptr),
-      owned_input_method_(false) {}
+      owned_input_method_(false) {
+  display::Screen::GetScreen()->RemoveObserver(this);
+}
 
 void WindowTreeHost::DestroyCompositor() {
   compositor_.reset();
@@ -340,6 +344,22 @@
   return dispatcher_.get();
 }
 
+void WindowTreeHost::OnDisplayAdded(const display::Display& new_display) {}
+
+void WindowTreeHost::OnDisplayRemoved(const display::Display& old_display) {}
+
+void WindowTreeHost::OnDisplayMetricsChanged(const display::Display& display,
+                                             uint32_t metrics) {
+  display::Screen* screen = display::Screen::GetScreen();
+  if (display.id() != screen->GetDisplayNearestView(window()).id())
+    return;
+
+  if (metrics & DisplayObserver::DISPLAY_METRIC_COLOR_SPACE) {
+    if (compositor_)
+      compositor_->SetDisplayColorSpace(display.color_space());
+  }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // WindowTreeHost, private:
 
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h
index 002c9f2..f0757f56 100644
--- a/ui/aura/window_tree_host.h
+++ b/ui/aura/window_tree_host.h
@@ -15,6 +15,7 @@
 #include "ui/aura/aura_export.h"
 #include "ui/base/cursor/cursor.h"
 #include "ui/base/ime/input_method_delegate.h"
+#include "ui/display/display_observer.h"
 #include "ui/events/event_source.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/native_widget_types.h"
@@ -47,7 +48,8 @@
 // It provides the accelerated widget and maps events from the native os to
 // aura.
 class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
-                                   public ui::EventSource {
+                                   public ui::EventSource,
+                                   public display::DisplayObserver {
  public:
   ~WindowTreeHost() override;
 
@@ -227,6 +229,12 @@
   // Overridden from ui::EventSource:
   ui::EventSink* GetEventSink() override;
 
+  // display::DisplayObserver implementation.
+  void OnDisplayAdded(const display::Display& new_display) override;
+  void OnDisplayRemoved(const display::Display& old_display) override;
+  void OnDisplayMetricsChanged(const display::Display& display,
+                               uint32_t metrics) override;
+
  private:
   friend class test::WindowTreeHostTestApi;
 
diff --git a/ui/compositor/test/test_suite.cc b/ui/compositor/test/test_suite.cc
index 66a9c82..b9ec38b 100644
--- a/ui/compositor/test/test_suite.cc
+++ b/ui/compositor/test/test_suite.cc
@@ -35,9 +35,7 @@
   gl::GLSurfaceTestSupport::InitializeOneOff();
 
 #if defined(USE_OZONE)
-  ui::OzonePlatform::InitParams params;
-  params.single_process = true;
-  ui::OzonePlatform::InitializeForUI(params);
+  ui::OzonePlatform::InitializeForUI();
 #endif
 
   gfx::RegisterPathProvider();
diff --git a/ui/display/display_list.cc b/ui/display/display_list.cc
index 74eb5c9b..9edacb7 100644
--- a/ui/display/display_list.cc
+++ b/ui/display/display_list.cc
@@ -93,6 +93,10 @@
     local_display->set_device_scale_factor(display.device_scale_factor());
     changed_values |= DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
   }
+  if (local_display->color_space() != display.color_space()) {
+    local_display->set_color_space(display.color_space());
+    changed_values |= DisplayObserver::DISPLAY_METRIC_COLOR_SPACE;
+  }
   if (should_notify_observers()) {
     for (DisplayObserver& observer : observers_)
       observer.OnDisplayMetricsChanged(*local_display, changed_values);
diff --git a/ui/file_manager/file_manager/background/js/test_util_base.js b/ui/file_manager/file_manager/background/js/test_util_base.js
index 97446023..f7d25584 100644
--- a/ui/file_manager/file_manager/background/js/test_util_base.js
+++ b/ui/file_manager/file_manager/background/js/test_util_base.js
@@ -334,17 +334,33 @@
  * Sends an event to the element specified by |targetQuery| or active element.
  *
  * @param {Window} contentWindow Window to be tested.
- * @param {?string} targetQuery Query to specify the element. If this value is
- *     null, an event is dispatched to active element of the document.
+ * @param {?string|Array<string>} targetQuery Query to specify the element.
+ *     If this value is null, an event is dispatched to active element of the
+ *     document.
+ *     If targetQuery is an array, |targetQuery[0]| specifies the first
+ *     element(s), |targetQuery[1]| specifies elements inside the shadow DOM of
+ *     the first element, and so on.
  * @param {!Event} event Event to be sent.
  * @param {string=} opt_iframeQuery Optional iframe selector.
  * @return {boolean} True if the event is sent to the target, false otherwise.
  */
 test.util.sync.sendEvent = function(
     contentWindow, targetQuery, event, opt_iframeQuery) {
-  var target = targetQuery === null ?
-      contentWindow.document.activeElement :
-      test.util.sync.getElement_(contentWindow, targetQuery, opt_iframeQuery);
+  var target;
+  if (targetQuery === null) {
+    target = contentWindow.document.activeElement;
+  } else if (typeof targetQuery === 'string') {
+    target =
+        test.util.sync.getElement_(contentWindow, targetQuery, opt_iframeQuery);
+  } else if (Array.isArray(targetQuery)) {
+    var doc = test.util.sync.getDocument_(
+        contentWindow, opt_iframeQuery || undefined);
+    if (doc) {
+      var elems = test.util.sync.deepQuerySelectorAll_(doc, targetQuery);
+      if (elems.length > 0)
+        target = elems[0];
+    }
+  }
 
   if (!target)
     return false;
@@ -415,7 +431,10 @@
  * events in turns.
  *
  * @param {Window} contentWindow Window to be tested.
- * @param {string} targetQuery Query to specify the element.
+ * @param {string|Array<string>} targetQuery Query to specify the element.
+ *     If targetQuery is an array, |targetQuery[0]| specifies the first
+ *     element(s), |targetQuery[1]| specifies elements inside the shadow DOM of
+ *     the first element, and so on.
  * @param {string=} opt_iframeQuery Optional iframe selector.
  * @return {boolean} True if the all events are sent to the target, false
  *     otherwise.
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js
index 7a602e92d..7d45f8d 100644
--- a/ui/file_manager/integration_tests/file_manager/quick_view.js
+++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -4,18 +4,9 @@
 
 'use strict';
 
-/**
- * Tests opening the Quick View.
- */
-testcase.openQuickView = function() {
-  var appId;
-
-  StepsRunner.run([
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
-    },
+function openQuickViewSteps(appId) {
+  return [
     function(results) {
-      appId = results.windowId;
       // Select an image file.
       remoteCall.callRemoteTestUtil(
           'selectFile', appId, ['My Desktop Background.png'], this.next);
@@ -52,5 +43,66 @@
 
       checkIfNoErrorsOccured(this.next);
     },
-  ]);
+    function() {
+      // Wait until Quick View is displayed.
+      repeatUntil(function() {
+        return remoteCall
+            .callRemoteTestUtil(
+                'deepQueryAllElements', appId,
+                [['#quick-view', '#dialog'], null, ['display']])
+            .then(function(results) {
+              if (results.length === 0 ||
+                  results[0].styles.display === 'none') {
+                return pending('Quick View is not opened yet.');
+              };
+              return results;
+            });
+      }).then(this.next);
+    },
+  ];
+}
+
+function closeQuickViewSteps(appId) {
+  return [
+    function() {
+      return remoteCall.callRemoteTestUtil(
+          'fakeMouseClick', appId, [['#quick-view', '#contentPanel']],
+          this.next);
+    },
+    function(result) {
+      chrome.test.assertEq(true, result);
+      // Wait until Quick View is displayed.
+      repeatUntil(function() {
+        return remoteCall
+            .callRemoteTestUtil(
+                'deepQueryAllElements', appId,
+                [['#quick-view', '#dialog'], null, ['display']])
+            .then(function(results) {
+              if (results.length > 0 && results[0].styles.display !== 'none') {
+                return pending('Quick View is not closed yet.');
+              };
+              return;
+            });
+      }).then(this.next);
+    }
+  ];
+}
+
+/**
+ * Tests opening the Quick View.
+ */
+testcase.openQuickView = function() {
+  setupAndWaitUntilReady(null, RootPath.DOWNLOADS).then(function(results) {
+    StepsRunner.run(openQuickViewSteps(results.windowId));
+  });
+};
+
+/**
+ * Test closing Quick View.
+ */
+testcase.closeQuickView = function() {
+  setupAndWaitUntilReady(null, RootPath.DOWNLOADS).then(function(results) {
+    StepsRunner.run(openQuickViewSteps(results.windowId)
+                        .concat(closeQuickViewSteps(results.windowId)));
+  });
 };
diff --git a/ui/gfx/platform_font_mac.mm b/ui/gfx/platform_font_mac.mm
index 1906c81a..c8ce3bd 100644
--- a/ui/gfx/platform_font_mac.mm
+++ b/ui/gfx/platform_font_mac.mm
@@ -236,7 +236,10 @@
       derived = [font_manager convertWeight:NO ofFont:derived];
   }
 
-  if (style != font_style_) {
+  // Always apply the italic trait, even if the italic trait is not changing.
+  // it's possible for a change in the weight to trigger the font to go italic.
+  // This is due to an AppKit bug. See http://crbug.com/742261.
+  if (style != font_style_ || weight != font_weight_) {
     NSFontTraitMask italic_trait_mask =
         (style & Font::ITALIC) ? NSItalicFontMask : NSUnitalicFontMask;
     derived = [font_manager convertFont:derived toHaveTrait:italic_trait_mask];
diff --git a/ui/gfx/platform_font_mac_unittest.mm b/ui/gfx/platform_font_mac_unittest.mm
index ffc469e..a935e945 100644
--- a/ui/gfx/platform_font_mac_unittest.mm
+++ b/ui/gfx/platform_font_mac_unittest.mm
@@ -330,4 +330,23 @@
   }
 }
 
+// Test to ensure we cater for the AppKit quirk that can make the font italic
+// when asking for a fine-grained weight. See http://crbug.com/742261. Note that
+// Appkit's bug was detected on macOS 10.10 which uses Helvetica Neue as the
+// system font.
+TEST(PlatformFontMacTest, DerivedSemiboldFontIsNotItalic) {
+  gfx::Font base_font;
+  {
+    NSFontTraitMask traits = [[NSFontManager sharedFontManager]
+        traitsOfFont:base_font.GetNativeFont()];
+    ASSERT_FALSE(traits & NSItalicFontMask);
+  }
+
+  gfx::Font semibold_font(
+      base_font.Derive(0, gfx::Font::NORMAL, gfx::Font::Weight::SEMIBOLD));
+  NSFontTraitMask traits = [[NSFontManager sharedFontManager]
+      traitsOfFont:semibold_font.GetNativeFont()];
+  EXPECT_FALSE(traits & NSItalicFontMask);
+}
+
 }  // namespace gfx
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc
index d4e22fd8..f8584a6a 100644
--- a/ui/keyboard/keyboard_controller.cc
+++ b/ui/keyboard/keyboard_controller.cc
@@ -331,7 +331,7 @@
   return container_.get();
 }
 
-void KeyboardController::NotifyKeyboardBoundsChanging(
+void KeyboardController::NotifyContentsBoundsChanging(
     const gfx::Rect& new_bounds) {
   current_keyboard_bounds_ = new_bounds;
   if (ui_->HasContentsWindow() && ui_->GetContentsWindow()->IsVisible()) {
@@ -346,7 +346,7 @@
   }
 }
 
-void KeyboardController::NotifyKeyboardLoadingComplete() {
+void KeyboardController::NotifyContentsLoadingComplete() {
   if (state_ != KeyboardControllerState::LOADING_EXTENSION)
     return;
 
@@ -371,7 +371,7 @@
           keyboard::KEYBOARD_CONTROL_HIDE_AUTO :
           keyboard::KEYBOARD_CONTROL_HIDE_USER);
 
-  NotifyKeyboardBoundsChanging(gfx::Rect());
+  NotifyContentsBoundsChanging(gfx::Rect());
 
   set_keyboard_locked(false);
 
@@ -423,7 +423,7 @@
   // When keyboard is floating, no overscroll or resize is necessary. Sets
   // keyboard bounds to zero so overscroll or resize is disabled.
   if (keyboard_mode_ == FLOATING) {
-    NotifyKeyboardBoundsChanging(gfx::Rect());
+    NotifyContentsBoundsChanging(gfx::Rect());
   } else if (keyboard_mode_ == FULL_WIDTH) {
     AdjustKeyboardBounds();
     // No animation added, so call ShowAnimationFinished immediately.
@@ -691,7 +691,7 @@
 
   // Notify observers after animation finished to prevent reveal desktop
   // background during animation.
-  NotifyKeyboardBoundsChanging(container_->bounds());
+  NotifyContentsBoundsChanging(container_->bounds());
   ui_->EnsureCaretInWorkArea();
   ChangeState(KeyboardControllerState::SHOWN);
 }
@@ -729,13 +729,6 @@
     error_message << "Unexpected transition";
   // TODO(oka): Add more condition check.
 
-  // Emit log on release build too for debug.
-  // TODO(oka): Change this to DLOG_IF once enough data is collected.
-  LOG_IF(ERROR, !error_message.str().empty())
-      << "State: " << StateToStr(prev) << " -> " << StateToStr(next) << " "
-      << error_message.str()
-      << "  stack trace: " << base::debug::StackTrace(10).ToString();
-
   // Emit UMA
   const int transition_record =
       (valid_transition ? 1 : -1) *
@@ -744,6 +737,13 @@
                               transition_record);
   UMA_HISTOGRAM_BOOLEAN("VirtualKeyboard.ControllerStateTransitionIsValid",
                         transition_record > 0);
+
+  // Crash on release build too for debug.
+  // TODO(oka): Change this to DCHECK once enough data is collected.
+  CHECK(error_message.str().empty())
+      << "State: " << StateToStr(prev) << " -> " << StateToStr(next) << " "
+      << error_message.str()
+      << "  stack trace: " << base::debug::StackTrace(10).ToString();
 }
 
 void KeyboardController::ChangeState(KeyboardControllerState state) {
diff --git a/ui/keyboard/keyboard_controller.h b/ui/keyboard/keyboard_controller.h
index 3f25cd6..46fac6c8 100644
--- a/ui/keyboard/keyboard_controller.h
+++ b/ui/keyboard/keyboard_controller.h
@@ -105,8 +105,8 @@
   // when the focus of input field quickly change.
   void HideKeyboard(HideReason reason);
 
-  // Notifies the keyboard observer for keyboard bounds changed.
-  void NotifyKeyboardBoundsChanging(const gfx::Rect& new_bounds);
+  // Notifies the observer for contents bounds changed.
+  void NotifyContentsBoundsChanging(const gfx::Rect& new_bounds);
 
   // Management of the observer list.
   void AddObserver(KeyboardControllerObserver* observer);
@@ -163,7 +163,7 @@
   // For access to Observer methods for simulation.
   friend class KeyboardControllerTest;
 
-  // For access to NotifyKeyboardLoadingComplete.
+  // For access to NotifyContentsLoadingComplete.
   friend class KeyboardLayoutManager;
 
   // aura::WindowObserver overrides
@@ -184,7 +184,7 @@
   void OnShowImeIfNeeded() override;
 
   // Notifies that the extension has completed loading
-  void NotifyKeyboardLoadingComplete();
+  void NotifyContentsLoadingComplete();
 
   // Show virtual keyboard immediately with animation.
   void ShowKeyboardInternal(int64_t display_id);
@@ -225,6 +225,8 @@
   base::ObserverList<KeyboardControllerObserver> observer_list_;
 
   // The currently used keyboard position.
+  // If the contents window is visible, this should be the same size as the
+  // contents window. If not, this should be empty.
   gfx::Rect current_keyboard_bounds_;
 
   KeyboardControllerState state_;
diff --git a/ui/keyboard/keyboard_layout_manager.cc b/ui/keyboard/keyboard_layout_manager.cc
index 5a79dc1d..b118baf 100644
--- a/ui/keyboard/keyboard_layout_manager.cc
+++ b/ui/keyboard/keyboard_layout_manager.cc
@@ -14,35 +14,32 @@
 
 // Overridden from aura::LayoutManager
 void KeyboardLayoutManager::OnWindowResized() {
-  if (keyboard_) {
-    // Container window is the top level window of the virtual keyboard window.
-    // To support window.moveTo for the virtual keyboard window, as it actually
-    // moves the top level window, the container window should be set to the
-    // desired bounds before changing the bounds of the virtual keyboard window.
+  if (contents_window_) {
     gfx::Rect container_bounds = controller_->GetContainerWindow()->bounds();
     // Always align container window and keyboard window.
     if (controller_->keyboard_mode() == FULL_WIDTH) {
-      SetChildBounds(keyboard_, gfx::Rect(container_bounds.size()));
+      SetChildBounds(contents_window_, gfx::Rect(container_bounds.size()));
     } else {
-      SetChildBoundsDirect(keyboard_, gfx::Rect(container_bounds.size()));
+      SetChildBoundsDirect(contents_window_,
+                           gfx::Rect(container_bounds.size()));
     }
   }
 }
 
 void KeyboardLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
-  DCHECK(!keyboard_);
-  keyboard_ = child;
+  DCHECK(!contents_window_);
+  contents_window_ = child;
   if (controller_->keyboard_mode() == FULL_WIDTH) {
     controller_->GetContainerWindow()->SetBounds(gfx::Rect());
   } else if (controller_->keyboard_mode() == FLOATING) {
     controller_->GetContainerWindow()->SetBounds(child->bounds());
-    SetChildBoundsDirect(keyboard_, gfx::Rect(child->bounds().size()));
+    SetChildBoundsDirect(contents_window_, gfx::Rect(child->bounds().size()));
   }
 }
 
 void KeyboardLayoutManager::SetChildBounds(aura::Window* child,
                                            const gfx::Rect& requested_bounds) {
-  DCHECK(child == keyboard_);
+  DCHECK(child == contents_window_);
 
   TRACE_EVENT0("vk", "KeyboardLayoutSetChildBounds");
 
@@ -64,10 +61,9 @@
   // Keyboard bounds should only be reset when it actually changes. Otherwise
   // it interrupts the initial animation of showing the keyboard. Described in
   // crbug.com/356753.
-  gfx::Rect old_bounds = keyboard_->GetTargetBounds();
-  aura::Window::ConvertRectToTarget(keyboard_,
-                                    keyboard_->GetRootWindow(),
-                                    &old_bounds);
+  gfx::Rect old_bounds = contents_window_->GetTargetBounds();
+  aura::Window::ConvertRectToTarget(
+      contents_window_, contents_window_->GetRootWindow(), &old_bounds);
   if (new_bounds == old_bounds)
     return;
 
@@ -78,7 +74,7 @@
     animator->StopAnimating();
 
   controller_->GetContainerWindow()->SetBounds(new_bounds);
-  SetChildBoundsDirect(keyboard_, gfx::Rect(new_bounds.size()));
+  SetChildBoundsDirect(contents_window_, gfx::Rect(new_bounds.size()));
 
   const bool container_had_size = old_bounds.height() != 0;
   const bool child_has_size = child->bounds().height() != 0;
@@ -103,16 +99,16 @@
         !controller_->keyboard_visible()) {
       // When the child is layed out, the controller is not shown, but showing
       // is not desired, this is indicative that the pre-load has completed.
-      controller_->NotifyKeyboardLoadingComplete();
+      controller_->NotifyContentsLoadingComplete();
     }
 
     if (controller_->keyboard_mode() == FULL_WIDTH) {
       // We need to send out this notification only if keyboard is visible since
-      // keyboard window is resized even if keyboard is hidden.
+      // the contents window is resized even if keyboard is hidden.
       if (controller_->keyboard_visible())
-        controller_->NotifyKeyboardBoundsChanging(new_bounds);
+        controller_->NotifyContentsBoundsChanging(new_bounds);
     } else if (controller_->keyboard_mode() == FLOATING) {
-      controller_->NotifyKeyboardBoundsChanging(gfx::Rect());
+      controller_->NotifyContentsBoundsChanging(gfx::Rect());
     }
   }
 }
diff --git a/ui/keyboard/keyboard_layout_manager.h b/ui/keyboard/keyboard_layout_manager.h
index aa036a3..912f9b7 100644
--- a/ui/keyboard/keyboard_layout_manager.h
+++ b/ui/keyboard/keyboard_layout_manager.h
@@ -19,8 +19,7 @@
 class KeyboardLayoutManager : public aura::LayoutManager {
  public:
   explicit KeyboardLayoutManager(KeyboardController* controller)
-      : controller_(controller), keyboard_(NULL) {
-  }
+      : controller_(controller), contents_window_(NULL) {}
 
   // Overridden from aura::LayoutManager
   void OnWindowResized() override;
@@ -34,7 +33,7 @@
 
  private:
   KeyboardController* controller_;
-  aura::Window* keyboard_;
+  aura::Window* contents_window_;
 
   DISALLOW_COPY_AND_ASSIGN(KeyboardLayoutManager);
 };
diff --git a/ui/ozone/demo/ozone_demo.cc b/ui/ozone/demo/ozone_demo.cc
index 8243f33..bf9aa69 100644
--- a/ui/ozone/demo/ozone_demo.cc
+++ b/ui/ozone/demo/ozone_demo.cc
@@ -354,9 +354,7 @@
   base::MessageLoopForUI message_loop;
   base::TaskScheduler::CreateAndStartWithDefaultParams("OzoneDemo");
 
-  ui::OzonePlatform::InitParams params;
-  params.single_process = true;
-  ui::OzonePlatform::InitializeForUI(params);
+  ui::OzonePlatform::InitializeForUI();
   ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()
       ->SetCurrentLayoutByName("us");
 
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc
index 4463c6a..83bd63d 100644
--- a/ui/ozone/public/ozone_platform.cc
+++ b/ui/ozone/public/ozone_platform.cc
@@ -32,6 +32,12 @@
 }
 
 // static
+void OzonePlatform::InitializeForUI() {
+  const InitParams params;
+  OzonePlatform::InitializeForUI(params);
+}
+
+// static
 void OzonePlatform::InitializeForUI(const InitParams& args) {
   EnsureInstance();
   if (g_platform_initialized_ui)
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h
index 3b17c885..a6f87c7 100644
--- a/ui/ozone/public/ozone_platform.h
+++ b/ui/ozone/public/ozone_platform.h
@@ -79,6 +79,11 @@
   static OzonePlatform* EnsureInstance();
 
   // Initializes the subsystems/resources necessary for the UI process (e.g.
+  // events, etc.)
+  // TODO(rjkroege): Remove deprecated entry point (http://crbug.com/620934)
+  static void InitializeForUI();
+
+  // Initializes the subsystems/resources necessary for the UI process (e.g.
   // events) with additional properties to customize the ozone platform
   // implementation. Ozone will not retain InitParams after returning from
   // InitalizeForUI.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index ef1fbbf..44dc502 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -166,7 +166,6 @@
       modal_dialog_counter_(0),
       close_widget_factory_(this),
       weak_factory_(this) {
-  display::Screen::GetScreen()->AddObserver(this);
 }
 
 DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() {
@@ -174,7 +173,6 @@
   wm::SetWindowMoveClient(window(), NULL);
   desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this);
   DestroyDispatcher();
-  display::Screen::GetScreen()->RemoveObserver(this);
 }
 
 // static
@@ -1302,15 +1300,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 // DesktopWindowTreeHostX11, display::DisplayObserver implementation:
 
-void DesktopWindowTreeHostX11::OnDisplayAdded(
-    const display::Display& new_display) {}
-
-void DesktopWindowTreeHostX11::OnDisplayRemoved(
-    const display::Display& old_display) {}
-
 void DesktopWindowTreeHostX11::OnDisplayMetricsChanged(
     const display::Display& display,
     uint32_t changed_metrics) {
+  aura::WindowTreeHost::OnDisplayMetricsChanged(display, changed_metrics);
+
   if ((changed_metrics & DISPLAY_METRIC_DEVICE_SCALE_FACTOR) &&
       display::Screen::GetScreen()->GetDisplayNearestWindow(window()).id() ==
           display.id()) {
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index de7fd801..cb18967 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -18,7 +18,6 @@
 #include "ui/aura/scoped_window_targeter.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/cursor/cursor_loader_x11.h"
-#include "ui/display/display_observer.h"
 #include "ui/events/platform/platform_event_dispatcher.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/geometry/rect.h"
@@ -45,8 +44,7 @@
 class VIEWS_EXPORT DesktopWindowTreeHostX11
     : public DesktopWindowTreeHost,
       public aura::WindowTreeHost,
-      public ui::PlatformEventDispatcher,
-      public display::DisplayObserver {
+      public ui::PlatformEventDispatcher {
  public:
   DesktopWindowTreeHostX11(
       internal::NativeWidgetDelegate* native_widget_delegate,
@@ -171,9 +169,7 @@
       const gfx::Point& location_in_pixels) override;
   void OnCursorVisibilityChangedNative(bool show) override;
 
-  // Overridden from display::DisplayObserver:
-  void OnDisplayAdded(const display::Display& new_display) override;
-  void OnDisplayRemoved(const display::Display& old_display) override;
+  // Overridden from display::DisplayObserver via aura::WindowTreeHost:
   void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t changed_metrics) override;
 
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html
index 1ca72f5..f3c89c62 100644
--- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html
+++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html
@@ -80,7 +80,8 @@
         <template is="dom-repeat" items="[[defaultImages]]">
           <img role="radio"
               data-type$="[[selectionTypesEnum_.DEFAULT]]"
-              data-index$="[[index]]" src="[[item.url]]" title="[[item.title]]">
+              data-index$="[[index]]" src="[[item.url]]"
+              srcset="[[getImgSrc2x_(item.url)]]" title="[[item.title]]">
         </template>
       </iron-selector>
     </div>
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js
index 016d93d7..9b64f8a 100644
--- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js
+++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js
@@ -207,4 +207,15 @@
     var activate = type != CrPicture.SelectionTypes.OLD;
     this.selectImage_(event.detail.item, activate);
   },
+
+  /**
+   * Returns the 2x (high dpi) image to use for 'srcset'. Note: 'src' will still
+   * be used as the 1x candidate as per the HTML spec.
+   * @param {string} url
+   * @return {string}
+   * @private
+   */
+  getImgSrc2x_: function(url) {
+    return url + '@2x 2x';
+  },
 });
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.html b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.html
index 73ae000..fdbc305a 100644
--- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.html
+++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.html
@@ -39,7 +39,8 @@
     </style>
     <template is="dom-if"
         if="[[showImagePreview_(cameraActive_, imageSrc)]]">
-      <img alt="[[previewAltText]]" src="[[imageSrc]]">
+      <img alt="[[previewAltText]]" src="[[imageSrc]]"
+          srcset="[[getImgSrc2x_(imageSrc)]]"">
       <div id="discard" hidden="[[!showDiscard_(imageType)]]">
         <button is="paper-icon-button-light" id="discardImage"
             class="icon-delete" title="[[discardImageLabel]]"
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.js b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.js
index b93c09d..31012d7b 100644
--- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.js
+++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.js
@@ -91,4 +91,15 @@
   onTapDiscardImage_: function() {
     this.fire('discard-image');
   },
+
+  /**
+   * Returns the 2x (high dpi) image to use for 'srcset'. Note: 'src' will still
+   * be used as the 1x candidate as per the HTML spec.
+   * @param {string} url
+   * @return {string}
+   * @private
+   */
+  getImgSrc2x_: function(url) {
+    return url + '@2x 2x';
+  },
 });