diff --git a/DEPS b/DEPS
index 371b5b4..05a587675 100644
--- a/DEPS
+++ b/DEPS
@@ -129,7 +129,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '7b49eeb4960b43d0eba7875201dea5fd4aedf363',
+  'skia_revision': '4273a150f84d70a9acc340261fd5e7be1af310a5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -145,7 +145,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': 'f2564656e7affc5c5c856186277b9bfc8a100928',
+  'swiftshader_revision': '3e485a4f3ec814d79dff15ae4b66cd860197548e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -184,7 +184,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling HarfBuzz
   # and whatever else without interference from each other.
-  'harfbuzz_revision': '8aaab78efcac81a05ec919be13792c98741ea1b5',
+  'harfbuzz_revision': 'bcb4e505d6ffe33e3268a06698e75d6be0e64957',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Emoji Segmenter
   # and whatever else without interference from each other.
@@ -192,7 +192,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': 'ec795debc5c195658e95f5e750f6c0895c8171f2',
+  'catapult_revision': 'bf564e0beff1b674b28666f8d1932a1687bf59c9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -801,7 +801,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c75272708a801769f6b0f3c2a83b28d4a10295e8',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'd537949d45f364e638004d2b6404f764d8b61002',
       'condition': 'checkout_linux',
   },
 
@@ -826,7 +826,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '3580425baa288b482c1fe2155c005736b7abc372',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'cf9613f166a2f3a7a6a52cff8ae5282aac45f3d9',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1168,7 +1168,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'e065d4ecc45179cfc63eeb932717138be9e5f7f8',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '91c4a41613b36db6ff5d7398dff0dc42f9a264ca',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1380,7 +1380,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0861b5e50a7f205395e9535013ae5f60e59ad274',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@2b8a8c7dba1186ebe62445f8d48cb796733e547a',
     'condition': 'checkout_src_internal',
   },
 
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 e9bd805..a05296d 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
@@ -246,7 +246,7 @@
     @Test
     @SmallTest
     @Feature({"AndroidWebView"})
-    public void testDoesNotCrashOnInvalidData() throws Throwable {
+    public void testDoesNotCrashOnInvalidData_NullInputStream() throws Throwable {
         final String aboutPageUrl = addAboutPageToTestServer(mWebServer);
 
         mShouldInterceptRequestHelper.setReturnValue(
@@ -254,16 +254,45 @@
         int callCount = mShouldInterceptRequestHelper.getCallCount();
         mActivityTestRule.loadUrlAsync(mAwContents, aboutPageUrl);
         mShouldInterceptRequestHelper.waitForCallback(callCount);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"AndroidWebView"})
+    public void testDoesNotCrashOnInvalidData_NullMimeEncodingAndZeroLengthStream()
+            throws Throwable {
+        final String aboutPageUrl = addAboutPageToTestServer(mWebServer);
 
         mShouldInterceptRequestHelper.setReturnValue(
                 new AwWebResourceResponse(null, null, new ByteArrayInputStream(new byte[0])));
-        callCount = mShouldInterceptRequestHelper.getCallCount();
+        int callCount = mShouldInterceptRequestHelper.getCallCount();
         mActivityTestRule.loadUrlAsync(mAwContents, aboutPageUrl);
         mShouldInterceptRequestHelper.waitForCallback(callCount);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"AndroidWebView"})
+    public void testDoesNotCrashOnInvalidData_NullMimeEncodingAndInputStream() throws Throwable {
+        final String aboutPageUrl = addAboutPageToTestServer(mWebServer);
 
         mShouldInterceptRequestHelper.setReturnValue(
                 new AwWebResourceResponse(null, null, null));
-        callCount = mShouldInterceptRequestHelper.getCallCount();
+        int callCount = mShouldInterceptRequestHelper.getCallCount();
+        mActivityTestRule.loadUrlAsync(mAwContents, aboutPageUrl);
+        mShouldInterceptRequestHelper.waitForCallback(callCount);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"AndroidWebView"})
+    public void testDoesNotCrashOnInvalidData_ResponseWithAllNullValues() throws Throwable {
+        final String aboutPageUrl = addAboutPageToTestServer(mWebServer);
+
+        mShouldInterceptRequestHelper.setReturnValue(new AwWebResourceResponse(null /* mime type */,
+                null /* encoding */, null /* input stream */, 0 /* status code */,
+                null /* reason phrase */, null /* response headers */));
+        int callCount = mShouldInterceptRequestHelper.getCallCount();
         mActivityTestRule.loadUrlAsync(mAwContents, aboutPageUrl);
         mShouldInterceptRequestHelper.waitForCallback(callCount);
     }
diff --git a/ash/display/cros_display_config.cc b/ash/display/cros_display_config.cc
index 54d47ea18..88962686 100644
--- a/ash/display/cros_display_config.cc
+++ b/ash/display/cros_display_config.cc
@@ -409,7 +409,8 @@
 // Attempts to set the display mode for display |id|.
 mojom::DisplayConfigResult SetDisplayMode(
     int64_t id,
-    const mojom::DisplayMode& display_mode) {
+    const mojom::DisplayMode& display_mode,
+    mojom::DisplayConfigSource source) {
   display::DisplayManager* display_manager = GetDisplayManager();
 
   display::ManagedDisplayMode current_mode;
@@ -430,7 +431,7 @@
     if (!Shell::Get()
              ->resolution_notification_controller()
              ->PrepareNotificationAndSetDisplayMode(
-                 id, current_mode, new_mode, base::BindOnce([]() {
+                 id, current_mode, new_mode, source, base::BindOnce([]() {
                    Shell::Get()->display_prefs()->MaybeStoreDisplayPrefs();
                  }))) {
       return mojom::DisplayConfigResult::kSetDisplayModeError;
@@ -634,6 +635,7 @@
 void CrosDisplayConfig::SetDisplayProperties(
     const std::string& id,
     mojom::DisplayConfigPropertiesPtr properties,
+    mojom::DisplayConfigSource source,
     SetDisplayPropertiesCallback callback) {
   const display::Display display = GetDisplay(id);
   mojom::DisplayConfigResult result =
@@ -691,7 +693,7 @@
   // will have already been applied. TODO(stevenjb): Validate the display mode
   // before applying any properties.
   if (properties->display_mode) {
-    result = SetDisplayMode(display.id(), *properties->display_mode);
+    result = SetDisplayMode(display.id(), *properties->display_mode, source);
     if (result != mojom::DisplayConfigResult::kSuccess) {
       std::move(callback).Run(result);
       return;
diff --git a/ash/display/cros_display_config.h b/ash/display/cros_display_config.h
index b2904bb9..bcc19cf 100644
--- a/ash/display/cros_display_config.h
+++ b/ash/display/cros_display_config.h
@@ -38,6 +38,7 @@
                               GetDisplayUnitInfoListCallback callback) override;
   void SetDisplayProperties(const std::string& id,
                             mojom::DisplayConfigPropertiesPtr properties,
+                            mojom::DisplayConfigSource source,
                             SetDisplayPropertiesCallback callback) override;
   void SetUnifiedDesktopEnabled(bool enabled) override;
   void OverscanCalibration(const std::string& display_id,
diff --git a/ash/display/cros_display_config_unittest.cc b/ash/display/cros_display_config_unittest.cc
index 91ecf39..5cd27e0f 100644
--- a/ash/display/cros_display_config_unittest.cc
+++ b/ash/display/cros_display_config_unittest.cc
@@ -130,7 +130,7 @@
     mojom::DisplayConfigResult result;
     base::RunLoop run_loop;
     cros_display_config_->SetDisplayProperties(
-        id, std::move(properties),
+        id, std::move(properties), mojom::DisplayConfigSource::kUser,
         base::BindOnce(&SetResult, &result, run_loop.QuitClosure()));
     run_loop.Run();
     return result;
diff --git a/ash/display/display_prefs_unittest.cc b/ash/display/display_prefs_unittest.cc
index ba09ee0b..fcb4eb6 100644
--- a/ash/display/display_prefs_unittest.cc
+++ b/ash/display/display_prefs_unittest.cc
@@ -632,8 +632,10 @@
   display::ManagedDisplayMode old_mode(gfx::Size(400, 300));
   display::ManagedDisplayMode new_mode(gfx::Size(500, 400));
   EXPECT_TRUE(shell->resolution_notification_controller()
-                  ->PrepareNotificationAndSetDisplayMode(id, old_mode, new_mode,
-                                                         base::OnceClosure()));
+                  ->PrepareNotificationAndSetDisplayMode(
+                      id, old_mode, new_mode,
+                      ash::mojom::DisplayConfigSource::kUser,
+                      base::OnceClosure()));
   UpdateDisplay("500x400#500x400|400x300|300x200");
 
   const base::DictionaryValue* properties =
diff --git a/ash/display/resolution_notification_controller.cc b/ash/display/resolution_notification_controller.cc
index b5a0355..1b9c08d 100644
--- a/ash/display/resolution_notification_controller.cc
+++ b/ash/display/resolution_notification_controller.cc
@@ -115,14 +115,16 @@
     int64_t display_id,
     const display::ManagedDisplayMode& old_resolution,
     const display::ManagedDisplayMode& new_resolution,
+    ash::mojom::DisplayConfigSource source,
     base::OnceClosure accept_callback) {
   Shell::Get()->screen_layout_observer()->SetDisplayChangedFromSettingsUI(
       display_id);
   display::DisplayManager* const display_manager =
       Shell::Get()->display_manager();
-  if (display::Display::IsInternalDisplayId(display_id)) {
+  if (source == ash::mojom::DisplayConfigSource::kPolicy ||
+      display::Display::IsInternalDisplayId(display_id)) {
     // We don't show notifications to confirm/revert the resolution change in
-    // the case of an internal display.
+    // the case of an internal display or policy-forced changes.
     return display_manager->SetDisplayMode(display_id, new_resolution);
   }
 
diff --git a/ash/display/resolution_notification_controller.h b/ash/display/resolution_notification_controller.h
index 6763090..7484613 100644
--- a/ash/display/resolution_notification_controller.h
+++ b/ash/display/resolution_notification_controller.h
@@ -9,6 +9,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/display/window_tree_host_manager.h"
+#include "ash/public/interfaces/cros_display_config.mojom.h"
 #include "base/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
@@ -32,7 +33,8 @@
   ResolutionNotificationController();
   ~ResolutionNotificationController() override;
 
-  // If |display_id| is not the internal display, Prepare a resolution change
+  // If |display_id| is not the internal display and |source| is |kSourceUser|
+  // (which means user initiated the change), Prepare a resolution change
   // notification for |display_id| from |old_resolution| to |new_resolution|,
   // which offers a button to revert the change in case something goes wrong.
   // The notification times out if there's only one display connected and the
@@ -44,9 +46,10 @@
   // In case SetDisplayMode() fails, the prepared notification will be
   // discarded.
   //
-  // If |display_id| is the internal display, the resolution change is applied
-  // directly without preparing the confirm/revert notification (this kind of
-  // notification is only useful for external displays).
+  // If |display_id| is the internal display or |source| is |kSourcePolicy|, the
+  // resolution change is applied directly without preparing the confirm/revert
+  // notification (this kind of notification is only useful for external
+  // displays).
   //
   // This method does not create a notification itself. The notification will be
   // created the next OnDisplayConfigurationChanged(), which will be called
@@ -59,6 +62,7 @@
       int64_t display_id,
       const display::ManagedDisplayMode& old_resolution,
       const display::ManagedDisplayMode& new_resolution,
+      ash::mojom::DisplayConfigSource source,
       base::OnceClosure accept_callback) WARN_UNUSED_RESULT;
 
   // Returns true if the notification is visible or scheduled to be visible and
diff --git a/ash/display/resolution_notification_controller_unittest.cc b/ash/display/resolution_notification_controller_unittest.cc
index 7146f0c7..c8dad741 100644
--- a/ash/display/resolution_notification_controller_unittest.cc
+++ b/ash/display/resolution_notification_controller_unittest.cc
@@ -57,7 +57,8 @@
   void SetDisplayResolutionAndNotifyWithResolution(
       const display::Display& display,
       const gfx::Size& new_resolution,
-      const gfx::Size& actual_new_resolution) {
+      const gfx::Size& actual_new_resolution,
+      mojom::DisplayConfigSource source = mojom::DisplayConfigSource::kUser) {
     const display::ManagedDisplayInfo& info =
         display_manager()->GetDisplayInfo(display.id());
     display::ManagedDisplayMode old_mode(
@@ -68,7 +69,7 @@
         old_mode.native(), old_mode.device_scale_factor());
 
     EXPECT_TRUE(controller()->PrepareNotificationAndSetDisplayMode(
-        display.id(), old_mode, new_mode,
+        display.id(), old_mode, new_mode, source,
         base::BindOnce(&ResolutionNotificationControllerTest::OnAccepted,
                        base::Unretained(this))));
 
@@ -89,10 +90,12 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  void SetDisplayResolutionAndNotify(const display::Display& display,
-                                     const gfx::Size& new_resolution) {
+  void SetDisplayResolutionAndNotify(
+      const display::Display& display,
+      const gfx::Size& new_resolution,
+      mojom::DisplayConfigSource source = mojom::DisplayConfigSource::kUser) {
     SetDisplayResolutionAndNotifyWithResolution(display, new_resolution,
-                                                new_resolution);
+                                                new_resolution, source);
   }
 
   static base::string16 GetNotificationMessage() {
@@ -183,6 +186,25 @@
   EXPECT_EQ(59.0, mode.refresh_rate());
 }
 
+// Check that notification is not shown when changes are forced by policy.
+TEST_F(ResolutionNotificationControllerTest, ForcedByPolicy) {
+  UpdateDisplay("300x300#300x300%57|200x200%58,250x250#250x250%59|200x200%60");
+  int64_t id2 = display_manager()->GetSecondaryDisplay().id();
+  ASSERT_EQ(0, accept_count());
+  EXPECT_FALSE(IsNotificationVisible());
+
+  // Changes the resolution and apply the result.
+  SetDisplayResolutionAndNotify(display_manager()->GetSecondaryDisplay(),
+                                gfx::Size(200, 200),
+                                mojom::DisplayConfigSource::kPolicy);
+  EXPECT_FALSE(IsNotificationVisible());
+  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
+  display::ManagedDisplayMode mode;
+  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
+  EXPECT_EQ("200x200", mode.size().ToString());
+  EXPECT_EQ(60.0, mode.refresh_rate());
+}
+
 TEST_F(ResolutionNotificationControllerTest, ClickMeansAccept) {
   UpdateDisplay("300x300#300x300%57|200x200%58,250x250#250x250%59|200x200%60");
   int64_t id2 = display_manager()->GetSecondaryDisplay().id();
diff --git a/ash/public/cpp/default_scale_factor_retriever_unittest.cc b/ash/public/cpp/default_scale_factor_retriever_unittest.cc
index 4173905..df1edad 100644
--- a/ash/public/cpp/default_scale_factor_retriever_unittest.cc
+++ b/ash/public/cpp/default_scale_factor_retriever_unittest.cc
@@ -49,6 +49,7 @@
   }
   void SetDisplayProperties(const std::string& id,
                             ash::mojom::DisplayConfigPropertiesPtr properties,
+                            ash::mojom::DisplayConfigSource source,
                             SetDisplayPropertiesCallback callback) override {}
   void SetUnifiedDesktopEnabled(bool enabled) override {}
   void OverscanCalibration(const std::string& display_id,
diff --git a/ash/public/interfaces/cros_display_config.mojom b/ash/public/interfaces/cros_display_config.mojom
index 7039c8b7..ac2899a1 100644
--- a/ash/public/interfaces/cros_display_config.mojom
+++ b/ash/public/interfaces/cros_display_config.mojom
@@ -63,6 +63,12 @@
   kShowNative,
 };
 
+// Describes who initiated configuration change.
+enum DisplayConfigSource {
+  kUser = 0,
+  kPolicy
+};
+
 // Defines a pair of display + touch points used for touch calibration.
 struct TouchCalibrationPair {
   // The coordinates of the display point.
@@ -239,9 +245,12 @@
   GetDisplayUnitInfoList(bool single_unified) =>
     (array<DisplayUnitInfo> info_list);
 
-  // Sets |properties| for individual display with identifier |id|. Returns
-  // Success if the properties are valid or an error value otherwise.
-  SetDisplayProperties(string id, DisplayConfigProperties properties) =>
+  // Sets |properties| for individual display with identifier |id|. |source|
+  // should describe who initiated the change. Returns Success if the properties
+  // are valid or an error value otherwise.
+  SetDisplayProperties(string id,
+                       DisplayConfigProperties properties,
+                       DisplayConfigSource source) =>
     (DisplayConfigResult result);
 
   // Enables or disables unified desktop mode. If the current display mode is
diff --git a/ash/shelf/app_list_button.cc b/ash/shelf/app_list_button.cc
index 28af351..3d37e025 100644
--- a/ash/shelf/app_list_button.cc
+++ b/ash/shelf/app_list_button.cc
@@ -188,6 +188,19 @@
   return kViewClassName;
 }
 
+std::unique_ptr<views::InkDropRipple> AppListButton::CreateInkDropRipple()
+    const {
+  const int app_list_button_radius = ShelfConstants::control_border_radius();
+  gfx::Point center = GetCenterPoint();
+  gfx::Rect bounds(center.x() - app_list_button_radius,
+                   center.y() - app_list_button_radius,
+                   2 * app_list_button_radius, 2 * app_list_button_radius);
+  return std::make_unique<views::FloodFillInkDropRipple>(
+      size(), GetLocalBounds().InsetsFrom(bounds),
+      GetInkDropCenterBasedOnLastEvent(), GetInkDropBaseColor(),
+      ink_drop_visible_opacity());
+}
+
 void AppListButton::PaintButtonContents(gfx::Canvas* canvas) {
   gfx::PointF circle_center(GetCenterPoint());
 
diff --git a/ash/shelf/app_list_button.h b/ash/shelf/app_list_button.h
index c698120..c92b86c 100644
--- a/ash/shelf/app_list_button.h
+++ b/ash/shelf/app_list_button.h
@@ -50,6 +50,7 @@
 
  protected:
   // views::Button:
+  std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override;
   void PaintButtonContents(gfx::Canvas* canvas) override;
 
  private:
diff --git a/ash/shelf/app_list_button_unittest.cc b/ash/shelf/app_list_button_unittest.cc
index f94e57c..fa0bbb0 100644
--- a/ash/shelf/app_list_button_unittest.cc
+++ b/ash/shelf/app_list_button_unittest.cc
@@ -16,7 +16,6 @@
 #include "ash/root_window_controller.h"
 #include "ash/session/session_controller.h"
 #include "ash/shelf/shelf.h"
-#include "ash/shelf/shelf_constants.h"
 #include "ash/shelf/shelf_view.h"
 #include "ash/shelf/shelf_view_test_api.h"
 #include "ash/shell.h"
@@ -154,7 +153,7 @@
 
   Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
   test_api.RunMessageLoopUntilAnimationsDone();
-  EXPECT_EQ(ShelfConstants::button_spacing(), app_list_button()->bounds().x());
+  EXPECT_EQ(0, app_list_button()->bounds().x());
 }
 
 class VoiceInteractionAppListButtonTest : public AppListButtonTest {
diff --git a/ash/shelf/overflow_bubble_view.cc b/ash/shelf/overflow_bubble_view.cc
index 487773d..d7c242f 100644
--- a/ash/shelf/overflow_bubble_view.cc
+++ b/ash/shelf/overflow_bubble_view.cc
@@ -179,8 +179,6 @@
 gfx::Rect OverflowBubbleView::GetBubbleBounds() {
   const gfx::Size content_size = GetPreferredSize();
   const gfx::Rect anchor_rect = GetAnchorRect();
-  const int distance_to_overflow_button =
-      kDistanceToMainShelf + (kShelfSize - kShelfControlSize) / 2;
   gfx::Rect monitor_rect =
       display::Screen::GetScreen()
           ->GetDisplayNearestPoint(anchor_rect.CenterPoint())
@@ -193,7 +191,7 @@
         base::i18n::IsRTL()
             ? anchor_rect.x() - kEndPadding
             : anchor_rect.right() - content_size.width() - kEndPadding,
-        anchor_rect.y() - distance_to_overflow_button - content_size.height(),
+        anchor_rect.y() - kDistanceToMainShelf - content_size.height(),
         content_size.width() + 2 * kEndPadding, content_size.height());
     if (bounds.x() < monitor_rect.x())
       bounds.Offset(monitor_rect.x() - bounds.x(), 0);
@@ -205,10 +203,9 @@
       0, anchor_rect.bottom() - content_size.height() - kEndPadding,
       content_size.width(), content_size.height() + 2 * kEndPadding);
   if (shelf_->alignment() == SHELF_ALIGNMENT_LEFT)
-    bounds.set_x(anchor_rect.right() + distance_to_overflow_button);
+    bounds.set_x(anchor_rect.right() + kDistanceToMainShelf);
   else
-    bounds.set_x(anchor_rect.x() - distance_to_overflow_button -
-                 content_size.width());
+    bounds.set_x(anchor_rect.x() - kDistanceToMainShelf - content_size.width());
   if (bounds.y() < monitor_rect.y())
     bounds.Offset(0, monitor_rect.y() - bounds.y());
   if (bounds.bottom() > monitor_rect.bottom())
diff --git a/ash/shelf/shelf_control_button.cc b/ash/shelf/shelf_control_button.cc
index e5a867ff..0143fb8 100644
--- a/ash/shelf/shelf_control_button.cc
+++ b/ash/shelf/shelf_control_button.cc
@@ -22,22 +22,21 @@
 ShelfControlButton::ShelfControlButton(ShelfView* shelf_view)
     : ShelfButton(shelf_view), shelf_(shelf_view->shelf()) {
   set_has_ink_drop_action_on_click(true);
+  SetSize(gfx::Size(kShelfControlSize, kShelfControlSize));
 }
 
 ShelfControlButton::~ShelfControlButton() = default;
 
 gfx::Point ShelfControlButton::GetCenterPoint() const {
-  return gfx::Point(width() / 2.f, height() / 2.f);
+  return gfx::Point(width() / 2.f, width() / 2.f);
 }
 
 std::unique_ptr<views::InkDropRipple> ShelfControlButton::CreateInkDropRipple()
     const {
-  const int button_radius = ShelfConstants::control_border_radius();
-  gfx::Point center = GetCenterPoint();
-  gfx::Rect bounds(center.x() - button_radius, center.y() - button_radius,
-                   2 * button_radius, 2 * button_radius);
   return std::make_unique<views::FloodFillInkDropRipple>(
-      size(), GetLocalBounds().InsetsFrom(bounds),
+      size(),
+      gfx::Insets(ShelfConstants::button_size() / 2 -
+                  ShelfConstants::control_border_radius()),
       GetInkDropCenterBasedOnLastEvent(), GetInkDropBaseColor(),
       ink_drop_visible_opacity());
 }
@@ -52,8 +51,21 @@
   return "ash/ShelfControlButton";
 }
 
+gfx::Rect ShelfControlButton::CalculateButtonBounds() const {
+  ShelfAlignment alignment = shelf_->alignment();
+  gfx::Rect content_bounds = GetContentsBounds();
+  // Align the button to the top of a bottom-aligned shelf, to the right edge
+  // a left-aligned shelf, and to the left edge of a right-aligned shelf.
+  const int inset = (ShelfConstants::shelf_size() - kShelfControlSize) / 2;
+  const int x = alignment == SHELF_ALIGNMENT_LEFT
+                    ? content_bounds.right() - inset - kShelfControlSize
+                    : content_bounds.x() + inset;
+  return gfx::Rect(x, content_bounds.y() + inset, kShelfControlSize,
+                   kShelfControlSize);
+}
+
 void ShelfControlButton::PaintButtonContents(gfx::Canvas* canvas) {
-  PaintBackground(canvas, GetContentsBounds());
+  PaintBackground(canvas, CalculateButtonBounds());
 }
 
 void ShelfControlButton::PaintBackground(gfx::Canvas* canvas,
diff --git a/ash/shelf/shelf_control_button.h b/ash/shelf/shelf_control_button.h
index 1b10a4e..ed1055c 100644
--- a/ash/shelf/shelf_control_button.h
+++ b/ash/shelf/shelf_control_button.h
@@ -37,6 +37,9 @@
   void PaintButtonContents(gfx::Canvas* canvas) override;
 
  private:
+  // Calculates the bounds of the control button based on the shelf alignment.
+  gfx::Rect CalculateButtonBounds() const;
+
   Shelf* shelf_;
 
   DISALLOW_COPY_AND_ASSIGN(ShelfControlButton);
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc
index 145bbea2..97e4f4e9 100644
--- a/ash/shelf/shelf_layout_manager.cc
+++ b/ash/shelf/shelf_layout_manager.cc
@@ -1122,7 +1122,10 @@
       return true;
     }
   }
-  return false;
+  auto* pip_container = Shell::GetContainer(root, kShellWindowId_PipContainer);
+  // The PIP window is not activatable and is not in the MRU list, but count
+  // it as a visible window for shelf auto-hide purposes. See crbug.com/942991.
+  return !pip_container->children().empty();
 }
 
 ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc
index b322dd6a..4a440dd 100644
--- a/ash/shelf/shelf_layout_manager_unittest.cc
+++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -2763,6 +2763,28 @@
             client.last_a11y_alert());
 }
 
+// Verifies the auto-hide shelf is hidden if there is only a single PIP window.
+TEST_F(ShelfLayoutManagerTest, AutoHideShelfHiddenForSinglePipWindow) {
+  Shelf* shelf = GetPrimaryShelf();
+  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
+  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
+  EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
+
+  // Create a PIP window.
+  aura::Window* window = CreateTestWindow();
+  window->SetBounds(gfx::Rect(0, 0, 100, 100));
+  // Set always on top so it is put in the PIP container.
+  window->SetProperty(aura::client::kAlwaysOnTopKey, true);
+  window->Show();
+  const wm::WMEvent pip_event(wm::WM_EVENT_PIP);
+  wm::GetWindowState(window)->OnWMEvent(&pip_event);
+  Shell::Get()->UpdateShelfVisibility();
+
+  // Expect the shelf to be hidden.
+  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
+  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
+}
+
 class ShelfLayoutManagerKeyboardTest : public AshTestBase {
  public:
   ShelfLayoutManagerKeyboardTest() = default;
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc
index 87be8b8..c8b1dd6 100644
--- a/ash/shelf/shelf_view.cc
+++ b/ash/shelf/shelf_view.cc
@@ -89,8 +89,8 @@
 constexpr int kSeparatorSize = 20;
 constexpr int kSeparatorThickness = 1;
 
-// The margin on either side of the group of app icons.
-constexpr int kAppIconGroupMargin = 16;
+// The margin between the app list button and the first shelf item.
+constexpr int kAppListButtonMargin = 32;
 
 // White with ~20% opacity.
 constexpr SkColor kSeparatorColor = SkColorSetARGB(0x32, 0xFF, 0xFF, 0xFF);
@@ -518,7 +518,8 @@
 }
 
 gfx::Size ShelfView::CalculatePreferredSize() const {
-  CalculateIdealBounds();
+  gfx::Rect overflow_bounds;
+  CalculateIdealBounds(&overflow_bounds);
 
   int last_button_index = last_visible_index_;
   if (!is_overflow_mode() && overflow_button_ && overflow_button_->visible())
@@ -1059,11 +1060,12 @@
     return;
   }
 
-  CalculateIdealBounds();
+  gfx::Rect overflow_bounds;
+  CalculateIdealBounds(&overflow_bounds);
   views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_);
+  overflow_button_->SetBoundsRect(overflow_bounds);
   UpdateBackButton();
   LayoutAppListAndBackButtonHighlight();
-  LayoutOverflowButton();
   UpdateVisibleShelfItemBoundsUnion();
 }
 
@@ -1081,24 +1083,17 @@
   return -1;
 }
 
-int ShelfView::GetDimensionOfAppIcons(int max_size) const {
+int ShelfView::GetDimensionOfCenteredShelfItems() const {
   int size = 0;
-  for (int i = kAppListButtonIndex + 1; i < view_model_->view_size(); ++i) {
-    int new_size = size;
-    new_size += ShelfConstants::button_size();
-    if (i > kAppListButtonIndex + 1) {
-      // TODO(manucornet): If one of the displayed items is the overflow
-      // button, we are overestimating the dimension a tiny bit because
-      // control buttons are smaller than app buttons. But taking this into
-      // account is a little tricky because at this stage we don't know whether
-      // we are overflowing. Fix this and add tests to check for perfect
-      // centering when the overflow button is shown.
-      new_size += ShelfConstants::button_spacing();
+  int added_items = 0;
+  for (ShelfItem item : model_->items()) {
+    if (item.type == TYPE_PINNED_APP || item.type == TYPE_APP ||
+        item.type == TYPE_BROWSER_SHORTCUT) {
+      size += ShelfConstants::button_size();
+      added_items++;
     }
-    if (new_size > max_size)
-      return size;
-    size = new_size;
   }
+  size += (added_items - 1) * ShelfConstants::button_spacing();
   return size;
 }
 
@@ -1143,17 +1138,13 @@
                                back_and_app_list_background_size));
 }
 
-void ShelfView::CalculateIdealBounds() const {
+void ShelfView::CalculateIdealBounds(gfx::Rect* overflow_bounds) const {
   DCHECK(model_->item_count() == view_model_->view_size());
 
   const int button_spacing = ShelfConstants::button_spacing();
+  const int button_size = ShelfConstants::button_size();
+
   const int available_size = shelf_->PrimaryAxisValue(width(), height());
-  // Size occupied by the app list button and back button plus all appropriate
-  // margins is not available for actual app icons.
-  const int available_size_for_app_icons =
-      available_size - kShelfButtonSpacing -
-      (IsTabletModeEnabled() ? 2 : 1) * kShelfControlSize -
-      2 * kAppIconGroupMargin;
   const int separator_index = GetSeparatorIndex();
   const bool virtual_keyboard_visible =
       Shell::Get()->system_tray_model()->virtual_keyboard()->visible();
@@ -1164,17 +1155,13 @@
                          !virtual_keyboard_visible);
   int app_list_button_position;
 
-  int x = shelf_->PrimaryAxisValue(button_spacing, 0);
-  int y = shelf_->PrimaryAxisValue(0, button_spacing);
+  int x = 0;
+  int y = 0;
+
+  int w = shelf_->PrimaryAxisValue(button_size, width());
+  int h = shelf_->PrimaryAxisValue(height(), button_size);
 
   for (int i = 0; i < view_model_->view_size(); ++i) {
-    // "Primary" as in "same direction as the shelf's direction". The
-    // "secondary" (orthogonal) size is always the full shelf to maximize click
-    // targets even for control buttons.
-    const int size_primary =
-        (i <= kAppListButtonIndex) ? kShelfControlSize : kShelfButtonSize;
-    const int size_secondary = kShelfButtonSize;
-
     if (i < first_visible_index_) {
       // This happens for the overflow view.
       view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0));
@@ -1182,41 +1169,19 @@
     }
     if (i == kAppListButtonIndex + 1) {
       // Start centering after we've laid out the app list button.
-      // Now there are two possibilities. Either all the apps fit when centered
-      // on the whole screen width, in which case we do that. Or, when space
-      // becomes a little tight (which happens especially when the status area
-      // is wider because of extra panels), we center apps according to the
-      // available space on the shelf (subtracting what's already allocated to
-      // the app list button).
-
-      int app_icons_size = GetDimensionOfAppIcons(available_size_for_app_icons);
+      // Center the shelf items on the whole shelf, including the status
+      // area widget.
+      int centered_shelf_items_size = GetDimensionOfCenteredShelfItems();
       StatusAreaWidget* status_widget = shelf_widget_->status_area_widget();
-      const int status_widget_size =
+      int status_widget_size =
           status_widget ? shelf_->PrimaryAxisValue(
                               status_widget->GetWindowBoundsInScreen().width(),
                               status_widget->GetWindowBoundsInScreen().height())
                         : 0;
-      const int screen_size = available_size + status_widget_size;
-
-      int padding_for_centering = 0;
-      // An easy way to check whether the apps fit at the exact center of the
-      // screen is to imagine that we have another status widget on the
-      // other side (the status widget is always bigger than the app list
-      // button plus the back button if applicable) and see if the apps
-      // can fit in the middle.
-      if (app_icons_size + 2 * status_widget_size + 2 * kAppIconGroupMargin <
-          screen_size) {
-        padding_for_centering = (screen_size - app_icons_size) / 2;
-      } else {
-        padding_for_centering =
-            kShelfButtonSpacing +
-            (IsTabletModeEnabled() ? 2 : 1) * kShelfControlSize +
-            kAppIconGroupMargin +
-            (available_size_for_app_icons - app_icons_size) / 2;
-      }
-
+      int padding_for_centering =
+          (available_size + status_widget_size - centered_shelf_items_size) / 2;
       if (padding_for_centering >
-          app_list_button_position + kAppIconGroupMargin) {
+          app_list_button_position + kAppListButtonMargin) {
         // Only shift buttons to the right, never let them interfere with the
         // left-aligned system buttons.
         x = shelf_->PrimaryAxisValue(padding_for_centering, 0);
@@ -1224,26 +1189,30 @@
       }
     }
 
-    view_model_->set_ideal_bounds(
-        i,
-        gfx::Rect(x, y, shelf_->PrimaryAxisValue(size_primary, size_secondary),
-                  shelf_->PrimaryAxisValue(size_secondary, size_primary)));
-
+    view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h));
     // If not in tablet mode do not increase |x| or |y|. Instead just let the
     // next item (app list button) cover the back button, which will have
     // opacity 0 anyways.
     if (i == kBackButtonIndex && !IsTabletModeEnabled())
       continue;
 
-    x = shelf_->PrimaryAxisValue(x + size_primary + button_spacing, x);
-    y = shelf_->PrimaryAxisValue(y, y + size_primary + button_spacing);
+    // There is no spacing between the first two elements. Do not worry about y
+    // since the back button only appears in tablet mode, which forces the shelf
+    // to be bottom aligned.
+    x = shelf_->PrimaryAxisValue(x + w + (i == 0 ? 0 : button_spacing), x);
+    y = shelf_->PrimaryAxisValue(y, y + h + button_spacing);
+
+    // In the new UI, padding between the back & app list buttons is smaller
+    // than between all other shelf items.
+    if (i == kBackButtonIndex)
+      x -= button_spacing;
 
     if (i == kAppListButtonIndex) {
       app_list_button_position = shelf_->PrimaryAxisValue(x, y);
       // A larger minimum padding after the app list button is required:
       // increment with the necessary extra amount.
-      x += shelf_->PrimaryAxisValue(kAppIconGroupMargin - button_spacing, 0);
-      y += shelf_->PrimaryAxisValue(0, kAppIconGroupMargin - button_spacing);
+      x += shelf_->PrimaryAxisValue(kAppListButtonMargin - button_spacing, 0);
+      y += shelf_->PrimaryAxisValue(0, kAppListButtonMargin - button_spacing);
     }
 
     if (i == separator_index) {
@@ -1268,8 +1237,11 @@
     const_cast<ShelfView*>(this)->UpdateAllButtonsVisibilityInOverflowMode();
     return;
   }
+
+  overflow_bounds->set_size(gfx::Size(shelf_->PrimaryAxisValue(w, width()),
+                                      shelf_->PrimaryAxisValue(height(), h)));
   last_visible_index_ =
-      IndexOfLastItemThatFitsSize(available_size - kAppIconGroupMargin);
+      IndexOfLastItemThatFitsSize(available_size - button_spacing);
   bool show_overflow = last_visible_index_ < model_->item_count() - 1;
 
   // In the main shelf, the first visible index is either the back button (in
@@ -1291,8 +1263,8 @@
     // FinalizeRipOffDrag().
     if (dragged_off_shelf_ && view_model_->view_at(i) == drag_view_)
       continue;
-    // If the virtual keyboard is visible, only the back button and the app
-    // list button are shown.
+    // If virtual keyboard is visible, only back button and app list button are
+    // shown.
     const bool is_visible_item = !virtual_keyboard_visible ||
                                  i == kBackButtonIndex ||
                                  i == kAppListButtonIndex;
@@ -1302,6 +1274,28 @@
 
   overflow_button_->SetVisible(show_overflow);
   if (show_overflow) {
+    DCHECK_NE(0, view_model_->view_size());
+    if (last_visible_index_ == -1) {
+      x = 0;
+      y = 0;
+    } else {
+      x = shelf_->PrimaryAxisValue(
+          view_model_->ideal_bounds(last_visible_index_).right(),
+          view_model_->ideal_bounds(last_visible_index_).x());
+      y = shelf_->PrimaryAxisValue(
+          view_model_->ideal_bounds(last_visible_index_).y(),
+          view_model_->ideal_bounds(last_visible_index_).bottom());
+    }
+
+    if (last_visible_index_ >= 0) {
+      // Add more space between last visible item and overflow button.
+      // Without this, two buttons look too close compared with other items.
+      x = shelf_->PrimaryAxisValue(x + button_spacing, x);
+      y = shelf_->PrimaryAxisValue(y, y + button_spacing);
+    }
+
+    overflow_bounds->set_x(x);
+    overflow_bounds->set_y(y);
     if (overflow_bubble_.get() && overflow_bubble_->IsShowing())
       UpdateOverflowRange(overflow_bubble_->bubble_view()->shelf_view());
   } else {
@@ -1310,31 +1304,6 @@
   }
 }
 
-void ShelfView::LayoutOverflowButton() const {
-  DCHECK_NE(0, view_model_->view_size());
-  int x = 0;
-  int y = 0;
-  if (last_visible_index_ != -1) {
-    const int offset = (kShelfButtonSize - kShelfControlSize) / 2;
-    x = shelf_->PrimaryAxisValue(
-        offset + view_model_->ideal_bounds(last_visible_index_).right(),
-        offset + view_model_->ideal_bounds(last_visible_index_).x());
-    y = shelf_->PrimaryAxisValue(
-        offset + view_model_->ideal_bounds(last_visible_index_).y(),
-        offset + view_model_->ideal_bounds(last_visible_index_).bottom());
-  }
-
-  if (last_visible_index_ >= 0) {
-    // Add more space between last visible item and overflow button.
-    // Without this, two buttons look too close compared with other items.
-    x = shelf_->PrimaryAxisValue(x + ShelfConstants::button_spacing(), x);
-    y = shelf_->PrimaryAxisValue(y, y + ShelfConstants::button_spacing());
-  }
-
-  overflow_button_->SetBoundsRect(
-      gfx::Rect(x, y, kShelfControlSize, kShelfControlSize));
-}
-
 int ShelfView::IndexOfLastItemThatFitsSize(int max_value) const {
   int index = model_->item_count() - 1;
   while (index >= 0 &&
@@ -1347,7 +1316,8 @@
 }
 
 void ShelfView::AnimateToIdealBounds() {
-  CalculateIdealBounds();
+  gfx::Rect overflow_bounds;
+  CalculateIdealBounds(&overflow_bounds);
   for (int i = 0; i < view_model_->view_size(); ++i) {
     View* view = view_model_->view_at(i);
     bounds_animator_->AnimateViewTo(view, view_model_->ideal_bounds(i));
@@ -1356,8 +1326,8 @@
     if (i && view->border())
       view->SetBorder(views::NullBorder());
   }
+  overflow_button_->SetBoundsRect(overflow_bounds);
   LayoutAppListAndBackButtonHighlight();
-  LayoutOverflowButton();
   UpdateVisibleShelfItemBoundsUnion();
 }
 
@@ -2050,7 +2020,8 @@
   // button before this animation completes it doesn't appear at some random
   // spot (because it was in the middle of animating from 0,0 0x0 to its
   // target).
-  CalculateIdealBounds();
+  gfx::Rect overflow_bounds;
+  CalculateIdealBounds(&overflow_bounds);
   view->SetBoundsRect(view_model_->ideal_bounds(model_index));
 
   // The first animation moves all the views to their target position. |view|
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h
index 1695af0..8af59e6 100644
--- a/ash/shelf/shelf_view.h
+++ b/ash/shelf/shelf_view.h
@@ -247,10 +247,9 @@
   // Returns whether |item| should belong in the pinned section of the shelf.
   bool IsItemPinned(const ShelfItem& item) const;
 
-  // Enumerates the shelf apps and returns the total size they occupy,
-  // accounting for all apps or, if the total size is greater than |max_size|,
-  // the size of however many app can fit without exceeding |max_size|.
-  int GetDimensionOfAppIcons(int max_size) const;
+  // Enumerates the shelf items that are centered in the new UI and returns
+  // the total size they occupy.
+  int GetDimensionOfCenteredShelfItems() const;
 
   // Returns the index of the item after which the separator should be shown,
   // or -1 if no separator is required.
@@ -344,9 +343,7 @@
 
   // Calculates the ideal bounds. The bounds of each button corresponding to an
   // item in the model is set in |view_model_|.
-  void CalculateIdealBounds() const;
-
-  void LayoutOverflowButton() const;
+  void CalculateIdealBounds(gfx::Rect* overflow_bounds) const;
 
   // Returns the index of the last view whose max primary axis coordinate is
   // less than |max_value|. Returns -1 if nothing fits, or there are no views.
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc
index 205ee78..656b3dd 100644
--- a/ash/shelf/shelf_view_unittest.cc
+++ b/ash/shelf/shelf_view_unittest.cc
@@ -12,7 +12,6 @@
 #include "ash/app_list/test/app_list_test_helper.h"
 #include "ash/app_list/views/app_list_view.h"
 #include "ash/focus_cycler.h"
-#include "ash/ime/ime_controller.h"
 #include "ash/public/cpp/shelf_item_delegate.h"
 #include "ash/public/cpp/shelf_model.h"
 #include "ash/public/cpp/shelf_prefs.h"
@@ -2282,122 +2281,6 @@
   EXPECT_TRUE(test_api_->CloseMenu());
 }
 
-void ExpectWithinOnePixel(int a, int b) {
-  EXPECT_TRUE(abs(a - b) <= 1) << "Values " << a << " and " << b
-                               << " should have a difference no greater than 1";
-}
-
-TEST_F(ShelfViewTest, IconCenteringTest) {
-  const display::Display display =
-      display::Screen::GetScreen()->GetPrimaryDisplay();
-  const int screen_width = display.bounds().width();
-  const int screen_center = screen_width / 2;
-
-  // Show the IME panel, to introduce for asymettry with a larger status area.
-  Shell::Get()->ime_controller()->ShowImeMenuOnShelf(true);
-
-  // At the start, we have exactly one app icon for the browser. That should
-  // be centered on the screen.
-  const ShelfAppButton* button1 = GetButtonByID(model_->items()[2].id);
-  ExpectWithinOnePixel(screen_center,
-                       button1->GetBoundsInScreen().CenterPoint().x());
-  // Also check that the distance between the icon edge and the screen edge is
-  // the same on both sides.
-  ExpectWithinOnePixel(button1->GetBoundsInScreen().x(),
-                       screen_width - button1->GetBoundsInScreen().right());
-
-  const int apps_that_can_fit_at_center_of_screen = 8;
-  std::vector<ShelfAppButton*> app_buttons;
-  // Start with just the browser app button.
-  app_buttons.push_back(GetButtonByID(model_->items()[2].id));
-  int n_buttons = 1;
-
-  // Now repeat the same process by adding apps until they can't fit at the
-  // center of the screen.
-  for (int i = 1; i < apps_that_can_fit_at_center_of_screen; ++i) {
-    // Add a new app and add its button to our list.
-    app_buttons.push_back(GetButtonByID(AddApp()));
-    n_buttons = app_buttons.size();
-    if (n_buttons % 2 == 1) {
-      // Odd number of apps. Check that the middle app is exactly at the center
-      // of the screen.
-      ExpectWithinOnePixel(
-          screen_center,
-          app_buttons[n_buttons / 2]->GetBoundsInScreen().CenterPoint().x());
-    }
-    // Also check that the first icon is at the same distance from the left
-    // screen edge as the last icon is from the right screen edge.
-    ExpectWithinOnePixel(
-        app_buttons[0]->GetBoundsInScreen().x(),
-        screen_width - app_buttons[n_buttons - 1]->GetBoundsInScreen().right());
-  }
-
-  // Add one more app. Now the block of apps should be at the center of the
-  // shelf part of the shelf widget (not including the status area) as opposed
-  // to at the center of the whole screen. But we're not overflowing yet.
-  app_buttons.push_back(GetButtonByID(AddApp()));
-  n_buttons = app_buttons.size();
-  EXPECT_FALSE(shelf_view_->GetOverflowButton()->visible());
-  // Icons at either end should also be at the same distance from the app list
-  // button on the left, and the status area on the right.
-  gfx::NativeWindow window = shelf_view_->shelf_widget()->GetNativeWindow();
-  views::View* status_area_view = RootWindowController::ForWindow(window)
-                                      ->GetStatusAreaWidget()
-                                      ->GetContentsView();
-  const int status_area_left = status_area_view->GetBoundsInScreen().x();
-  const int app_list_button_right =
-      shelf_view_->GetAppListButton()->GetBoundsInScreen().right();
-  ExpectWithinOnePixel(
-      app_buttons[0]->GetBoundsInScreen().x() - app_list_button_right,
-      status_area_left -
-          app_buttons[n_buttons - 1]->GetBoundsInScreen().right());
-
-  // Add another app. The overflow button should now appear.
-  app_buttons.push_back(GetButtonByID(AddApp()));
-  n_buttons = app_buttons.size();
-  EXPECT_TRUE(shelf_view_->GetOverflowButton()->visible());
-}
-
-TEST_F(ShelfViewTest, FirstAndLastVisibleIndex) {
-  // At the start, the only things visible on the shelf are the app list button
-  // (index 1) and the browser app button (index 2).
-  EXPECT_EQ(1, shelf_view_->first_visible_index());
-  EXPECT_EQ(2, shelf_view_->last_visible_index());
-  // By enabling tablet mode, the back button (index 0) should become visible.
-  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
-  EXPECT_EQ(0, shelf_view_->first_visible_index());
-  EXPECT_EQ(2, shelf_view_->last_visible_index());
-  // And things should return back to the previous state once tablet mode is off
-  // again.
-  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
-  EXPECT_EQ(1, shelf_view_->first_visible_index());
-  EXPECT_EQ(2, shelf_view_->last_visible_index());
-  // Now let's add some apps until the overflow button shows up, each time
-  // checking the first and last visible indices are what we expect.
-  int last_visible_index = 2;
-  int last_visible_index_before_overflow;
-  ShelfID last_added_item_id;
-  while (true) {
-    last_added_item_id = AddApp();
-    if (shelf_view_->GetOverflowButton()->visible()) {
-      last_visible_index_before_overflow = last_visible_index;
-      break;
-    }
-    last_visible_index++;
-    EXPECT_EQ(1, shelf_view_->first_visible_index());
-    EXPECT_EQ(last_visible_index, shelf_view_->last_visible_index());
-  }
-  // Now remove the last item we just added. That should get rid of the
-  // overflow button, and get back to the previous state.
-  RemoveByID(last_added_item_id);
-  EXPECT_EQ(1, shelf_view_->first_visible_index());
-  EXPECT_EQ(last_visible_index_before_overflow,
-            shelf_view_->last_visible_index());
-  // Adding another app should let the overflow button appear again.
-  AddApp();
-  EXPECT_TRUE(shelf_view_->GetOverflowButton()->visible());
-}
-
 // Test class that tests both context and application menus.
 class ShelfViewMenuTest : public ShelfViewTest,
                           public testing::WithParamInterface<bool> {
diff --git a/base/message_loop/message_loop_current.cc b/base/message_loop/message_loop_current.cc
index c0b2ff7..7dcab95 100644
--- a/base/message_loop/message_loop_current.cc
+++ b/base/message_loop/message_loop_current.cc
@@ -9,26 +9,23 @@
 #include "base/message_loop/message_pump_for_io.h"
 #include "base/message_loop/message_pump_for_ui.h"
 #include "base/no_destructor.h"
+#include "base/task/sequence_manager/sequence_manager_impl.h"
 #include "base/threading/thread_local.h"
 #include "base/threading/thread_task_runner_handle.h"
 
 namespace base {
 
-namespace {
-
-base::ThreadLocalPointer<MessageLoopBase>* GetTLSMessageLoop() {
-  static NoDestructor<ThreadLocalPointer<MessageLoopBase>> lazy_tls_ptr;
-  return lazy_tls_ptr.get();
-}
-
-}  // namespace
-
 //------------------------------------------------------------------------------
 // MessageLoopCurrent
 
 // static
+MessageLoopBase* MessageLoopCurrent::GetCurrentMessageLoopBase() {
+  return sequence_manager::internal::SequenceManagerImpl::GetCurrent();
+}
+
+// static
 MessageLoopCurrent MessageLoopCurrent::Get() {
-  return MessageLoopCurrent(GetTLSMessageLoop()->Get());
+  return MessageLoopCurrent(GetCurrentMessageLoopBase());
 }
 
 // static
@@ -38,7 +35,7 @@
 
 // static
 bool MessageLoopCurrent::IsSet() {
-  return !!GetTLSMessageLoop()->Get();
+  return !!GetCurrentMessageLoopBase();
 }
 
 void MessageLoopCurrent::AddDestructionObserver(
@@ -69,7 +66,7 @@
 }
 
 bool MessageLoopCurrent::IsBoundToCurrentThread() const {
-  return current_ == GetTLSMessageLoop()->Get();
+  return current_ == GetCurrentMessageLoopBase();
 }
 
 bool MessageLoopCurrent::IsIdleForTesting() {
@@ -102,7 +99,7 @@
 }
 
 MessageLoopCurrent::ScopedNestableTaskAllower::ScopedNestableTaskAllower()
-    : loop_(GetTLSMessageLoop()->Get()),
+    : loop_(GetCurrentMessageLoopBase()),
       old_state_(loop_->IsTaskExecutionAllowed()) {
   loop_->SetTaskExecutionAllowed(true);
 }
@@ -111,20 +108,6 @@
   loop_->SetTaskExecutionAllowed(old_state_);
 }
 
-// static
-void MessageLoopCurrent::BindToCurrentThreadInternal(MessageLoopBase* current) {
-  DCHECK(!GetTLSMessageLoop()->Get())
-      << "Can't register a second MessageLoop on the same thread.";
-  GetTLSMessageLoop()->Set(current);
-}
-
-// static
-void MessageLoopCurrent::UnbindFromCurrentThreadInternal(
-    MessageLoopBase* current) {
-  DCHECK_EQ(current, GetTLSMessageLoop()->Get());
-  GetTLSMessageLoop()->Set(nullptr);
-}
-
 bool MessageLoopCurrent::operator==(const MessageLoopCurrent& other) const {
   return current_ == other.current_;
 }
@@ -136,7 +119,7 @@
 
 // static
 MessageLoopCurrentForUI MessageLoopCurrentForUI::Get() {
-  MessageLoopBase* loop = GetTLSMessageLoop()->Get();
+  MessageLoopBase* loop = GetCurrentMessageLoopBase();
   DCHECK(loop);
 #if defined(OS_ANDROID)
   DCHECK(loop->IsType(MessageLoop::TYPE_UI) ||
@@ -149,7 +132,7 @@
 
 // static
 bool MessageLoopCurrentForUI::IsSet() {
-  MessageLoopBase* loop = GetTLSMessageLoop()->Get();
+  MessageLoopBase* loop = GetCurrentMessageLoopBase();
   return loop &&
 #if defined(OS_ANDROID)
          (loop->IsType(MessageLoop::TYPE_UI) ||
@@ -207,7 +190,7 @@
 
 // static
 MessageLoopCurrentForIO MessageLoopCurrentForIO::Get() {
-  MessageLoopBase* loop = GetTLSMessageLoop()->Get();
+  MessageLoopBase* loop = GetCurrentMessageLoopBase();
   DCHECK(loop);
   DCHECK(loop->IsType(MessageLoop::TYPE_IO));
   return MessageLoopCurrentForIO(loop);
@@ -215,7 +198,7 @@
 
 // static
 bool MessageLoopCurrentForIO::IsSet() {
-  MessageLoopBase* loop = GetTLSMessageLoop()->Get();
+  MessageLoopBase* loop = GetCurrentMessageLoopBase();
   return loop && loop->IsType(MessageLoop::TYPE_IO);
 }
 
diff --git a/base/message_loop/message_loop_current.h b/base/message_loop/message_loop_current.h
index bcab89d6..1809f87 100644
--- a/base/message_loop/message_loop_current.h
+++ b/base/message_loop/message_loop_current.h
@@ -187,18 +187,10 @@
   bool IsIdleForTesting();
 
  protected:
-  // Binds |current| to the current thread. It will from then on be the
-  // MessageLoop driven by MessageLoopCurrent on this thread. This is only meant
-  // to be invoked by the MessageLoop itself.
-  static void BindToCurrentThreadInternal(MessageLoopBase* current);
-
-  // Unbinds |current| from the current thread. Must be invoked on the same
-  // thread that invoked |BindToCurrentThreadInternal(current)|. This is only
-  // meant to be invoked by the MessageLoop itself.
-  static void UnbindFromCurrentThreadInternal(MessageLoopBase* current);
-
   explicit MessageLoopCurrent(MessageLoopBase* current) : current_(current) {}
 
+  static MessageLoopBase* GetCurrentMessageLoopBase();
+
   friend class MessageLoopImpl;
   friend class MessagePumpLibeventTest;
   friend class ScheduleWorkTest;
@@ -207,11 +199,6 @@
   friend class MessageLoopTaskRunnerTest;
   friend class web::TestWebThreadBundle;
 
-  // Return the pointer to MessageLoop for internal needs.
-  // All other callers should call MessageLoopCurrent::Get().
-  // TODO(altimin): Remove this.
-  MessageLoopBase* ToMessageLoopBaseDeprecated() const { return current_; }
-
   MessageLoopBase* current_;
 };
 
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
index 0118b54..d622291 100644
--- a/base/task/sequence_manager/sequence_manager_impl.cc
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -14,6 +14,7 @@
 #include "base/json/json_writer.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop_current.h"
+#include "base/no_destructor.h"
 #include "base/optional.h"
 #include "base/rand_util.h"
 #include "base/task/sequence_manager/real_time_domain.h"
@@ -23,6 +24,7 @@
 #include "base/task/sequence_manager/work_queue.h"
 #include "base/task/sequence_manager/work_queue_sets.h"
 #include "base/threading/thread_id_name_manager.h"
+#include "base/threading/thread_local.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/tick_clock.h"
 #include "base/trace_event/trace_event.h"
@@ -30,6 +32,16 @@
 
 namespace base {
 namespace sequence_manager {
+namespace {
+
+base::ThreadLocalPointer<internal::SequenceManagerImpl>*
+GetTLSSequenceManagerImpl() {
+  static NoDestructor<ThreadLocalPointer<internal::SequenceManagerImpl>>
+      lazy_tls_ptr;
+  return lazy_tls_ptr.get();
+}
+
+}  // namespace
 
 // This controls how big the the initial for
 // |MainThreadOnly::task_execution_stack| should be. We don't expect to see
@@ -124,6 +136,11 @@
 
 }  // namespace
 
+// static
+SequenceManagerImpl* SequenceManagerImpl::GetCurrent() {
+  return GetTLSSequenceManagerImpl()->Get();
+}
+
 SequenceManagerImpl::SequenceManagerImpl(
     std::unique_ptr<internal::ThreadController> controller,
     SequenceManager::Settings settings)
@@ -184,8 +201,10 @@
     observer.WillDestroyCurrentMessageLoop();
 
   // OK, now make it so that no one can find us.
-  if (GetMessagePump())
-    MessageLoopCurrent::UnbindFromCurrentThreadInternal(this);
+  if (GetMessagePump()) {
+    DCHECK_EQ(this, GetTLSSequenceManagerImpl()->Get());
+    GetTLSSequenceManagerImpl()->Set(nullptr);
+  }
 }
 
 SequenceManagerImpl::MainThreadOnly::MainThreadOnly(
@@ -205,8 +224,7 @@
 // static
 std::unique_ptr<SequenceManagerImpl> SequenceManagerImpl::CreateOnCurrentThread(
     SequenceManager::Settings settings) {
-  MessageLoopBase* message_loop_base =
-      MessageLoopCurrent::Get()->ToMessageLoopBaseDeprecated();
+  MessageLoopBase* message_loop_base = GetTLSSequenceManagerImpl()->Get();
   std::unique_ptr<SequenceManagerImpl> manager(new SequenceManagerImpl(
       ThreadControllerImpl::Create(message_loop_base, settings.clock),
       std::move(settings)));
@@ -264,8 +282,11 @@
 void SequenceManagerImpl::CompleteInitializationOnBoundThread() {
   controller_->AddNestingObserver(this);
   main_thread_only().nesting_observer_registered_ = true;
-  if (GetMessagePump())
-    MessageLoopCurrent::BindToCurrentThreadInternal(this);
+  if (GetMessagePump()) {
+    DCHECK(!GetTLSSequenceManagerImpl()->Get())
+        << "Can't register a second SequenceManagerImpl on the same thread.";
+    GetTLSSequenceManagerImpl()->Set(this);
+  }
 }
 
 void SequenceManagerImpl::RegisterTimeDomain(TimeDomain* time_domain) {
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h
index 20bb55fe..b1d440e 100644
--- a/base/task/sequence_manager/sequence_manager_impl.h
+++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -202,6 +202,12 @@
   friend class ::base::sequence_manager::SequenceManagerForTest;
 
  private:
+  // Returns the SequenceManager running the
+  // current thread. It must only be used on the thread it was obtained.
+  // Only to be used by MessageLoopCurrent for the moment
+  static SequenceManagerImpl* GetCurrent();
+  friend class ::base::MessageLoopCurrent;
+
   enum class ProcessTaskResult {
     kDeferred,
     kExecuted,
diff --git a/build/config/chromecast_build.gni b/build/config/chromecast_build.gni
index 13d4b43..f93f40b 100644
--- a/build/config/chromecast_build.gni
+++ b/build/config/chromecast_build.gni
@@ -10,6 +10,11 @@
   # Linux and Android.
   is_chromecast = false
 
+  # If true, IS_CAST_DEBUG_BUILD() will evaluate to 1 in version.h. Otherwise,
+  # it will evaluate to 0. Overriding this when is_debug=false is useful for
+  # doing engineering builds.
+  cast_is_debug = is_debug
+
   # chromecast_branding is used to include or exclude Google-branded components.
   # Set it to "public" for a Chromium build.
   chromecast_branding = "public"
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index b363eb1..d99fadd 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -83,9 +83,9 @@
 # For unofficial (e.g. development) builds and non-Chrome branded (e.g. Cronet
 # which doesn't use Crashpad, crbug.com/479283) builds it's useful to be able
 # to unwind at runtime.
-exclude_unwind_tables =
-    (is_chrome_branded && is_official_build) ||
-    (is_chromecast && !is_cast_desktop_build && !is_debug && !is_fuchsia)
+exclude_unwind_tables = (is_chrome_branded && is_official_build) ||
+                        (is_chromecast && !is_cast_desktop_build && !is_debug &&
+                         !cast_is_debug && !is_fuchsia)
 
 # If true, optimize for size. Does not affect windows builds.
 # Linux & Mac favor speed over size.
diff --git a/build/sanitizers/lsan_suppressions.cc b/build/sanitizers/lsan_suppressions.cc
index 2d1dba1..63838ac 100644
--- a/build/sanitizers/lsan_suppressions.cc
+++ b/build/sanitizers/lsan_suppressions.cc
@@ -75,9 +75,6 @@
     "leak:ppapi::proxy::PPP_Instance_Private_ProxyTest_PPPInstancePrivate_"
     "Test\n"
 
-    // http://crbug.com/322671
-    "leak:content::SpeechRecognitionBrowserTest::SetUpOnMainThread\n"
-
     // http://crbug.com/355641
     "leak:TrayAccessibilityTest\n"
 
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc
index c77515e..3f61e1c6 100644
--- a/build/sanitizers/tsan_suppressions.cc
+++ b/build/sanitizers/tsan_suppressions.cc
@@ -241,9 +241,6 @@
     // http://crbug.com/691029
     "deadlock:libGLX.so*\n"
 
-    // http://crbug.com/719633
-    "race:crypto::EnsureNSSInit()\n"
-
     // http://crbug.com/695929
     "race:base::i18n::IsRTL\n"
     "race:base::i18n::SetICUDefaultLocale\n"
diff --git a/build/toolchain/win/rc/rc.py b/build/toolchain/win/rc/rc.py
index 2338762..2eff7d2 100755
--- a/build/toolchain/win/rc/rc.py
+++ b/build/toolchain/win/rc/rc.py
@@ -141,12 +141,7 @@
   # lines in the file except the preprocessor directives."""
   # Thankfully, the Microsoft headers are mostly good about putting everything
   # in the system headers behind `if !defined(RC_INVOKED)`, so regular
-  # preprocessing with RC_INVOKED defined almost works. The one exception
-  # is struct tagCRGB in dlgs.h, but that will be fixed in the next major
-  # SDK release too.
-  # TODO(thakis): Remove this once an SDK with the fix has been released.
-  preprocessed_output = re.sub('typedef struct tagCRGB\s*{[^}]*} CRGB;', '',
-                               preprocessed_output)
+  # preprocessing with RC_INVOKED defined works.
   return preprocessed_output
 
 
diff --git a/build/toolchain/win/tool_wrapper.py b/build/toolchain/win/tool_wrapper.py
index 6f01ebf40..f173adb 100644
--- a/build/toolchain/win/tool_wrapper.py
+++ b/build/toolchain/win/tool_wrapper.py
@@ -8,6 +8,8 @@
 is used to set up calls to tools used by the build that need wrappers.
 """
 
+from __future__ import print_function
+
 import os
 import re
 import shutil
@@ -154,7 +156,7 @@
       if (not line.startswith('   Creating library ') and
           not line.startswith('Generating code') and
           not line.startswith('Finished generating code')):
-        print line,
+        print(line)
     result = link.wait()
     if result == 0 and sys.platform == 'win32':
       # Flush the file buffers to try to work around a Windows 10 kernel bug,
@@ -178,7 +180,7 @@
     out, _ = popen.communicate()
     for line in out.splitlines():
       if not line.startswith(' Assembling: '):
-        print line
+        print(line)
     return popen.returncode
 
   def ExecRcWrapper(self, arch, *args):
@@ -207,11 +209,13 @@
     if rc_exe_exit_code == 0:
       # Since tool("rc") can't have deps, add deps on this script and on rc.py
       # and its deps here, so that rc edges become dirty if rc.py changes.
-      print 'Note: including file: ../../build/toolchain/win/tool_wrapper.py'
-      print 'Note: including file: ../../build/toolchain/win/rc/rc.py'
-      print 'Note: including file: ../../build/toolchain/win/rc/linux64/rc.sha1'
-      print 'Note: including file: ../../build/toolchain/win/rc/mac/rc.sha1'
-      print 'Note: including file: ../../build/toolchain/win/rc/win/rc.exe.sha1'
+      print('Note: including file: ../../build/toolchain/win/tool_wrapper.py')
+      print('Note: including file: ../../build/toolchain/win/rc/rc.py')
+      print(
+          'Note: including file: ../../build/toolchain/win/rc/linux64/rc.sha1')
+      print('Note: including file: ../../build/toolchain/win/rc/mac/rc.sha1')
+      print(
+          'Note: including file: ../../build/toolchain/win/rc/win/rc.exe.sha1')
 
     # 2. Run Microsoft rc.exe.
     if sys.platform == 'win32' and rc_exe_exit_code == 0:
diff --git a/build/win/copy_cdb_to_output.py b/build/win/copy_cdb_to_output.py
index 327c71b..1f0f22a 100755
--- a/build/win/copy_cdb_to_output.py
+++ b/build/win/copy_cdb_to_output.py
@@ -3,6 +3,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from __future__ import print_function
+
 import glob
 import hashlib
 import os
@@ -38,7 +40,7 @@
       ((not os.path.isfile(target)) or
        _HexDigest(source) != _HexDigest(target))):
     if verbose:
-      print 'Copying %s to %s...' % (source, target)
+      print('Copying %s to %s...' % (source, target))
     if os.path.exists(target):
       os.unlink(target)
     shutil.copy(source, target)
@@ -69,7 +71,7 @@
   elif target_arch in ['x64', 'arm64']:
     src_arch = target_arch
   else:
-    print 'copy_cdb_to_output.py: unknown target_arch %s' % target_arch
+    print('copy_cdb_to_output.py: unknown target_arch %s' % target_arch)
     sys.exit(1)
   # We need to copy multiple files, so cache the computed source directory.
   src_dir = os.path.join(win_sdk_dir, 'Debuggers', src_arch)
@@ -109,8 +111,8 @@
 
 def main():
   if len(sys.argv) < 2:
-    print >>sys.stderr, 'Usage: copy_cdb_to_output.py <output_dir> ' + \
-        '<target_arch>'
+    print('Usage: copy_cdb_to_output.py <output_dir> ' + \
+        '<target_arch>', file=sys.stderr)
     return 1
   return _CopyCDBToOutput(sys.argv[1], sys.argv[2])
 
diff --git a/build/win/message_compiler.py b/build/win/message_compiler.py
index 7c1902e4..ee4abdc 100644
--- a/build/win/message_compiler.py
+++ b/build/win/message_compiler.py
@@ -6,6 +6,8 @@
 #
 # Usage: message_compiler.py <environment_file> [<args to mc.exe>*]
 
+from __future__ import print_function
+
 import difflib
 import distutils.dir_util
 import filecmp
@@ -65,7 +67,7 @@
     # we use the 2017 Fall Creator's Update by default.
     mc_help = subprocess.check_output(['mc.exe', '/?'], env=env_dict,
                                       stderr=subprocess.STDOUT, shell=True)
-    version = re.search(r'Message Compiler\s+Version (\S+)', mc_help).group(1)
+    version = re.search(b'Message Compiler\s+Version (\S+)', mc_help).group(1)
     if version != '10.0.15063':
       return
 
@@ -122,20 +124,21 @@
     # in tmp_dir to the checked-in outputs.
     diff = filecmp.dircmp(tmp_dir, source)
     if diff.diff_files or set(diff.left_list) != set(diff.right_list):
-      print 'mc.exe output different from files in %s, see %s' % (source,
-                                                                  tmp_dir)
+      print('mc.exe output different from files in %s, see %s' % (source,
+                                                                  tmp_dir))
       diff.report()
       for f in diff.diff_files:
         if f.endswith('.bin'): continue
         fromfile = os.path.join(source, f)
         tofile = os.path.join(tmp_dir, f)
-        print ''.join(difflib.unified_diff(open(fromfile, 'U').readlines(),
-                                           open(tofile, 'U').readlines(),
-                                           fromfile, tofile))
+        print(''.join(
+            difflib.unified_diff(
+                open(fromfile, 'U').readlines(),
+                open(tofile, 'U').readlines(), fromfile, tofile)))
       delete_tmp_dir = False
       sys.exit(1)
   except subprocess.CalledProcessError as e:
-    print e.output
+    print(e.output)
     sys.exit(e.returncode)
   finally:
     if os.path.exists(tmp_dir) and delete_tmp_dir:
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
index 95d4f1418..773e3af 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
@@ -28,6 +28,7 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.library_loader.LibraryProcessType;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.autofill_assistant.R;
 import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantCarouselCoordinator;
@@ -108,6 +109,7 @@
     // highlight chips and so on.
     @Test
     @MediumTest
+    @DisabledTest // TODO(crbug.com/943483) test fails on "Android CFI" builder.
     public void testStartAndAccept() throws Exception {
         InOrder inOrder = inOrder(mRunnableMock);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifier.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifier.java
index 7f9f52a..4092ad12 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifier.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifier.java
@@ -17,6 +17,7 @@
 import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
 import org.chromium.chrome.browser.customtabs.TabObserverRegistrar;
+import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabController;
 import org.chromium.chrome.browser.dependency_injection.ActivityScope;
 import org.chromium.chrome.browser.init.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.lifecycle.Destroyable;
@@ -93,6 +94,23 @@
         }
     };
 
+    private final CustomTabActivityTabController.Observer mVerifyOnTabSwitchObserver =
+            new CustomTabActivityTabController.Observer() {
+                @Override
+                public void onTabChanged() {
+                    // During startup, onTabChanged is called before the ActivityTabProvider has
+                    // updated to have a Tab. Subsequent calls to onTabChanged occur after the
+                    // corresponding ActivityTabProvider update. Initial startup is covered by the
+                    // verify on page load observer, so it's fine to no-op here.
+                    if (mActivityTabProvider.getActivityTab() == null) return;
+
+                    // When a link with target="_blank" is followed and the user navigates back, we
+                    // don't get the onDidFinishNavigation event (because the original page wasn't
+                    // navigated away from, it was only ever hidden). https://crbug.com/942088
+                    verify(new Origin(mActivityTabProvider.getActivityTab().getUrl()));
+                }
+            };
+
     @Inject
     public TrustedWebActivityVerifier(Lazy<ClientAppDataRecorder> clientAppDataRecorder,
             CustomTabIntentDataProvider intentDataProvider,
@@ -100,7 +118,8 @@
             ActivityLifecycleDispatcher lifecycleDispatcher,
             TabObserverRegistrar tabObserverRegistrar,
             ActivityTabProvider activityTabProvider,
-            OriginVerifier.Factory originVerifierFactory) {
+            OriginVerifier.Factory originVerifierFactory,
+            CustomTabActivityTabController activityTabController) {
         mClientAppDataRecorder = clientAppDataRecorder;
         mCustomTabsConnection = customTabsConnection;
         mIntentDataProvider = intentDataProvider;
@@ -113,6 +132,7 @@
         mOriginVerifier = originVerifierFactory.create(mClientPackageName, RELATIONSHIP);
 
         tabObserverRegistrar.registerTabObserver(mVerifyOnPageLoadObserver);
+        activityTabController.addObserver(mVerifyOnTabSwitchObserver);
         lifecycleDispatcher.register(this);
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifierTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifierTest.java
index e9a7a32..53fc5823 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifierTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifierTest.java
@@ -37,6 +37,7 @@
 import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
 import org.chromium.chrome.browser.customtabs.TabObserverRegistrar;
+import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabController;
 import org.chromium.chrome.browser.init.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabObserver;
@@ -78,6 +79,7 @@
     @Mock TabObserverRegistrar mTabObserverRegistrar;
     @Mock ActivityLifecycleDispatcher mLifecycleDispatcher;
     @Mock OriginVerifier.Factory mOriginVerifierFactory;
+    @Mock CustomTabActivityTabController mCustomTabActivityTabController;
     @Mock Tab mTab;
     @Captor ArgumentCaptor<TabObserver> mTabObserverCaptor;
 
@@ -96,7 +98,8 @@
         doNothing().when(mTabObserverRegistrar).registerTabObserver(mTabObserverCaptor.capture());
         mVerifier = new TrustedWebActivityVerifier(() -> mClientAppDataRecorder,
                 mIntentDataProvider, mCustomTabsConnection, mLifecycleDispatcher,
-                mTabObserverRegistrar, mActivityTabProvider, mOriginVerifierFactory);
+                mTabObserverRegistrar, mActivityTabProvider, mOriginVerifierFactory,
+                mCustomTabActivityTabController);
     }
 
     @Test
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index d7b200ec..268b2367 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -3829,8 +3829,11 @@
     Password (optional)
   </message>
 
-  <!-- Strings for PluginVm launcher -->
+  <!-- Strings for PluginVm -->
   <!-- TODO(okalitova, timloh): Remove translatable flag after strings are finalized. -->
+  <message name="IDS_PLUGIN_VM_APP_NAME" desc="Name of the PluginVm app." translateable="false">
+    Plugin VM
+  </message>
   <message name="IDS_PLUGIN_VM_LAUNCHER_ENVIRONMENT_SETTING_TITLE" desc="Title of the PluginVm launcher, a dialog for launching PluginVm." translateable="false">
     Finishing <ph name="APP_NAME">PluginVm</ph> environment setting...
   </message>
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service.cc b/chrome/browser/chromeos/crostini/crostini_registry_service.cc
index 87c2bc03..47dd733 100644
--- a/chrome/browser/chromeos/crostini/crostini_registry_service.cc
+++ b/chrome/browser/chromeos/crostini/crostini_registry_service.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
 #include "chrome/browser/chromeos/crostini/crostini_util.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/grit/generated_resources.h"
 #include "chromeos/dbus/vm_applications/apps.pb.h"
@@ -515,9 +516,13 @@
     // Try a lookup with the window app id.
   }
 
-  if (!window_app_id || base::StartsWith(*window_app_id, kArcWindowAppIdPrefix,
-                                         base::CompareCase::SENSITIVE))
+  // TODO(timloh): Crostini shouldn't need to know about Arc and PluginVm.
+  if (!window_app_id ||
+      base::StartsWith(*window_app_id, kArcWindowAppIdPrefix,
+                       base::CompareCase::SENSITIVE) ||
+      plugin_vm::IsPluginVmExoApplicationId(*window_app_id)) {
     return std::string();
+  }
 
   // Wayland apps won't be prefixed with org.chromium.termina.
   if (!base::StartsWith(*window_app_id, kCrostiniWindowAppIdPrefix,
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
index b9009e14..ff231b0 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -1106,12 +1106,6 @@
   Respond(OneArgument(std::move(result)));
 }
 
-ExtensionFunction::ResponseAction
-FileManagerPrivateIsUMAEnabledFunction::Run() {
-  return RespondNow(OneArgument(std::make_unique<base::Value>(
-      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled())));
-}
-
 FileManagerPrivateInternalSetEntryTagFunction::
     FileManagerPrivateInternalSetEntryTagFunction()
     : chrome_details_(this) {}
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
index 16d20d4..d13b57e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
@@ -363,21 +363,6 @@
   const ChromeExtensionFunctionDetails chrome_details_;
 };
 
-// Implements the chrome.fileManagerPrivate.isUMAEnabled method.
-class FileManagerPrivateIsUMAEnabledFunction
-    : public UIThreadExtensionFunction {
- public:
-  FileManagerPrivateIsUMAEnabledFunction() = default;
-  DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.isUMAEnabled",
-                             FILEMANAGERPRIVATE_ISUMAENABLED)
- protected:
-  ~FileManagerPrivateIsUMAEnabledFunction() override = default;
-
- private:
-  ExtensionFunction::ResponseAction Run() override;
-  DISALLOW_COPY_AND_ASSIGN(FileManagerPrivateIsUMAEnabledFunction);
-};
-
 // Implements the chrome.fileManagerPrivate.setEntryTag method.
 class FileManagerPrivateInternalSetEntryTagFunction
     : public LoggedUIThreadExtensionFunction {
diff --git a/chrome/browser/chromeos/file_manager/path_util_unittest.cc b/chrome/browser/chromeos/file_manager/path_util_unittest.cc
index 1facea88..96c6a3a 100644
--- a/chrome/browser/chromeos/file_manager/path_util_unittest.cc
+++ b/chrome/browser/chromeos/file_manager/path_util_unittest.cc
@@ -591,13 +591,13 @@
       storage::ExternalMountPoints::GetSystemInstance();
   std::string downloads_mount_name = GetDownloadsMountPointName(profile_.get());
   base::FilePath downloads = GetDownloadsFolderForProfile(profile_.get());
-  EXPECT_TRUE(mount_points->RegisterFileSystem(
-      downloads_mount_name, storage::kFileSystemTypeNativeLocal,
-      storage::FileSystemMountOption(), downloads));
+  mount_points->RegisterFileSystem(downloads_mount_name,
+                                   storage::kFileSystemTypeNativeLocal,
+                                   storage::FileSystemMountOption(), downloads);
   base::FilePath removable = base::FilePath(kRemovableMediaPath);
-  EXPECT_TRUE(mount_points->RegisterFileSystem(
+  mount_points->RegisterFileSystem(
       chromeos::kSystemMountNameRemovable, storage::kFileSystemTypeNativeLocal,
-      storage::FileSystemMountOption(), base::FilePath(kRemovableMediaPath)));
+      storage::FileSystemMountOption(), base::FilePath(kRemovableMediaPath));
   std::string relative_path_1 = "foo";
   std::string relative_path_2 = "foo/bar";
   std::string mount_name;
@@ -632,12 +632,9 @@
       removable, &mount_name, &file_system_name, &full_path));
 
   // <removable>/foo/
-  // TODO(crbug.com/942371): Extra debugging to detect what is causing flakes.
-  base::FilePath absolute_path = removable.Append(relative_path_1);
-  base::FilePath virtual_path;
-  EXPECT_TRUE(mount_points->GetVirtualPath(absolute_path, &virtual_path));
   EXPECT_TRUE(ExtractMountNameFileSystemNameFullPath(
-      absolute_path, &mount_name, &file_system_name, &full_path));
+      removable.Append(relative_path_1), &mount_name, &file_system_name,
+      &full_path));
   EXPECT_EQ(mount_name, "removable/foo");
   EXPECT_EQ(file_system_name, "foo");
   EXPECT_EQ(full_path, "/");
diff --git a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
index 2fccbe1e2..a006b6e 100644
--- a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
+++ b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
@@ -254,6 +254,7 @@
     main_profile_.reset();
     disk_mount_manager_.reset();
     chromeos::PowerManagerClient::Shutdown();
+    thread_bundle_.RunUntilIdle();
   }
 
   Profile* profile() const { return main_profile_->profile(); }
@@ -726,8 +727,7 @@
   volume_manager()->RemoveObserver(&observer);
 }
 
-// TODO(crbug.com/943570): test is flaky, disabled.
-TEST_F(VolumeManagerTest, DISABLED_OnFormatEvent_CompletedFailed) {
+TEST_F(VolumeManagerTest, OnFormatEvent_CompletedFailed) {
   LoggingObserver observer;
   volume_manager()->AddObserver(&observer);
 
@@ -1014,7 +1014,7 @@
   volume_manager()->RemoveObserver(&observer);
 }
 
-TEST_F(VolumeManagerTest, DISABLED_OnRenameEvent_Completed) {
+TEST_F(VolumeManagerTest, OnRenameEvent_Completed) {
   LoggingObserver observer;
   volume_manager()->AddObserver(&observer);
 
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
index a1475ec..ca9e419 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
@@ -28,9 +28,9 @@
 namespace chromeos {
 namespace file_system_provider {
 
-// Converts net::CompletionCallback to net::Int64CompletionCallback.
-void Int64ToIntCompletionCallback(net::CompletionOnceCallback callback,
-                                  int64_t result) {
+// Converts net::CompletionOnceCallback to net::Int64CompletionOnceCallback.
+void Int64ToIntCompletionOnceCallback(net::CompletionOnceCallback callback,
+                                      int64_t result) {
   std::move(callback).Run(static_cast<int>(result));
 }
 
@@ -220,22 +220,23 @@
 }
 
 void FileStreamReader::Initialize(
-    const base::Closure& pending_closure,
-    const net::Int64CompletionCallback& error_callback) {
+    base::OnceClosure pending_closure,
+    net::Int64CompletionOnceCallback error_callback) {
   DCHECK_EQ(NOT_INITIALIZED, state_);
   state_ = INITIALIZING;
 
   base::PostTaskWithTraits(
       FROM_HERE, {BrowserThread::UI},
       base::BindOnce(&OperationRunner::OpenFileOnUIThread, runner_, url_,
-                     base::Bind(&FileStreamReader::OnOpenFileCompleted,
-                                weak_ptr_factory_.GetWeakPtr(), pending_closure,
-                                error_callback)));
+                     base::BindOnce(&FileStreamReader::OnOpenFileCompleted,
+                                    weak_ptr_factory_.GetWeakPtr(),
+                                    std::move(pending_closure),
+                                    std::move(error_callback))));
 }
 
 void FileStreamReader::OnOpenFileCompleted(
-    const base::Closure& pending_closure,
-    const net::Int64CompletionCallback& error_callback,
+    base::OnceClosure pending_closure,
+    net::Int64CompletionOnceCallback error_callback,
     base::File::Error result) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK_EQ(INITIALIZING, state_);
@@ -244,7 +245,7 @@
   // Read() or GetLength() pending request.
   if (result != base::File::FILE_OK) {
     state_ = FAILED;
-    error_callback.Run(net::FileErrorToNetError(result));
+    std::move(error_callback).Run(net::FileErrorToNetError(result));
     return;
   }
 
@@ -254,14 +255,15 @@
   base::PostTaskWithTraits(
       FROM_HERE, {BrowserThread::UI},
       base::BindOnce(&OperationRunner::GetMetadataOnUIThread, runner_,
-                     base::Bind(&FileStreamReader::OnInitializeCompleted,
-                                weak_ptr_factory_.GetWeakPtr(), pending_closure,
-                                error_callback)));
+                     base::BindOnce(&FileStreamReader::OnInitializeCompleted,
+                                    weak_ptr_factory_.GetWeakPtr(),
+                                    std::move(pending_closure),
+                                    std::move(error_callback))));
 }
 
 void FileStreamReader::OnInitializeCompleted(
-    const base::Closure& pending_closure,
-    const net::Int64CompletionCallback& error_callback,
+    base::OnceClosure pending_closure,
+    net::Int64CompletionOnceCallback error_callback,
     std::unique_ptr<EntryMetadata> metadata,
     base::File::Error result) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -270,7 +272,7 @@
   // In case of an error, abort.
   if (result != base::File::FILE_OK) {
     state_ = FAILED;
-    error_callback.Run(net::FileErrorToNetError(result));
+    std::move(error_callback).Run(net::FileErrorToNetError(result));
     return;
   }
 
@@ -280,7 +282,7 @@
   if (!expected_modification_time_.is_null() &&
       *metadata->modification_time != expected_modification_time_) {
     state_ = FAILED;
-    error_callback.Run(net::ERR_UPLOAD_FILE_CHANGED);
+    std::move(error_callback).Run(net::ERR_UPLOAD_FILE_CHANGED);
     return;
   }
 
@@ -288,7 +290,7 @@
   state_ = INITIALIZED;
 
   // Run the task waiting for the initialization to be completed.
-  pending_closure.Run();
+  std::move(pending_closure).Run();
 }
 
 int FileStreamReader::Read(net::IOBuffer* buffer,
@@ -305,14 +307,15 @@
   switch (state_) {
     case NOT_INITIALIZED:
       // Lazily initialize with the first call to Read().
-      Initialize(base::Bind(&FileStreamReader::ReadAfterInitialized,
-                            weak_ptr_factory_.GetWeakPtr(),
-                            base::WrapRefCounted(buffer), buffer_length,
-                            base::Bind(&FileStreamReader::OnReadCompleted,
-                                       weak_ptr_factory_.GetWeakPtr())),
-                 base::Bind(&Int64ToIntCompletionCallback,
-                            base::Bind(&FileStreamReader::OnReadCompleted,
-                                       weak_ptr_factory_.GetWeakPtr())));
+      Initialize(
+          base::BindOnce(&FileStreamReader::ReadAfterInitialized,
+                         weak_ptr_factory_.GetWeakPtr(),
+                         base::WrapRefCounted(buffer), buffer_length,
+                         base::BindRepeating(&FileStreamReader::OnReadCompleted,
+                                             weak_ptr_factory_.GetWeakPtr())),
+          base::BindOnce(&Int64ToIntCompletionOnceCallback,
+                         base::BindOnce(&FileStreamReader::OnReadCompleted,
+                                        weak_ptr_factory_.GetWeakPtr())));
       break;
 
     case INITIALIZING:
@@ -320,9 +323,10 @@
       break;
 
     case INITIALIZED:
-      ReadAfterInitialized(buffer, buffer_length,
-                           base::Bind(&FileStreamReader::OnReadCompleted,
-                                      weak_ptr_factory_.GetWeakPtr()));
+      ReadAfterInitialized(
+          buffer, buffer_length,
+          base::BindRepeating(&FileStreamReader::OnReadCompleted,
+                              weak_ptr_factory_.GetWeakPtr()));
       break;
 
     case FAILED:
@@ -347,10 +351,10 @@
   switch (state_) {
     case NOT_INITIALIZED:
       // Lazily initialize with the first call to GetLength().
-      Initialize(base::Bind(&FileStreamReader::GetLengthAfterInitialized,
-                            weak_ptr_factory_.GetWeakPtr()),
-                 base::Bind(&FileStreamReader::OnGetLengthCompleted,
-                            weak_ptr_factory_.GetWeakPtr()));
+      Initialize(base::BindOnce(&FileStreamReader::GetLengthAfterInitialized,
+                                weak_ptr_factory_.GetWeakPtr()),
+                 base::BindOnce(&FileStreamReader::OnGetLengthCompleted,
+                                weak_ptr_factory_.GetWeakPtr()));
       break;
 
     case INITIALIZING:
@@ -376,17 +380,18 @@
 void FileStreamReader::ReadAfterInitialized(
     scoped_refptr<net::IOBuffer> buffer,
     int buffer_length,
-    const net::CompletionCallback& callback) {
+    const net::CompletionRepeatingCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK_EQ(INITIALIZED, state_);
 
   current_length_ = 0;
   base::PostTaskWithTraits(
       FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(&OperationRunner::ReadFileOnUIThread, runner_, buffer,
-                     current_offset_, buffer_length,
-                     base::Bind(&FileStreamReader::OnReadChunkReceived,
-                                weak_ptr_factory_.GetWeakPtr(), callback)));
+      base::BindOnce(
+          &OperationRunner::ReadFileOnUIThread, runner_, buffer,
+          current_offset_, buffer_length,
+          base::BindRepeating(&FileStreamReader::OnReadChunkReceived,
+                              weak_ptr_factory_.GetWeakPtr(), callback)));
 }
 
 void FileStreamReader::GetLengthAfterInitialized() {
@@ -402,7 +407,7 @@
 }
 
 void FileStreamReader::OnReadChunkReceived(
-    const net::CompletionCallback& callback,
+    const net::CompletionRepeatingCallback& callback,
     int chunk_length,
     bool has_more,
     base::File::Error result) {
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.h b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.h
index 580908f..8206439 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.h
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.h
@@ -13,8 +13,8 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
-#include "net/base/completion_callback.h"
 #include "net/base/completion_once_callback.h"
+#include "net/base/completion_repeating_callback.h"
 #include "storage/browser/fileapi/file_stream_reader.h"
 #include "storage/browser/fileapi/file_system_url.h"
 
@@ -66,18 +66,17 @@
 
   // Initializes the reader by opening the file. When completed with success,
   // runs the |pending_closure|. Otherwise, calls the |error_callback|.
-  void Initialize(const base::Closure& pending_closure,
-                  const net::Int64CompletionCallback& error_callback);
+  void Initialize(base::OnceClosure pending_closure,
+                  net::Int64CompletionOnceCallback error_callback);
 
   // Called when opening a file is completed with either a success or an error.
-  void OnOpenFileCompleted(
-      const base::Closure& pending_closure,
-      const net::Int64CompletionCallback& error_callback,
-      base::File::Error result);
+  void OnOpenFileCompleted(base::OnceClosure pending_closure,
+                           net::Int64CompletionOnceCallback error_callback,
+                           base::File::Error result);
 
   // Called when initialization is completed with either a success or an error.
-  void OnInitializeCompleted(const base::Closure& pending_closure,
-                             const net::Int64CompletionCallback& error_callback,
+  void OnInitializeCompleted(base::OnceClosure pending_closure,
+                             net::Int64CompletionOnceCallback error_callback,
                              std::unique_ptr<EntryMetadata> metadata,
                              base::File::Error result);
 
@@ -85,7 +84,7 @@
   // this may be called multiple times per single Read() call, as long as
   // |has_more| is set to true. |result| is set to success only if reading is
   // successful, and the file has not changed while reading.
-  void OnReadChunkReceived(const net::CompletionCallback& callback,
+  void OnReadChunkReceived(const net::CompletionRepeatingCallback& callback,
                            int chunk_length,
                            bool has_more,
                            base::File::Error result);
@@ -99,7 +98,7 @@
   // Same as Read(), but called after initializing is completed.
   void ReadAfterInitialized(scoped_refptr<net::IOBuffer> buffer,
                             int buffer_length,
-                            const net::CompletionCallback& callback);
+                            const net::CompletionRepeatingCallback& callback);
 
   // Same as GetLength(), but called after initializing is completed.
   void GetLengthAfterInitialized();
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.cc b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.cc
index c9f95ac7..15fdfbd8 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.cc
@@ -157,9 +157,8 @@
                          this);
 }
 
-void FileStreamWriter::Initialize(
-    const base::Closure& pending_closure,
-    const net::CompletionCallback& error_callback) {
+void FileStreamWriter::Initialize(base::OnceClosure pending_closure,
+                                  net::CompletionOnceCallback error_callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK_EQ(NOT_INITIALIZED, state_);
   state_ = INITIALIZING;
@@ -167,14 +166,15 @@
   base::PostTaskWithTraits(
       FROM_HERE, {BrowserThread::UI},
       base::BindOnce(&OperationRunner::OpenFileOnUIThread, runner_, url_,
-                     base::Bind(&FileStreamWriter::OnOpenFileCompleted,
-                                weak_ptr_factory_.GetWeakPtr(), pending_closure,
-                                error_callback)));
+                     base::BindOnce(&FileStreamWriter::OnOpenFileCompleted,
+                                    weak_ptr_factory_.GetWeakPtr(),
+                                    std::move(pending_closure),
+                                    std::move(error_callback))));
 }
 
 void FileStreamWriter::OnOpenFileCompleted(
-    const base::Closure& pending_closure,
-    const net::CompletionCallback& error_callback,
+    base::OnceClosure pending_closure,
+    net::CompletionOnceCallback error_callback,
     base::File::Error result) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(state_ == INITIALIZING || state_ == CANCELLING);
@@ -185,7 +185,7 @@
   // Write() pending request.
   if (result != base::File::FILE_OK) {
     state_ = FAILED;
-    error_callback.Run(net::FileErrorToNetError(result));
+    std::move(error_callback).Run(net::FileErrorToNetError(result));
     return;
   }
 
@@ -193,7 +193,7 @@
   state_ = INITIALIZED;
 
   // Run the task waiting for the initialization to be completed.
-  pending_closure.Run();
+  std::move(pending_closure).Run();
 }
 
 int FileStreamWriter::Write(net::IOBuffer* buffer,
@@ -210,13 +210,14 @@
   switch (state_) {
     case NOT_INITIALIZED:
       // Lazily initialize with the first call to Write().
-      Initialize(base::Bind(&FileStreamWriter::WriteAfterInitialized,
-                            weak_ptr_factory_.GetWeakPtr(),
-                            base::WrapRefCounted(buffer), buffer_length,
-                            base::Bind(&FileStreamWriter::OnWriteCompleted,
-                                       weak_ptr_factory_.GetWeakPtr())),
-                 base::Bind(&FileStreamWriter::OnWriteCompleted,
-                            weak_ptr_factory_.GetWeakPtr()));
+      Initialize(
+          base::BindOnce(&FileStreamWriter::WriteAfterInitialized,
+                         weak_ptr_factory_.GetWeakPtr(),
+                         base::WrapRefCounted(buffer), buffer_length,
+                         base::BindOnce(&FileStreamWriter::OnWriteCompleted,
+                                        weak_ptr_factory_.GetWeakPtr())),
+          base::BindOnce(&FileStreamWriter::OnWriteCompleted,
+                         weak_ptr_factory_.GetWeakPtr()));
       break;
 
     case INITIALIZING:
@@ -225,8 +226,8 @@
 
     case INITIALIZED:
       WriteAfterInitialized(buffer, buffer_length,
-                            base::Bind(&FileStreamWriter::OnWriteCompleted,
-                                       weak_ptr_factory_.GetWeakPtr()));
+                            base::BindOnce(&FileStreamWriter::OnWriteCompleted,
+                                           weak_ptr_factory_.GetWeakPtr()));
       break;
 
     case EXECUTING:
@@ -277,7 +278,7 @@
 
 void FileStreamWriter::OnWriteFileCompleted(
     int buffer_length,
-    const net::CompletionCallback& callback,
+    net::CompletionOnceCallback callback,
     base::File::Error result) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(state_ == EXECUTING || state_ == CANCELLING);
@@ -288,12 +289,12 @@
 
   if (result != base::File::FILE_OK) {
     state_ = FAILED;
-    callback.Run(net::FileErrorToNetError(result));
+    std::move(callback).Run(net::FileErrorToNetError(result));
     return;
   }
 
   current_offset_ += buffer_length;
-  callback.Run(buffer_length);
+  std::move(callback).Run(buffer_length);
 }
 
 void FileStreamWriter::OnWriteCompleted(int result) {
@@ -308,7 +309,7 @@
 void FileStreamWriter::WriteAfterInitialized(
     scoped_refptr<net::IOBuffer> buffer,
     int buffer_length,
-    const net::CompletionCallback& callback) {
+    net::CompletionOnceCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(state_ == INITIALIZED || state_ == CANCELLING);
   if (state_ == CANCELLING)
@@ -318,11 +319,11 @@
 
   base::PostTaskWithTraits(
       FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(
-          &OperationRunner::WriteFileOnUIThread, runner_, buffer,
-          current_offset_, buffer_length,
-          base::Bind(&FileStreamWriter::OnWriteFileCompleted,
-                     weak_ptr_factory_.GetWeakPtr(), buffer_length, callback)));
+      base::BindOnce(&OperationRunner::WriteFileOnUIThread, runner_, buffer,
+                     current_offset_, buffer_length,
+                     base::BindOnce(&FileStreamWriter::OnWriteFileCompleted,
+                                    weak_ptr_factory_.GetWeakPtr(),
+                                    buffer_length, std::move(callback))));
 }
 
 }  // namespace file_system_provider
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.h b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.h
index 7c85885..f22484a 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.h
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.h
@@ -12,7 +12,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
-#include "net/base/completion_callback.h"
 #include "net/base/completion_once_callback.h"
 #include "storage/browser/fileapi/file_stream_writer.h"
 #include "storage/browser/fileapi/file_system_url.h"
@@ -53,7 +52,7 @@
 
   // Called when OperationRunner::WriteOnUIThread is completed.
   void OnWriteFileCompleted(int buffer_length,
-                            const net::CompletionCallback& callback,
+                            net::CompletionOnceCallback callback,
                             base::File::Error result);
 
   // Called when Write() operation is completed with either a success or an
@@ -62,19 +61,18 @@
 
   // Initializes the writer by opening the file. When completed with success,
   // runs the |pending_closure|. Otherwise, calls the |error_callback|.
-  void Initialize(const base::Closure& pending_closure,
-                  const net::CompletionCallback& error_callback);
+  void Initialize(base::OnceClosure pending_closure,
+                  net::CompletionOnceCallback error_callback);
 
   // Called when opening a file is completed with either a success or an error.
-  void OnOpenFileCompleted(
-      const base::Closure& pending_closure,
-      const net::CompletionCallback& error_callback,
-      base::File::Error result);
+  void OnOpenFileCompleted(base::OnceClosure pending_closure,
+                           net::CompletionOnceCallback error_callback,
+                           base::File::Error result);
 
   // Same as Write(), but called after initializing is completed.
   void WriteAfterInitialized(scoped_refptr<net::IOBuffer> buffer,
                              int buffer_length,
-                             const net::CompletionCallback& callback);
+                             net::CompletionOnceCallback callback);
 
   net::CompletionOnceCallback write_callback_;
   storage::FileSystemURL url_;
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
index daed843f..55c1d2f 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
@@ -14,7 +14,7 @@
 
 namespace plugin_vm {
 
-bool IsPluginVmAllowedForProfile(Profile* profile) {
+bool IsPluginVmAllowedForProfile(const Profile* profile) {
   // Check that the profile is eligible.
   if (!profile || profile->IsChild() || profile->IsLegacySupervised() ||
       profile->IsOffTheRecord() ||
@@ -62,6 +62,11 @@
   return true;
 }
 
+// TODO(timloh): Implement this (crbug.com/940319).
+bool IsPluginVmExoApplicationId(const std::string& app_id) {
+  return false;
+}
+
 std::string GetPluginVmLicenseKey() {
   std::string plugin_vm_license_key;
   if (!chromeos::CrosSettings::Get()->GetString(chromeos::kPluginVmLicenseKey,
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h
index eec3668..bc6c778 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h
@@ -11,13 +11,19 @@
 
 namespace plugin_vm {
 
+// Generated as crx_file::id_util::GenerateId("org.chromium.plugin_vm");
+constexpr char kPluginVmAppId[] = "lgjpclljbbmphhnalkeplcmnjpfmmaek";
+
 // Checks if PluginVm is allowed for the current profile.
-bool IsPluginVmAllowedForProfile(Profile* profile);
+bool IsPluginVmAllowedForProfile(const Profile* profile);
 // Checks if PluginVm is configured for the current profile.
 bool IsPluginVmConfigured(Profile* profile);
 
 void ShowPluginVmLauncherView(Profile* profile);
 
+// Checks if an exo window's app id is for plugin vm.
+bool IsPluginVmExoApplicationId(const std::string& app_id);
+
 // Retrieves the license key to be used for PluginVm. If
 // none is set this will return an empty string.
 std::string GetPluginVmLicenseKey();
diff --git a/chrome/browser/chromeos/policy/display_resolution_handler.cc b/chrome/browser/chromeos/policy/display_resolution_handler.cc
index feb7d5e..b52a2d6 100644
--- a/chrome/browser/chromeos/policy/display_resolution_handler.cc
+++ b/chrome/browser/chromeos/policy/display_resolution_handler.cc
@@ -233,6 +233,7 @@
     resized_display_ids_.insert(display_id);
     cros_display_config->SetDisplayProperties(
         display_unit_info->id, std::move(new_config),
+        ash::mojom::DisplayConfigSource::kPolicy,
         base::BindOnce([](ash::mojom::DisplayConfigResult result) {
           if (result == ash::mojom::DisplayConfigResult::kSuccess) {
             VLOG(1) << "Successfully changed display mode.";
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
index 86cc004d..f261dc8 100644
--- a/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
+++ b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
@@ -68,7 +68,8 @@
     config_properties->rotation =
         ash::mojom::DisplayRotation::New(display_rotation_default_);
     cros_display_config->SetDisplayProperties(
-        display_unit_info->id, std::move(config_properties), base::DoNothing());
+        display_unit_info->id, std::move(config_properties),
+        ash::mojom::DisplayConfigSource::kPolicy, base::DoNothing());
   }
 }
 
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
index d87b11b..14eb754 100644
--- a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
+++ b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
@@ -101,6 +101,7 @@
   // Sync is running.
   syncer::SyncService* sync_service =
       ProfileSyncServiceFactory::GetForProfile(profile);
+  sync_service->GetUserSettings()->SetSyncRequested(true);
   sync_service->GetUserSettings()->SetFirstSetupComplete();
 
   ASSERT_EQ(sync_ui_util::SYNCED, sync_ui_util::GetStatus(profile));
diff --git a/chrome/browser/extensions/api/preference/preferences_private_apitest.cc b/chrome/browser/extensions/api/preference/preferences_private_apitest.cc
deleted file mode 100644
index 0dd2f8c..0000000
--- a/chrome/browser/extensions/api/preference/preferences_private_apitest.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/extension_apitest.h"
-#include "extensions/common/switches.h"
-
-namespace extensions {
-
-class PreferencesPrivateApiTest : public ExtensionApiTest {
- public:
-  PreferencesPrivateApiTest() {}
-  ~PreferencesPrivateApiTest() override {}
-
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    ExtensionApiTest::SetUpCommandLine(command_line);
-    command_line->AppendSwitchASCII(switches::kWhitelistedExtensionID,
-                                    "cpfhkdbjfdgdebcjlifoldbijinjfifp");
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PreferencesPrivateApiTest);
-};
-
-IN_PROC_BROWSER_TEST_F(PreferencesPrivateApiTest, TestEasyUnlockEvent) {
-  ASSERT_TRUE(RunExtensionTest("preferences_private")) << message_;
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
index c3e0289..5ab5e14 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
@@ -113,7 +113,7 @@
     ExtensionWebRequestEventRouter::EventResponse* response) {
   ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
       profile, extension_id, event_name, sub_event_name, request_id,
-      0 /* embedder_process_id */, 0 /* web_view_instance_id */, response);
+      0 /* render_process_id */, 0 /* web_view_instance_id */, response);
 }
 
 // Returns whether |warnings| contains an extension for |extension_id|.
@@ -982,7 +982,7 @@
   EXPECT_EQ(i, ipc_sender_.sent_end());
 }
 
-// Tests that |embedder_process_id| is not relevant for adding and removing
+// Tests that |render_process_id| is not relevant for adding and removing
 // listeners with |web_view_instance_id| = 0.
 TEST_F(ExtensionWebRequestTest, AddAndRemoveListeners) {
   std::string ext_id("abcdefghijklmnopabcdefghijklmnop");
@@ -998,12 +998,10 @@
   // Add two non-webview listeners.
   ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
       &profile_, ext_id, ext_id, events::FOR_TEST, kEventName, kSubEventName,
-      filter, 0, 1 /* embedder_process_id */, 0,
-      ipc_sender_factory.GetWeakPtr());
+      filter, 0, 1 /* render_process_id */, 0, ipc_sender_factory.GetWeakPtr());
   ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
       &profile_, ext_id, ext_id, events::FOR_TEST, kEventName, kSubEventName,
-      filter, 0, 2 /* embedder_process_id */, 0,
-      ipc_sender_factory.GetWeakPtr());
+      filter, 0, 2 /* render_process_id */, 0, ipc_sender_factory.GetWeakPtr());
   EXPECT_EQ(
       2u,
       ExtensionWebRequestEventRouter::GetInstance()->GetListenerCountForTesting(
@@ -1070,7 +1068,7 @@
   response->cancel = true;
   ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
       &profile_, extension_id, kEventName, kEventName + "/1",
-      request->identifier(), 0 /* embedder_process_id */,
+      request->identifier(), 0 /* render_process_id */,
       0 /* web_view_instance_id */, response);
   {
     base::RunLoop run_loop;
diff --git a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
index 5a329246..0445bcf 100644
--- a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
+++ b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
@@ -375,6 +375,7 @@
 
   cros_display_config_->SetDisplayProperties(
       display_id_str, std::move(config_properties),
+      ash::mojom::DisplayConfigSource::kUser,
       base::BindOnce(
           [](ErrorCallback callback, ash::mojom::DisplayConfigResult result) {
             std::move(callback).Run(GetStringResult(result));
diff --git a/chrome/browser/previews/lazyload_browsertest.cc b/chrome/browser/previews/lazyload_browsertest.cc
index 241a431e..d62ec67 100644
--- a/chrome/browser/previews/lazyload_browsertest.cc
+++ b/chrome/browser/previews/lazyload_browsertest.cc
@@ -43,3 +43,20 @@
 
 // TODO(rajendrant): Add a test that checks if the deferred image is loaded when
 // user scrolls near it.
+
+IN_PROC_BROWSER_TEST_F(LazyLoadBrowserTest, CSSPseudoBackgroundImageLoaded) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  base::HistogramTester histogram_tester;
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL(
+                     "/lazyload/css-pseudo-background-image.html"));
+
+  base::RunLoop().RunUntilIdle();
+  // Navigate away to finish the histogram recording.
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+
+  // Verify that the image bucket has substantial kilobytes recorded.
+  EXPECT_GE(30 /* KB */, histogram_tester.GetBucketCount(
+                             "DataUse.ContentType.UserTrafficKB",
+                             data_use_measurement::DataUseUserData::IMAGE));
+}
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 195cf93..07f7eb6 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -1089,7 +1089,7 @@
     // Enterprise users should not be included in any NUX/Navi flow.
     if (!base::IsMachineExternallyManaged()) {
       profile->GetPrefs()->SetString(prefs::kNaviOnboardGroup,
-                                     nux::GetOnboardingGroup(profile));
+                                     nux::GetOnboardingGroup());
     }
 #endif  // defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
   }
diff --git a/chrome/browser/resources/chromeos/camera/BUILD.gn b/chrome/browser/resources/chromeos/camera/BUILD.gn
index 0e89b06..5778978 100644
--- a/chrome/browser/resources/chromeos/camera/BUILD.gn
+++ b/chrome/browser/resources/chromeos/camera/BUILD.gn
@@ -7,9 +7,11 @@
 group("chrome_camera_app") {
   deps = [
     ":chrome_camera_app_base",
-    ":chrome_camera_app_mojo",
     "//chrome/browser/resources/chromeos/camera/src/strings:camera_strings",
   ]
+  data_deps = [
+    ":chrome_camera_app_mojo",
+  ]
 }
 
 copy("chrome_camera_app_base") {
diff --git a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js
index 3badb9b..6417661 100644
--- a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js
+++ b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js
@@ -134,6 +134,12 @@
       Polymer.dom.flush();
       this.$$('#list').notifyResize();
     }
+
+    // Update input enable to reflect new additions/removals.
+    // TODO(hsuregan): Remove hack when notifyPath() or notifySplices()
+    // is successful at creating DOM changes when applied to words_ (when
+    // attached to input newWord), OR when array changes are registered.
+    this.$.addWord.disabled = !this.$.newWord.validate();
   },
 
   /**
diff --git a/chrome/browser/resources/settings/people_page/people_page.html b/chrome/browser/resources/settings/people_page/people_page.html
index 6c5cff34..794f969 100644
--- a/chrome/browser/resources/settings/people_page/people_page.html
+++ b/chrome/browser/resources/settings/people_page/people_page.html
@@ -125,9 +125,6 @@
           font-size: 1.1rem;
           line-height: 1.625rem;
         }
-        --promo-separator: {
-          display: none;
-        }
       }
 </if>
     </style>
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.html b/chrome/browser/resources/settings/people_page/sync_account_control.html
index 4fed8da4..c7227b8 100644
--- a/chrome/browser/resources/settings/people_page/sync_account_control.html
+++ b/chrome/browser/resources/settings/people_page/sync_account_control.html
@@ -139,10 +139,6 @@
       :host([showing-promo]) #promo-description {
         @apply --promo-description;
       }
-
-      :host([showing-promo]) #promo-separator {
-        @apply --promo-separator;
-      }
     </style>
     <div id="banner" hidden="[[syncStatus.signedIn]]"></div>
     <div class$="settings-box first
@@ -155,8 +151,6 @@
         </div>
         <div class="secondary">[[subLabel_]]</div>
       </div>
-      <div id="promo-separator" class="separator"
-          hidden="[[shouldShowAvatarRow_]]"></div>
       <paper-button class="action-button" on-click="onSigninTap_"
           disabled="[[syncStatus.setupInProgress]]" id="sign-in"
           hidden="[[shouldShowAvatarRow_]]">
diff --git a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
index 5d3faa29..9d2056dc 100644
--- a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
@@ -138,6 +138,7 @@
   // Simulate the user opting in to full Sync: Make the account primary, and
   // set first-time setup to complete.
   secondary_account_helper::MakeAccountPrimary(profile(), "user@email.com");
+  GetSyncService(0)->GetUserSettings()->SetSyncRequested(true);
   GetSyncService(0)->GetUserSettings()->SetFirstSetupComplete();
 
   EXPECT_TRUE(GetClient(0)->AwaitSyncSetupCompletion());
diff --git a/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc b/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc
index 191a8c2..9ec8e18 100644
--- a/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc
@@ -49,44 +49,14 @@
   DISALLOW_COPY_AND_ASSIGN(SingleClientStandaloneTransportSyncTest);
 };
 
-#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
-IN_PROC_BROWSER_TEST_F(SingleClientStandaloneTransportSyncTest,
-                       StartsSyncFeatureOnSignin) {
-  // On platforms where Sync starts automatically (in practice, Android and
-  // ChromeOS), IsFirstSetupComplete gets set automatically, and so the full
-  // Sync feature will start upon sign-in to a primary account.
-  ASSERT_TRUE(browser_defaults::kSyncAutoStarts);
-
-  ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
-
-  // Signing in (without explicitly setting up Sync) should trigger starting the
-  // Sync machinery. Because IsFirstSetupComplete gets set automatically, this
-  // will actually start the full Sync feature, not just the transport.
-  ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount());
-  EXPECT_EQ(syncer::SyncService::TransportState::INITIALIZING,
-            GetSyncService(0)->GetTransportState());
-
-  EXPECT_TRUE(GetClient(0)->AwaitSyncTransportActive());
-
-  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
-            GetSyncService(0)->GetTransportState());
-
-  ASSERT_TRUE(GetSyncService(0)->GetUserSettings()->IsFirstSetupComplete());
-
-  EXPECT_TRUE(GetSyncService(0)->IsSyncFeatureEnabled());
-  EXPECT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
-}
-#else
 IN_PROC_BROWSER_TEST_F(SingleClientStandaloneTransportSyncTest,
                        StartsSyncTransportOnSignin) {
-  ASSERT_FALSE(browser_defaults::kSyncAutoStarts);
-
   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
 
   // Signing in (without explicitly setting up Sync) should trigger starting the
   // Sync machinery in standalone transport mode.
   ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount());
-  EXPECT_EQ(syncer::SyncService::TransportState::START_DEFERRED,
+  EXPECT_NE(syncer::SyncService::TransportState::DISABLED,
             GetSyncService(0)->GetTransportState());
 
   EXPECT_TRUE(GetClient(0)->AwaitSyncTransportActive());
@@ -94,7 +64,12 @@
   EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
             GetSyncService(0)->GetTransportState());
 
-  ASSERT_FALSE(GetSyncService(0)->GetUserSettings()->IsFirstSetupComplete());
+  // IsFirstSetupComplete gets set automatically on some platforms, but
+  // IsSyncRequested remains false (it gets set by the Sync confirmation dialog,
+  // or by the settings page if going through the advanced settings flow).
+  ASSERT_EQ(browser_defaults::kSyncAutoStarts,
+            GetSyncService(0)->GetUserSettings()->IsFirstSetupComplete());
+  ASSERT_FALSE(GetSyncService(0)->GetUserSettings()->IsSyncRequested());
 
   EXPECT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled());
   EXPECT_FALSE(GetSyncService(0)->IsSyncFeatureActive());
@@ -107,7 +82,6 @@
                          AllowedTypesInStandaloneTransportMode());
   EXPECT_TRUE(bad_types.Empty()) << syncer::ModelTypeSetToString(bad_types);
 }
-#endif  // defined(OS_CHROMEOS) || defined(OS_ANDROID)
 
 IN_PROC_BROWSER_TEST_F(SingleClientStandaloneTransportSyncTest,
                        SwitchesBetweenTransportAndFeature) {
diff --git a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
index 7d977c5..014ba7b8 100644
--- a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
@@ -1370,6 +1370,7 @@
   // Simulate the user opting in to full Sync: Make the account primary, and
   // set first-time setup to complete.
   secondary_account_helper::MakeAccountPrimary(profile(), "user@email.com");
+  GetSyncService(0)->GetUserSettings()->SetSyncRequested(true);
   GetSyncService(0)->GetUserSettings()->SetFirstSetupComplete();
 
   // Wait for Sync to get reconfigured into feature mode.
@@ -1431,6 +1432,7 @@
   secondary_account_helper::MakeAccountPrimary(profile(), "user@email.com");
 
   // Now start actually configuring Sync.
+  GetSyncService(0)->GetUserSettings()->SetSyncRequested(true);
   auto setup_handle = GetSyncService(0)->GetSetupInProgressHandle();
 
   // Adding a primary account triggers a restart of the Sync engine, so it
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 465e60f..015a529 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1062,8 +1062,6 @@
       "thumbnails/thumbnail_tab_helper.h",
       "thumbnails/thumbnail_utils.cc",
       "thumbnails/thumbnail_utils.h",
-      "thumbnails/thumbnailing_context.cc",
-      "thumbnails/thumbnailing_context.h",
       "toolbar/app_menu_icon_controller.cc",
       "toolbar/app_menu_icon_controller.h",
       "toolbar/app_menu_model.cc",
@@ -3313,10 +3311,6 @@
         "app_list/page_break_app_item.h",
         "app_list/page_break_constants.cc",
         "app_list/page_break_constants.h",
-        "app_list/plugin_vm/plugin_vm_app_item.cc",
-        "app_list/plugin_vm/plugin_vm_app_item.h",
-        "app_list/plugin_vm/plugin_vm_app_model_builder.cc",
-        "app_list/plugin_vm/plugin_vm_app_model_builder.h",
         "app_list/search/app_service_app_result.cc",
         "app_list/search/app_service_app_result.h",
         "app_list/search/arc_app_result.cc",
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc
index a35bb8f5..5547057 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/crostini/crostini_util.h"
 #include "chrome/browser/chromeos/file_manager/app_id.h"
-#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/app_list_client_impl.h"
@@ -36,7 +35,6 @@
 #include "chrome/browser/ui/app_list/internal_app/internal_app_model_builder.h"
 #include "chrome/browser/ui/app_list/page_break_app_item.h"
 #include "chrome/browser/ui/app_list/page_break_constants.h"
-#include "chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -376,10 +374,6 @@
       crostini_apps_builder_ =
           std::make_unique<CrostiniAppModelBuilder>(controller);
     }
-    if (plugin_vm::IsPluginVmAllowedForProfile(profile_)) {
-      plugin_vm_apps_builder_ =
-          std::make_unique<PluginVmAppModelBuilder>(controller);
-    }
     internal_apps_builder_ =
         std::make_unique<InternalAppModelBuilder>(controller);
   }
@@ -395,8 +389,6 @@
       arc_apps_builder_->Initialize(this, profile_, model_updater_.get());
     if (crostini_apps_builder_.get())
       crostini_apps_builder_->Initialize(this, profile_, model_updater_.get());
-    if (plugin_vm_apps_builder_.get())
-      plugin_vm_apps_builder_->Initialize(this, profile_, model_updater_.get());
     internal_apps_builder_->Initialize(this, profile_, model_updater_.get());
   }
 
@@ -967,7 +959,6 @@
   crostini_apps_builder_.reset();
   arc_apps_builder_.reset();
   ext_apps_builder_.reset();
-  plugin_vm_apps_builder_.reset();
 }
 
 // AppListSyncableService private
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.h b/chrome/browser/ui/app_list/app_list_syncable_service.h
index 90dd7fb..1773294 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service.h
+++ b/chrome/browser/ui/app_list/app_list_syncable_service.h
@@ -33,7 +33,6 @@
 class CrostiniAppModelBuilder;
 class ExtensionAppModelBuilder;
 class InternalAppModelBuilder;
-class PluginVmAppModelBuilder;
 class Profile;
 
 namespace extensions {
@@ -311,7 +310,6 @@
   std::unique_ptr<ArcAppModelBuilder> arc_apps_builder_;
   std::unique_ptr<CrostiniAppModelBuilder> crostini_apps_builder_;
   std::unique_ptr<InternalAppModelBuilder> internal_apps_builder_;
-  std::unique_ptr<PluginVmAppModelBuilder> plugin_vm_apps_builder_;
   std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_;
   std::unique_ptr<syncer::SyncErrorFactory> sync_error_handler_;
   SyncItemMap sync_items_;
diff --git a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc
index 07e7ef3..1b39a438 100644
--- a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc
+++ b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc
@@ -17,6 +17,7 @@
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/session_sync_service_factory.h"
@@ -117,6 +118,16 @@
          /*show_in_launcher=*/true, InternalAppName::kDiscover,
          /*searchable_string_resource_id=*/IDS_INTERNAL_APP_DISCOVER});
   }
+
+  if (get_all || plugin_vm::IsPluginVmAllowedForProfile(profile)) {
+    internal_app_list->push_back(
+        {plugin_vm::kPluginVmAppId, IDS_PLUGIN_VM_APP_NAME,
+         IDR_LOGO_PLUGIN_VM_DEFAULT_192,
+         /*recommendable=*/true,
+         /*searchable=*/true,
+         /*show_in_launcher=*/true, InternalAppName::kPluginVm,
+         /*searchable_string_resource_id=*/0});
+  }
   return *internal_app_list;
 }
 
@@ -283,11 +294,15 @@
           base::BindOnce(&OnArcFeaturesRead, profile, event_flags));
     }
   } else if (app_id == kInternalAppIdDiscover) {
-#if defined(OS_CHROMEOS)
     base::RecordAction(base::UserMetricsAction("ShowDiscover"));
     chromeos::DiscoverWindowManager::GetInstance()
         ->ShowChromeDiscoverPageForProfile(profile);
-#endif
+  } else if (app_id == plugin_vm::kPluginVmAppId) {
+    if (plugin_vm::IsPluginVmConfigured(profile)) {
+      // TODO(http://crbug.com/904853): Start PluginVm.
+    } else {
+      plugin_vm::ShowPluginVmLauncherView(profile);
+    }
   }
 }
 
diff --git a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h
index f866356..9096b06 100644
--- a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h
+++ b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h
@@ -27,7 +27,8 @@
   kContinueReading = 2,
   kCamera = 3,
   kDiscover = 4,
-  kMaxValue = kDiscover,
+  kPluginVm = 5,
+  kMaxValue = kPluginVm,
 };
 
 // Metadata about an internal app.
diff --git a/chrome/browser/ui/app_list/plugin_vm/OWNERS b/chrome/browser/ui/app_list/plugin_vm/OWNERS
deleted file mode 100644
index dcb220c..0000000
--- a/chrome/browser/ui/app_list/plugin_vm/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-aoldemeier@chromium.org
-benwells@chromium.org
-nverne@chromium.org
-okalitova@chromium.org
-timloh@chromium.org
diff --git a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_item.cc b/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_item.cc
deleted file mode 100644
index 0260695d..0000000
--- a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_item.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_item.h"
-
-#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
-#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
-#include "ui/gfx/image/image_skia.h"
-
-// static
-const char PluginVmAppItem::kItemType[] = "PluginVmAppItem";
-
-PluginVmAppItem::PluginVmAppItem(
-    Profile* profile,
-    AppListModelUpdater* model_updater,
-    const app_list::AppListSyncableService::SyncItem* sync_item,
-    const std::string& id,
-    const std::string& name,
-    const gfx::ImageSkia* image_skia)
-    : ChromeAppListItem(profile, id) {
-  SetIcon(*image_skia);
-  SetName(name);
-  if (sync_item && sync_item->item_ordinal.IsValid()) {
-    UpdateFromSync(sync_item);
-  } else {
-    SetDefaultPositionIfApplicable(model_updater);
-  }
-}
-
-PluginVmAppItem::~PluginVmAppItem() {}
-
-const char* PluginVmAppItem::GetItemType() const {
-  return PluginVmAppItem::kItemType;
-}
-
-void PluginVmAppItem::Activate(int event_flags) {
-  if (plugin_vm::IsPluginVmConfigured(profile())) {
-    // TODO(http://crbug.com/904853): Start PluginVm.
-    // Manually close app_list view because focus is not changed on PluginVm app
-    // start, and current view remains active.
-    GetController()->DismissView();
-  } else {
-    plugin_vm::ShowPluginVmLauncherView(profile());
-  }
-}
diff --git a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_item.h b/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_item.h
deleted file mode 100644
index d5c1a35..0000000
--- a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_item.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_APP_LIST_PLUGIN_VM_PLUGIN_VM_APP_ITEM_H_
-#define CHROME_BROWSER_UI_APP_LIST_PLUGIN_VM_PLUGIN_VM_APP_ITEM_H_
-
-#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
-
-namespace gfx {
-class ImageSkia;
-}
-
-class PluginVmAppItem : public ChromeAppListItem {
- public:
-  static const char kItemType[];
-  PluginVmAppItem(Profile* profile,
-                  AppListModelUpdater* model_updater,
-                  const app_list::AppListSyncableService::SyncItem* sync_item,
-                  const std::string& id,
-                  const std::string& name,
-                  const gfx::ImageSkia* image_skia);
-  ~PluginVmAppItem() override;
-
- private:
-  // ChromeAppListItem:
-  void Activate(int event_flags) override;
-  const char* GetItemType() const override;
-
-  DISALLOW_COPY_AND_ASSIGN(PluginVmAppItem);
-};
-
-#endif  // CHROME_BROWSER_UI_APP_LIST_PLUGIN_VM_PLUGIN_VM_APP_ITEM_H_
diff --git a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.cc b/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.cc
deleted file mode 100644
index 5475b0b..0000000
--- a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.h"
-
-#include "base/no_destructor.h"
-#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
-#include "chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_item.h"
-#include "chrome/grit/chrome_unscaled_resources.h"
-#include "components/crx_file/id_util.h"
-#include "ui/base/resource/resource_bundle.h"
-
-namespace {
-const char kPluginVmTerminalAppName[] = "PluginVm";
-}  // namespace
-
-PluginVmAppModelBuilder::PluginVmAppModelBuilder(
-    AppListControllerDelegate* controller)
-    : AppListModelBuilder(controller, PluginVmAppItem::kItemType) {}
-
-PluginVmAppModelBuilder::~PluginVmAppModelBuilder() = default;
-
-void PluginVmAppModelBuilder::BuildModel() {
-  static const base::NoDestructor<std::string> kPluginVmTerminalId(
-      crx_file::id_util::GenerateId(kPluginVmTerminalAppName));
-  InsertApp(std::make_unique<PluginVmAppItem>(
-      profile(), model_updater(), GetSyncItem(*kPluginVmTerminalId),
-      *kPluginVmTerminalId, kPluginVmTerminalAppName,
-      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-          IDR_LOGO_PLUGIN_VM_DEFAULT_192)));
-}
diff --git a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.h b/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.h
deleted file mode 100644
index 9b246094..0000000
--- a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_APP_LIST_PLUGIN_VM_PLUGIN_VM_APP_MODEL_BUILDER_H_
-#define CHROME_BROWSER_UI_APP_LIST_PLUGIN_VM_PLUGIN_VM_APP_MODEL_BUILDER_H_
-
-#include "base/macros.h"
-#include "chrome/browser/ui/app_list/app_list_model_builder.h"
-
-class AppListControllerDelegate;
-
-// This class populates and maintains PluginVm apps.
-class PluginVmAppModelBuilder : public AppListModelBuilder {
- public:
-  explicit PluginVmAppModelBuilder(AppListControllerDelegate* controller);
-  ~PluginVmAppModelBuilder() override;
-
- private:
-  // AppListModelBuilder:
-  void BuildModel() override;
-
-  DISALLOW_COPY_AND_ASSIGN(PluginVmAppModelBuilder);
-};
-
-#endif  // CHROME_BROWSER_UI_APP_LIST_PLUGIN_VM_PLUGIN_VM_APP_MODEL_BUILDER_H_
diff --git a/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc b/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc
index 24dacb2..0d79bbe 100644
--- a/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc
+++ b/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc
@@ -9,11 +9,13 @@
 #include "ash/shell.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
 #include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h"
 #include "chrome/browser/ui/ash/launcher/app_window_base.h"
 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client.h"
+#include "components/exo/shell_surface_util.h"
 #include "components/user_manager/user_manager.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/env.h"
@@ -98,7 +100,19 @@
 
   ash::ShelfID shelf_id =
       ash::ShelfID::Deserialize(window->GetProperty(ash::kShelfIDKey));
-  if (shelf_id.IsNull() || !app_list::IsInternalApp(shelf_id.app_id))
+
+  if (shelf_id.IsNull()) {
+    const std::string* window_app_id = exo::GetShellApplicationId(window);
+    if (!window_app_id ||
+        !plugin_vm::IsPluginVmExoApplicationId(*window_app_id)) {
+      return;
+    }
+    shelf_id = ash::ShelfID(plugin_vm::kPluginVmAppId);
+    window->SetProperty(ash::kShelfIDKey,
+                        new std::string(shelf_id.Serialize()));
+  }
+
+  if (!app_list::IsInternalApp(shelf_id.app_id))
     return;
 
   RegisterAppWindow(window, shelf_id);
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index d814fed..1d6f94bfa 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -73,6 +73,7 @@
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "chrome/browser/ui/tab_dialogs.h"
 #include "chrome/browser/ui/tab_ui_helper.h"
+#include "chrome/browser/ui/thumbnails/thumbnail_tab_helper.h"
 #include "chrome/browser/ui/web_applications/web_app_metrics.h"
 #include "chrome/browser/vr/vr_tab_helper.h"
 #include "chrome/common/buildflags.h"
@@ -105,6 +106,7 @@
 #include "chrome/browser/ui/android/view_android_helper.h"
 #else
 #include "chrome/browser/banners/app_banner_manager_desktop.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/plugins/plugin_observer.h"
 #include "chrome/browser/safe_browsing/safe_browsing_tab_observer.h"
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
@@ -300,6 +302,8 @@
   safe_browsing::SafeBrowsingTabObserver::CreateForWebContents(web_contents);
   SearchTabHelper::CreateForWebContents(web_contents);
   TabDialogs::CreateForWebContents(web_contents);
+  if (base::FeatureList::IsEnabled(features::kTabHoverCardImages))
+    ThumbnailTabHelper::CreateForWebContents(web_contents);
   web_modal::WebContentsModalDialogManager::CreateForWebContents(web_contents);
 
   if (banners::AppBannerManagerDesktop::IsEnabled())
diff --git a/chrome/browser/ui/thumbnails/thumbnail_image.cc b/chrome/browser/ui/thumbnails/thumbnail_image.cc
index 95a68ab..d139e210 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_image.cc
+++ b/chrome/browser/ui/thumbnails/thumbnail_image.cc
@@ -9,6 +9,44 @@
 #include "base/task/post_task.h"
 #include "base/task/task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "ui/gfx/codec/jpeg_codec.h"
+
+// Refcounted class that stores compressed JPEG data.
+class ThumbnailImage::ThumbnailData
+    : public base::RefCountedThreadSafe<ThumbnailData> {
+ public:
+  static gfx::ImageSkia ToImageSkia(
+      scoped_refptr<ThumbnailData> representation) {
+    const auto& data = representation->data_;
+    gfx::ImageSkia result = gfx::ImageSkia::CreateFrom1xBitmap(
+        *gfx::JPEGCodec::Decode(data.data(), data.size()));
+    result.MakeThreadSafe();
+    return result;
+  }
+
+  static scoped_refptr<ThumbnailData> FromSkBitmap(SkBitmap bitmap) {
+    constexpr int kCompressionQuality = 97;
+    std::vector<uint8_t> data;
+    const bool result =
+        gfx::JPEGCodec::Encode(bitmap, kCompressionQuality, &data);
+    DCHECK(result);
+    return scoped_refptr<ThumbnailData>(new ThumbnailData(std::move(data)));
+  }
+
+  size_t size() const { return data_.size(); }
+
+ private:
+  friend base::RefCountedThreadSafe<ThumbnailData>;
+
+  explicit ThumbnailData(std::vector<uint8_t>&& data)
+      : data_(std::move(data)) {}
+
+  ~ThumbnailData() = default;
+
+  std::vector<uint8_t> data_;
+
+  DISALLOW_COPY_AND_ASSIGN(ThumbnailData);
+};
 
 ThumbnailImage::ThumbnailImage() = default;
 ThumbnailImage::~ThumbnailImage() = default;
@@ -19,7 +57,7 @@
 ThumbnailImage& ThumbnailImage::operator=(ThumbnailImage&& other) = default;
 
 gfx::ImageSkia ThumbnailImage::AsImageSkia() const {
-  return ConvertFromRepresentation(image_representation_);
+  return ThumbnailData::ToImageSkia(image_representation_);
 }
 
 bool ThumbnailImage::AsImageSkiaAsync(AsImageSkiaCallback callback) const {
@@ -30,33 +68,28 @@
       FROM_HERE,
       {base::TaskPriority::BEST_EFFORT,
        base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-      base::BindOnce(&ThumbnailImage::ConvertFromRepresentation,
-                     image_representation_),
+      base::BindOnce(&ThumbnailData::ToImageSkia, image_representation_),
       std::move(callback));
 
   return true;
 }
 
 bool ThumbnailImage::HasData() const {
-  return !image_representation_.isNull();
+  return static_cast<bool>(image_representation_);
 }
 
 size_t ThumbnailImage::GetStorageSize() const {
-  if (image_representation_.isNull())
-    return 0;
-
-  return image_representation_.bitmap()->computeByteSize();
+  return image_representation_ ? image_representation_->size() : 0;
 }
 
 bool ThumbnailImage::BackedBySameObjectAs(const ThumbnailImage& other) const {
-  return image_representation_.BackedBySameObjectAs(
-      other.image_representation_);
+  return image_representation_.get() == other.image_representation_.get();
 }
 
 // static
 ThumbnailImage ThumbnailImage::FromSkBitmap(SkBitmap bitmap) {
   ThumbnailImage result;
-  result.image_representation_ = ConvertToRepresentation(bitmap);
+  result.image_representation_ = ThumbnailData::FromSkBitmap(bitmap);
   return result;
 }
 
@@ -67,27 +100,13 @@
       FROM_HERE,
       {base::TaskPriority::BEST_EFFORT,
        base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-      base::BindOnce(&ThumbnailImage::ConvertToRepresentation, bitmap),
+      base::BindOnce(&ThumbnailData::FromSkBitmap, bitmap),
       base::BindOnce(
           [](CreateThumbnailCallback callback,
-             ThumbnailRepresentation representation) {
+             scoped_refptr<ThumbnailData> representation) {
             ThumbnailImage result;
             result.image_representation_ = representation;
             std::move(callback).Run(result);
           },
           std::move(callback)));
 }
-
-// static
-gfx::ImageSkia ThumbnailImage::ConvertFromRepresentation(
-    ThumbnailRepresentation representation) {
-  return representation;
-}
-
-// static
-ThumbnailImage::ThumbnailRepresentation ThumbnailImage::ConvertToRepresentation(
-    SkBitmap bitmap) {
-  ThumbnailRepresentation result = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
-  result.MakeThreadSafe();
-  return result;
-}
diff --git a/chrome/browser/ui/thumbnails/thumbnail_image.h b/chrome/browser/ui/thumbnails/thumbnail_image.h
index c86696e8..a959728 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_image.h
+++ b/chrome/browser/ui/thumbnails/thumbnail_image.h
@@ -5,9 +5,10 @@
 #ifndef CHROME_BROWSER_UI_THUMBNAILS_THUMBNAIL_IMAGE_H_
 #define CHROME_BROWSER_UI_THUMBNAILS_THUMBNAIL_IMAGE_H_
 
+#include <vector>
+
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
-
 #include "ui/gfx/image/image_skia.h"
 
 // Value type holding thumbnail image data. Data is internally refcounted, so
@@ -63,15 +64,9 @@
                                 CreateThumbnailCallback callback);
 
  private:
-  // TODO(dfried): In a followup CL, change this to be compressed data.
-  using ThumbnailRepresentation = gfx::ImageSkia;
+  class ThumbnailData;
 
-  static gfx::ImageSkia ConvertFromRepresentation(
-      ThumbnailRepresentation representation);
-
-  static ThumbnailRepresentation ConvertToRepresentation(SkBitmap bitmap);
-
-  ThumbnailRepresentation image_representation_;
+  scoped_refptr<ThumbnailData> image_representation_;
 };
 
 #endif  // CHROME_BROWSER_UI_THUMBNAILS_THUMBNAIL_IMAGE_H_
diff --git a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
index 5c37cbc..ac77bea 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
+++ b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
@@ -10,6 +10,7 @@
 #include "base/task/post_task.h"
 #include "base/task/task_traits.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/tabs/tab_style.h"
 #include "chrome/browser/ui/thumbnails/thumbnail_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -22,56 +23,8 @@
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/scrollbar_size.h"
 
-using thumbnails::ThumbnailingContext;
-
-namespace {
-
-// The desired thumbnail size in DIP. Note that on 1x devices, we actually take
-// thumbnails of twice that size.
-const int kThumbnailWidth = 154;
-const int kThumbnailHeight = 96;
-
-void ComputeThumbnailScore(const SkBitmap& thumbnail,
-                           scoped_refptr<ThumbnailingContext> context) {
-  base::TimeTicks process_bitmap_start_time = base::TimeTicks::Now();
-
-  context->score.boring_score = color_utils::CalculateBoringScore(thumbnail);
-
-  context->score.good_clipping =
-      thumbnails::IsGoodClipping(context->clip_result);
-
-  base::TimeDelta process_bitmap_time =
-      base::TimeTicks::Now() - process_bitmap_start_time;
-  UMA_HISTOGRAM_TIMES("Thumbnails.ProcessBitmapTime", process_bitmap_time);
-}
-
-}  // namespace
-
-// Overview
-// --------
-// DEPRECATED, thumbnails have been removed from the New Tab Page. See
-// https://crbug.com/893362.
-//
-// This class provides a service for updating thumbnails to be used in the
-// "Most visited" section of the New Tab page. The process is started by
-// StartThumbnailCaptureIfNecessary(), which updates the thumbnail for the
-// current tab if needed. The heuristics to judge whether to update the
-// thumbnail are implemented in ThumbnailService::ShouldAcquirePageThumbnail().
-// There are two triggers that can start the process:
-// - When a renderer is about to be hidden (this usually occurs when the current
-//   tab is closed or another tab is clicked).
-// - Just before navigating away from the current page.
-
 ThumbnailTabHelper::ThumbnailTabHelper(content::WebContents* contents)
-    : content::WebContentsObserver(contents),
-      observer_(this),
-      did_navigation_finish_(false),
-      has_received_document_since_navigation_finished_(false),
-      has_painted_since_document_received_(false),
-      page_transition_(ui::PAGE_TRANSITION_LINK),
-      load_interrupted_(false),
-      waiting_for_capture_(false),
-      weak_factory_(this) {}
+    : content::WebContentsObserver(contents) {}
 
 ThumbnailTabHelper::~ThumbnailTabHelper() = default;
 
@@ -214,7 +167,7 @@
   }
 
   // Ignore thumbnail update requests if one is already in progress.
-  if (thumbnailing_context_) {
+  if (thumbnailing_in_progress_) {
     LogThumbnailingOutcome(trigger, Outcome::NOT_ATTEMPTED_IN_PROGRESS);
     return;
   }
@@ -246,34 +199,28 @@
     return;
   }
 
-  // TODO(miu): This is the wrong size. It's the size of the view on-screen, and
-  // not the rendering size of the view. This will be replaced with the view's
-  // actual rendering size in a later change. http://crbug.com/73362
-  gfx::Rect copy_rect = gfx::Rect(view->GetViewBounds().size());
+  // Note: this is the size in pixels on-screen, not the size in DIPs.
+  gfx::Size source_size = view->GetViewBounds().size();
   // Clip the pixels that will commonly hold a scrollbar, which looks bad in
   // thumbnails.
-  int scrollbar_size = gfx::scrollbar_size();
-  copy_rect.Inset(0, 0, scrollbar_size, scrollbar_size);
+  const float scale_factor = view->GetDeviceScaleFactor();
+  const int scrollbar_size = gfx::scrollbar_size() * scale_factor;
+  source_size.Enlarge(-scrollbar_size, -scrollbar_size);
 
-  if (copy_rect.IsEmpty()) {
+  if (source_size.IsEmpty()) {
     LogThumbnailingOutcome(trigger, Outcome::NOT_ATTEMPTED_EMPTY_RECT);
     return;
   }
 
-  bool at_top = view->IsScrollOffsetAtTop();
-  bool load_completed = !web_contents()->IsLoading() && !load_interrupted_;
-  thumbnailing_context_ = new ThumbnailingContext(url, at_top, load_completed);
+  thumbnailing_in_progress_ = true;
 
-  ui::ScaleFactor scale_factor =
-      ui::GetSupportedScaleFactor(view->GetDeviceScaleFactor());
-  thumbnailing_context_->clip_result = thumbnails::GetCanvasCopyInfo(
-      copy_rect.size(), scale_factor,
-      gfx::Size(kThumbnailWidth, kThumbnailHeight), &copy_rect,
-      &thumbnailing_context_->requested_copy_size);
+  const gfx::Size desired_size = TabStyle::GetPreviewImageSize();
+  thumbnails::CanvasCopyInfo copy_info =
+      thumbnails::GetCanvasCopyInfo(source_size, scale_factor, desired_size);
   copy_from_surface_start_time_ = base::TimeTicks::Now();
   waiting_for_capture_ = true;
   view->CopyFromSurface(
-      copy_rect, thumbnailing_context_->requested_copy_size,
+      copy_info.copy_rect, copy_info.target_size,
       base::BindOnce(&ThumbnailTabHelper::ProcessCapturedBitmap,
                      weak_factory_.GetWeakPtr(), trigger));
 }
@@ -294,39 +241,13 @@
     DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
     // From here on, nothing can fail, so log success.
     LogThumbnailingOutcome(trigger, Outcome::SUCCESS);
-    base::PostTaskWithTraitsAndReply(
-        FROM_HERE,
-        {base::TaskPriority::BEST_EFFORT,
-         base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-        base::BindOnce(&ComputeThumbnailScore, bitmap, thumbnailing_context_),
-        base::BindOnce(&ThumbnailTabHelper::StoreThumbnail,
-                       weak_factory_.GetWeakPtr(), bitmap));
+    thumbnail_ = ThumbnailImage::FromSkBitmap(bitmap);
+    web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);
   } else {
     LogThumbnailingOutcome(
         trigger, was_canceled ? Outcome::CANCELED : Outcome::READBACK_FAILED);
-    // On failure because of shutdown we are not on the UI thread, so ensure
-    // that cleanup happens on that thread.
-    // TODO(treib): Figure out whether it actually happen that we get called
-    // back on something other than the UI thread.
-    base::PostTaskWithTraits(
-        FROM_HERE, {content::BrowserThread::UI},
-        base::BindOnce(&ThumbnailTabHelper::CleanUpFromThumbnailGeneration,
-                       weak_factory_.GetWeakPtr()));
   }
-}
-
-void ThumbnailTabHelper::StoreThumbnail(const SkBitmap& thumbnail) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  thumbnail_ = ThumbnailImage::FromSkBitmap(thumbnail);
-  web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);
-
-  CleanUpFromThumbnailGeneration();
-}
-
-void ThumbnailTabHelper::CleanUpFromThumbnailGeneration() {
-  // Make a note that thumbnail generation is complete.
-  thumbnailing_context_ = nullptr;
+  thumbnailing_in_progress_ = false;
 }
 
 void ThumbnailTabHelper::TabHidden() {
diff --git a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.h b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.h
index db709b4..a4fe69ec 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.h
+++ b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.h
@@ -10,7 +10,6 @@
 #include "base/scoped_observer.h"
 #include "base/time/time.h"
 #include "chrome/browser/ui/thumbnails/thumbnail_image.h"
-#include "chrome/browser/ui/thumbnails/thumbnailing_context.h"
 #include "content/public/browser/render_widget_host_observer.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
@@ -88,38 +87,32 @@
   // Creates a thumbnail from the web contents bitmap.
   void ProcessCapturedBitmap(TriggerReason trigger, const SkBitmap& bitmap);
 
-  // Passes the thumbnail to the thumbnail service.
-  void StoreThumbnail(const SkBitmap& thumbnail);
-
-  // Cleans up after thumbnail generation has ended.
-  void CleanUpFromThumbnailGeneration();
-
   // Called when the current tab gets hidden.
   void TabHidden();
 
   static void LogThumbnailingOutcome(TriggerReason trigger, Outcome outcome);
 
-  ScopedObserver<content::RenderWidgetHost, content::RenderWidgetHostObserver>
-      observer_;
+  bool did_navigation_finish_ = false;
+  bool has_received_document_since_navigation_finished_ = false;
+  bool has_painted_since_document_received_ = false;
 
-  bool did_navigation_finish_;
-  bool has_received_document_since_navigation_finished_;
-  bool has_painted_since_document_received_;
+  ui::PageTransition page_transition_ = ui::PAGE_TRANSITION_LINK;
+  bool load_interrupted_ = false;
 
-  ui::PageTransition page_transition_;
-  bool load_interrupted_;
-
-  scoped_refptr<thumbnails::ThumbnailingContext> thumbnailing_context_;
-  bool waiting_for_capture_;
+  bool thumbnailing_in_progress_ = false;
+  bool waiting_for_capture_ = false;
 
   base::TimeTicks copy_from_surface_start_time_;
 
   ThumbnailImage thumbnail_;
 
-  base::WeakPtrFactory<ThumbnailTabHelper> weak_factory_;
+  ScopedObserver<content::RenderWidgetHost, content::RenderWidgetHostObserver>
+      observer_{this};
 
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 
+  base::WeakPtrFactory<ThumbnailTabHelper> weak_factory_{this};
+
   DISALLOW_COPY_AND_ASSIGN(ThumbnailTabHelper);
 };
 
diff --git a/chrome/browser/ui/thumbnails/thumbnail_utils.cc b/chrome/browser/ui/thumbnails/thumbnail_utils.cc
index 2c91f596..2584e21 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_utils.cc
+++ b/chrome/browser/ui/thumbnails/thumbnail_utils.cc
@@ -13,85 +13,62 @@
 namespace thumbnails {
 
 bool IsGoodClipping(ClipResult clip_result) {
-  return clip_result == CLIP_RESULT_WIDER_THAN_TALL ||
-         clip_result == CLIP_RESULT_TALLER_THAN_WIDE ||
-         clip_result == CLIP_RESULT_NOT_CLIPPED;
+  return clip_result == ClipResult::kSourceWiderThanTall ||
+         clip_result == ClipResult::kSourceTallerThanWide ||
+         clip_result == ClipResult::kSourceNotClipped;
 }
 
-ClipResult GetCanvasCopyInfo(const gfx::Size& source_size,
-                             ui::ScaleFactor scale_factor,
-                             const gfx::Size& target_size,
-                             gfx::Rect* clipping_rect,
-                             gfx::Size* copy_size) {
+CanvasCopyInfo GetCanvasCopyInfo(const gfx::Size& source_size,
+                                 float scale_factor,
+                                 const gfx::Size& target_size) {
   DCHECK(!source_size.IsEmpty());
   DCHECK(!target_size.IsEmpty());
-  ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED;
-  *clipping_rect = GetClippingRect(source_size, target_size, &clip_result);
-  *copy_size = GetCopySizeForThumbnail(scale_factor, target_size);
-  return clip_result;
-}
+  DCHECK_GT(scale_factor, 0.0f);
 
-// RenderWidgetHostView::CopyFromSurface() can be costly especially when it is
-// necessary to read back the web contents image data from GPU. As the cost is
-// roughly proportional to the number of the copied pixels, the size of the
-// copied pixels should be as small as possible.
-gfx::Size GetCopySizeForThumbnail(ui::ScaleFactor scale_factor,
-                                  const gfx::Size& thumbnail_size) {
-  // The copy size returned is the pixel equivalent of |thumbnail_size|, which
-  // is in DIPs.
-  if (scale_factor == ui::SCALE_FACTOR_100P) {
-    // In the case of 1x devices, we get a thumbnail twice as big and reduce
-    // it at serve time to improve quality.
-    scale_factor = ui::SCALE_FACTOR_200P;
-  }
-  float scale = GetScaleForScaleFactor(scale_factor);
-  // Limit the scale factor to a maximum of 2x for privacy reasons; see
-  // crbug.com/670488.
-  scale = std::min(2.0f, scale);
-  return gfx::ScaleToFlooredSize(thumbnail_size, scale);
-}
+  CanvasCopyInfo copy_info;
 
-gfx::Rect GetClippingRect(const gfx::Size& source_size,
-                          const gfx::Size& desired_size,
-                          ClipResult* clip_result) {
-  DCHECK(clip_result);
-
-  float desired_aspect =
-      static_cast<float>(desired_size.width()) / desired_size.height();
+  const float desired_aspect =
+      float{target_size.width()} / float{target_size.height()};
 
   // Get the clipping rect so that we can preserve the aspect ratio while
   // filling the destination.
-  gfx::Rect clipping_rect;
-  if (source_size.width() < desired_size.width() ||
-      source_size.height() < desired_size.height()) {
+  if (source_size.width() < target_size.width() ||
+      source_size.height() < target_size.height()) {
     // Source image is smaller: we clip the part of source image within the
     // dest rect, and then stretch it to fill the dest rect. We don't respect
     // the aspect ratio in this case.
-    clipping_rect = gfx::Rect(desired_size);
-    *clip_result = thumbnails::CLIP_RESULT_SOURCE_IS_SMALLER;
+    copy_info.copy_rect = gfx::Rect(target_size);
+    copy_info.clip_result = ClipResult::kSourceSmallerThanTarget;
+
   } else {
-    float src_aspect =
-        static_cast<float>(source_size.width()) / source_size.height();
+    const float src_aspect =
+        float{source_size.width()} / float{source_size.height()};
+
     if (src_aspect > desired_aspect) {
       // Wider than tall, clip horizontally: we center the smaller
       // thumbnail in the wider screen.
-      int new_width = static_cast<int>(source_size.height() * desired_aspect);
-      int x_offset = (source_size.width() - new_width) / 2;
-      clipping_rect.SetRect(x_offset, 0, new_width, source_size.height());
-      *clip_result =
+      const int new_width = source_size.height() * desired_aspect;
+      const int x_offset = (source_size.width() - new_width) / 2;
+      copy_info.clip_result =
           (src_aspect >= history::ThumbnailScore::kTooWideAspectRatio)
-              ? thumbnails::CLIP_RESULT_MUCH_WIDER_THAN_TALL
-              : thumbnails::CLIP_RESULT_WIDER_THAN_TALL;
+              ? ClipResult::kSourceMuchWiderThanTall
+              : ClipResult::kSourceWiderThanTall;
+      copy_info.copy_rect.SetRect(x_offset, 0, new_width, source_size.height());
+
     } else if (src_aspect < desired_aspect) {
-      clipping_rect =
+      copy_info.clip_result = ClipResult::kSourceTallerThanWide;
+      copy_info.copy_rect =
           gfx::Rect(source_size.width(), source_size.width() / desired_aspect);
-      *clip_result = thumbnails::CLIP_RESULT_TALLER_THAN_WIDE;
+
     } else {
-      clipping_rect = gfx::Rect(source_size);
-      *clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED;
+      copy_info.clip_result = ClipResult::kSourceNotClipped;
+      copy_info.copy_rect = gfx::Rect(source_size);
     }
   }
-  return clipping_rect;
+
+  copy_info.target_size = gfx::ScaleToFlooredSize(target_size, scale_factor);
+
+  return copy_info;
 }
 
 }  // namespace thumbnails
diff --git a/chrome/browser/ui/thumbnails/thumbnail_utils.h b/chrome/browser/ui/thumbnails/thumbnail_utils.h
index 6435c32..0434aced 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_utils.h
+++ b/chrome/browser/ui/thumbnails/thumbnail_utils.h
@@ -12,51 +12,42 @@
 
 namespace thumbnails {
 
-// The result of clipping. This can be used to determine if the
-// generated thumbnail is good or not.
-enum ClipResult {
-  // Clipping is not done yet.
-  CLIP_RESULT_UNPROCESSED,
-  // The source image is smaller.
-  CLIP_RESULT_SOURCE_IS_SMALLER,
-  // Wider than tall by twice or more, clip horizontally.
-  CLIP_RESULT_MUCH_WIDER_THAN_TALL,
-  // Wider than tall, clip horizontally.
-  CLIP_RESULT_WIDER_THAN_TALL,
-  // Taller than wide, clip vertically.
-  CLIP_RESULT_TALLER_THAN_WIDE,
-  // The source and destination aspect ratios are identical.
-  CLIP_RESULT_NOT_CLIPPED,
+// The result of clipping. This can be used to determine if the generated
+// thumbnail is good or not.
+enum class ClipResult {
+  kSourceNotClipped,         // Source and target aspect ratios are identical.
+  kSourceSmallerThanTarget,  // Source image is smaller than target.
+  kSourceMuchWiderThanTall,  // Wider than tall by 2x+, clip horizontally.
+  kSourceWiderThanTall,      // Wider than tall, clip horizontally.
+  kSourceTallerThanWide,     // Taller than wide, clip vertically.
+};
+
+// Describes how a thumbnail bitmap should be generated from a target surface.
+struct CanvasCopyInfo {
+  // How the source canvas is clipped to achieve the target size.
+  ClipResult clip_result = ClipResult::kSourceNotClipped;
+
+  // Cropping rectangle for the source canvas, in pixels (not DIPs).
+  gfx::Rect copy_rect;
+
+  // Size of the target bitmap in pixels.
+  gfx::Size target_size;
 };
 
 bool IsGoodClipping(ClipResult clip_result);
 
 // The implementation of the 'classic' thumbnail cropping algorithm. It is not
-// content-driven in any meaningful way (save for score calculation). Rather,
-// the choice of a cropping region is based on relation between source and
-// target sizes. The selected source region is then rescaled into the target
-// thumbnail image.
-
+// content-driven in any meaningful way. Rather, the choice of a cropping region
+// is based on relation between source and target sizes. The selected source
+// region is then rescaled into the target thumbnail image.
+//
 // Provides information necessary to crop-and-resize image data from a source
 // canvas of |source_size|. Auxiliary |scale_factor| helps compute the target
-// thumbnail size to be copied from the backing store, in pixels. Parameters
-// of the required copy operation are assigned to |clipping_rect| (cropping
-// rectangle for the source canvas) and |copy_size| (the size of the copied
-// bitmap in pixels). The return value indicates the type of clipping that
-// will be done.
-ClipResult GetCanvasCopyInfo(const gfx::Size& source_size,
-                             ui::ScaleFactor scale_factor,
-                             const gfx::Size& target_size,
-                             gfx::Rect* clipping_rect,
-                             gfx::Size* copy_size);
-
-// Returns the size copied from the backing store. |thumbnail_size| is in
-// DIP, returned size in pixels.
-gfx::Size GetCopySizeForThumbnail(ui::ScaleFactor scale_factor,
-                                  const gfx::Size& thumbnail_size);
-gfx::Rect GetClippingRect(const gfx::Size& source_size,
-                          const gfx::Size& desired_size,
-                          ClipResult* clip_result);
+// thumbnail size to be copied from the backing store, in pixels. The return
+// value contains the type of clip and the clip parameters.
+CanvasCopyInfo GetCanvasCopyInfo(const gfx::Size& source_size,
+                                 float scale_factor,
+                                 const gfx::Size& target_size);
 
 }  // namespace thumbnails
 
diff --git a/chrome/browser/ui/thumbnails/thumbnail_utils_unittest.cc b/chrome/browser/ui/thumbnails/thumbnail_utils_unittest.cc
index d4536496..693b033 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_utils_unittest.cc
+++ b/chrome/browser/ui/thumbnails/thumbnail_utils_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/thumbnails/thumbnail_utils.h"
 
-#include "chrome/browser/ui/thumbnails/thumbnailing_context.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/test/mock_render_process_host.h"
@@ -20,115 +19,57 @@
 
 typedef testing::Test SimpleThumbnailCropTest;
 
-TEST_F(SimpleThumbnailCropTest, GetCanvasCopyInfo) {
-  gfx::Size thumbnail_size(200, 120);
-  gfx::Size expected_2x_size = gfx::ScaleToFlooredSize(thumbnail_size, 2.0);
-  float desired_aspect =
-      static_cast<float>(thumbnail_size.width()) / thumbnail_size.height();
-  gfx::Rect clipping_rect_result;
-  gfx::Size target_size_result;
+namespace thumbnails {
 
-  thumbnails::ClipResult clip_result = thumbnails::GetCanvasCopyInfo(
-      gfx::Size(400, 210), ui::SCALE_FACTOR_200P, thumbnail_size,
-      &clipping_rect_result, &target_size_result);
-  gfx::Size clipping_size = clipping_rect_result.size();
-  float clip_aspect =
-      static_cast<float>(clipping_size.width()) / clipping_size.height();
-  EXPECT_EQ(thumbnails::CLIP_RESULT_WIDER_THAN_TALL, clip_result);
-  EXPECT_EQ(expected_2x_size, target_size_result);
-  EXPECT_NEAR(desired_aspect, clip_aspect, 0.01);
+// Test which generates thumbnails from various source scales.
+class ThumbnailUtilsTest : public testing::TestWithParam<float> {
+ public:
+  ThumbnailUtilsTest() = default;
 
-  clip_result = thumbnails::GetCanvasCopyInfo(
-      gfx::Size(600, 200), ui::SCALE_FACTOR_200P, thumbnail_size,
-      &clipping_rect_result, &target_size_result);
-  clipping_size = clipping_rect_result.size();
-  clip_aspect =
-      static_cast<float>(clipping_size.width()) / clipping_size.height();
-  EXPECT_EQ(thumbnails::CLIP_RESULT_MUCH_WIDER_THAN_TALL, clip_result);
-  EXPECT_EQ(expected_2x_size, target_size_result);
-  EXPECT_NEAR(desired_aspect, clip_aspect, 0.01);
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ThumbnailUtilsTest);
+};
 
-  clip_result = thumbnails::GetCanvasCopyInfo(
-      gfx::Size(300, 600), ui::SCALE_FACTOR_200P, thumbnail_size,
-      &clipping_rect_result, &target_size_result);
-  clipping_size = clipping_rect_result.size();
-  clip_aspect =
-      static_cast<float>(clipping_size.width()) / clipping_size.height();
-  EXPECT_EQ(thumbnails::CLIP_RESULT_TALLER_THAN_WIDE, clip_result);
-  EXPECT_EQ(expected_2x_size, target_size_result);
-  EXPECT_NEAR(desired_aspect, clip_aspect, 0.01);
-
-  clip_result = thumbnails::GetCanvasCopyInfo(
-      gfx::Size(200, 100), ui::SCALE_FACTOR_200P, thumbnail_size,
-      &clipping_rect_result, &target_size_result);
-  EXPECT_EQ(thumbnails::CLIP_RESULT_SOURCE_IS_SMALLER, clip_result);
-  EXPECT_EQ(expected_2x_size, target_size_result);
+static float GetAspect(const gfx::Size& size) {
+  return float{size.width()} / float{size.height()};
 }
 
-TEST_F(SimpleThumbnailCropTest, GetCanvasCopyInfoDifferentScales) {
-  gfx::Size thumbnail_size(200, 120);
+INSTANTIATE_TEST_SUITE_P(,
+                         ThumbnailUtilsTest,
+                         testing::ValuesIn({1.0f, 1.25f, 1.62f, 2.0f}));
 
-  gfx::Rect clipping_rect_result;
-  gfx::Size target_size_result;
+TEST_P(ThumbnailUtilsTest, GetCanvasCopyInfo) {
+  constexpr gfx::Size kThumbnailSize(200, 120);
+  const float scale_factor = GetParam();
+  const gfx::Size expected_size =
+      gfx::ScaleToFlooredSize(kThumbnailSize, scale_factor);
+  const float desired_aspect = GetAspect(kThumbnailSize);
+  const gfx::Size wider_than_tall_source(400, 210);
+  const gfx::Size much_wider_than_tall_source(600, 200);
+  const gfx::Size taller_than_wide_source(300, 600);
+  const gfx::Size small_source(200, 100);
 
-  gfx::Size expected_2x_size = gfx::ScaleToFlooredSize(thumbnail_size, 2.0);
+  CanvasCopyInfo result =
+      GetCanvasCopyInfo(wider_than_tall_source, scale_factor, kThumbnailSize);
+  EXPECT_EQ(ClipResult::kSourceWiderThanTall, result.clip_result);
+  EXPECT_EQ(expected_size, result.target_size);
+  EXPECT_NEAR(desired_aspect, GetAspect(result.copy_rect.size()), 0.01);
 
-  // Test at 1x scale. Expect a 2x thumbnail (we do this for quality).
-  thumbnails::GetCanvasCopyInfo(gfx::Size(400, 210), ui::SCALE_FACTOR_100P,
-                                thumbnail_size, &clipping_rect_result,
-                                &target_size_result);
-  EXPECT_EQ(expected_2x_size, target_size_result);
+  result = GetCanvasCopyInfo(much_wider_than_tall_source, scale_factor,
+                             kThumbnailSize);
+  EXPECT_EQ(ClipResult::kSourceMuchWiderThanTall, result.clip_result);
+  EXPECT_EQ(expected_size, result.target_size);
+  EXPECT_NEAR(desired_aspect, GetAspect(result.copy_rect.size()), 0.01);
 
-  // Test at 1.5x scale.
-  gfx::Size expected_15x_size = gfx::ScaleToFlooredSize(thumbnail_size, 1.5);
-  thumbnails::GetCanvasCopyInfo(gfx::Size(400, 210), ui::SCALE_FACTOR_150P,
-                                thumbnail_size, &clipping_rect_result,
-                                &target_size_result);
-  EXPECT_EQ(expected_15x_size, target_size_result);
+  result =
+      GetCanvasCopyInfo(taller_than_wide_source, scale_factor, kThumbnailSize);
+  EXPECT_EQ(ClipResult::kSourceTallerThanWide, result.clip_result);
+  EXPECT_EQ(expected_size, result.target_size);
+  EXPECT_NEAR(desired_aspect, GetAspect(result.copy_rect.size()), 0.01);
 
-  // Test at 2x scale.
-  thumbnails::GetCanvasCopyInfo(gfx::Size(400, 210), ui::SCALE_FACTOR_200P,
-                                thumbnail_size, &clipping_rect_result,
-                                &target_size_result);
-  EXPECT_EQ(expected_2x_size, target_size_result);
-
-  // Test at 3x scale. Expect a 2x (!) thumbnail (see crbug.com/670488).
-  thumbnails::GetCanvasCopyInfo(gfx::Size(400, 210), ui::SCALE_FACTOR_300P,
-                                thumbnail_size, &clipping_rect_result,
-                                &target_size_result);
-  EXPECT_EQ(expected_2x_size, target_size_result);
+  result = GetCanvasCopyInfo(small_source, scale_factor, kThumbnailSize);
+  EXPECT_EQ(ClipResult::kSourceSmallerThanTarget, result.clip_result);
+  EXPECT_EQ(expected_size, result.target_size);
 }
 
-TEST_F(SimpleThumbnailCropTest, GetClippingRect) {
-  const gfx::Size desired_size(300, 200);
-  thumbnails::ClipResult clip_result;
-  // Try out 'microsource'.
-  gfx::Rect clip_rect = thumbnails::GetClippingRect(gfx::Size(300, 199),
-                                                    desired_size, &clip_result);
-  EXPECT_EQ(thumbnails::CLIP_RESULT_SOURCE_IS_SMALLER, clip_result);
-  EXPECT_EQ(gfx::Point(0, 0).ToString(), clip_rect.origin().ToString());
-  EXPECT_EQ(desired_size.ToString(), clip_rect.size().ToString());
-
-  // Portrait source.
-  clip_rect = thumbnails::GetClippingRect(gfx::Size(500, 1200), desired_size,
-                                          &clip_result);
-  EXPECT_EQ(thumbnails::CLIP_RESULT_TALLER_THAN_WIDE, clip_result);
-  EXPECT_EQ(gfx::Point(0, 0).ToString(), clip_rect.origin().ToString());
-  EXPECT_EQ(500, clip_rect.width());
-  EXPECT_GE(1200, clip_rect.height());
-
-  clip_rect = thumbnails::GetClippingRect(gfx::Size(2000, 800), desired_size,
-                                          &clip_result);
-  EXPECT_TRUE(clip_result == thumbnails::CLIP_RESULT_WIDER_THAN_TALL ||
-              clip_result == thumbnails::CLIP_RESULT_MUCH_WIDER_THAN_TALL);
-  EXPECT_EQ(0, clip_rect.y());
-  EXPECT_LT(0, clip_rect.x());
-  EXPECT_GE(2000, clip_rect.width());
-  EXPECT_EQ(800, clip_rect.height());
-
-  clip_rect = thumbnails::GetClippingRect(gfx::Size(900, 600), desired_size,
-                                          &clip_result);
-  EXPECT_EQ(thumbnails::CLIP_RESULT_NOT_CLIPPED, clip_result);
-  EXPECT_EQ(gfx::Point(0, 0).ToString(), clip_rect.origin().ToString());
-  EXPECT_EQ(gfx::Size(900, 600).ToString(), clip_rect.size().ToString());
-}
+}  // namespace thumbnails
diff --git a/chrome/browser/ui/thumbnails/thumbnailing_context.cc b/chrome/browser/ui/thumbnails/thumbnailing_context.cc
deleted file mode 100644
index dbb3932..0000000
--- a/chrome/browser/ui/thumbnails/thumbnailing_context.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/thumbnails/thumbnailing_context.h"
-
-namespace thumbnails {
-
-ThumbnailingContext::ThumbnailingContext(const GURL& url,
-                                         bool at_top,
-                                         bool load_completed)
-    : url(url), clip_result(CLIP_RESULT_UNPROCESSED) {
-  score.at_top = at_top;
-  score.load_completed = load_completed;
-}
-
-ThumbnailingContext::~ThumbnailingContext() = default;
-
-}  // namespace thumbnails
diff --git a/chrome/browser/ui/thumbnails/thumbnailing_context.h b/chrome/browser/ui/thumbnails/thumbnailing_context.h
deleted file mode 100644
index 3be4a12..0000000
--- a/chrome/browser/ui/thumbnails/thumbnailing_context.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_THUMBNAILS_THUMBNAILING_CONTEXT_H_
-#define CHROME_BROWSER_UI_THUMBNAILS_THUMBNAILING_CONTEXT_H_
-
-#include "base/memory/ref_counted.h"
-#include "chrome/browser/ui/thumbnails/thumbnail_utils.h"
-#include "components/history/core/common/thumbnail_score.h"
-#include "ui/gfx/geometry/size.h"
-#include "url/gurl.h"
-
-namespace thumbnails {
-
-// Holds the information needed for processing a thumbnail.
-struct ThumbnailingContext : base::RefCountedThreadSafe<ThumbnailingContext> {
-  ThumbnailingContext(const GURL& url, bool at_top, bool load_completed);
-
-  GURL url;
-  ClipResult clip_result;
-  gfx::Size requested_copy_size;
-  history::ThumbnailScore score;
-
- private:
-  ~ThumbnailingContext();
-
-  friend class base::RefCountedThreadSafe<ThumbnailingContext>;
-};
-
-}  // namespace thumbnails
-
-#endif  // CHROME_BROWSER_UI_THUMBNAILS_THUMBNAILING_CONTEXT_H_
diff --git a/chrome/browser/ui/views/extensions/extension_popup.cc b/chrome/browser/ui/views/extensions/extension_popup.cc
index c20b6797..db05a2b 100644
--- a/chrome/browser/ui/views/extensions/extension_popup.cc
+++ b/chrome/browser/ui/views/extensions/extension_popup.cc
@@ -21,17 +21,11 @@
 
 #if defined(USE_AURA)
 #include "chrome/browser/ui/browser_dialogs.h"
+#include "ui/aura/window.h"
 #include "ui/wm/core/window_animations.h"
+#include "ui/wm/public/activation_client.h"
 #endif
 
-// The minimum/maximum dimensions of the popup.
-// The minimum is just a little larger than the size of the button itself.
-// The maximum is an arbitrary number that should be smaller than most screens.
-const int ExtensionPopup::kMinWidth = 25;
-const int ExtensionPopup::kMinHeight = 25;
-const int ExtensionPopup::kMaxWidth = 800;
-const int ExtensionPopup::kMaxHeight = 600;
-
 // static
 void ExtensionPopup::ShowPopup(
     std::unique_ptr<extensions::ExtensionViewHost> host,
@@ -48,6 +42,12 @@
       native_view, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL);
   wm::SetWindowVisibilityAnimationVerticalPosition(native_view, -3.0f);
 
+  // This is removed in ExtensionPopup::OnWidgetDestroying(), which is
+  // guaranteed to be called before the Widget goes away.  It's not safe to use
+  // a ScopedObserver for this, since the activation client may be deleted
+  // without a call back to this class.
+  wm::GetActivationClient(native_view->GetRootWindow())->AddObserver(popup);
+
   chrome::RecordDialogCreation(chrome::DialogIdentifier::EXTENSION_POPUP_AURA);
 #endif
 }
@@ -59,12 +59,14 @@
 gfx::Size ExtensionPopup::CalculatePreferredSize() const {
   // Constrain the size to popup min/max.
   gfx::Size sz = views::View::CalculatePreferredSize();
-  sz.set_width(std::max(kMinWidth, std::min(kMaxWidth, sz.width())));
-  sz.set_height(std::max(kMinHeight, std::min(kMaxHeight, sz.height())));
+  sz.SetToMax(gfx::Size(kMinWidth, kMinHeight));
+  sz.SetToMin(gfx::Size(kMaxWidth, kMaxHeight));
   return sz;
 }
 
 void ExtensionPopup::AddedToWidget() {
+  BubbleDialogDelegateView::AddedToWidget();
+
   const int radius =
       GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius();
   const bool contents_has_rounded_corners =
@@ -79,19 +81,54 @@
 
 void ExtensionPopup::OnWidgetActivationChanged(views::Widget* widget,
                                                bool active) {
-  if (active && observe_next_widget_activation_) {
-    observe_next_widget_activation_ = false;
-    views::Widget* const my_widget = GetWidget();
-    if (widget != my_widget)
-      my_widget->Close();
-  }
   BubbleDialogDelegateView::OnWidgetActivationChanged(widget, active);
+
+  // The widget is shown asynchronously and may take a long time to appear, so
+  // only close if it's actually been shown.
+  if (GetWidget()->IsVisible()) {
+    // Extension popups need to open child windows sometimes (e.g. for JS
+    // alerts), which take activation; so ExtensionPopup can't close on
+    // deactivation.  Instead, close when the parent widget is activated; this
+    // leaves the popup open when e.g. a non-Chrome window is activated, which
+    // doesn't feel very menu-like, but is better than any alternative.  See
+    // https://crbug.com/941994 for more discussion.
+    if (widget == anchor_widget() && active)
+      CloseUnlessUnderInspection();
+  }
 }
 
 bool ExtensionPopup::ShouldHaveRoundCorners() const {
   return false;
 }
 
+#if defined(USE_AURA)
+void ExtensionPopup::OnWidgetDestroying(views::Widget* widget) {
+  BubbleDialogDelegateView::OnWidgetDestroying(widget);
+
+  if (widget == GetWidget()) {
+    auto* activation_client =
+        wm::GetActivationClient(widget->GetNativeWindow()->GetRootWindow());
+    // If the popup was being inspected with devtools and the browser window
+    // was closed, then the root window and activation client are already
+    // destroyed.
+    if (activation_client)
+      activation_client->RemoveObserver(this);
+  }
+}
+
+void ExtensionPopup::OnWindowActivated(
+    wm::ActivationChangeObserver::ActivationReason reason,
+    aura::Window* gained_active,
+    aura::Window* lost_active) {
+  // Close on anchor window activation (i.e. user clicked the browser window).
+  // DesktopNativeWidgetAura does not trigger the expected browser widget
+  // [de]activation events when activating widgets in its own root window.
+  // This additional check handles those cases. See https://crbug.com/320889 .
+  if (gained_active == anchor_widget()->GetNativeWindow())
+    CloseUnlessUnderInspection();
+}
+#endif  // defined(USE_AURA)
+
 void ExtensionPopup::OnExtensionSizeChanged(ExtensionViewViews* view) {
   SizeToContents();
 }
@@ -99,21 +136,18 @@
 void ExtensionPopup::Observe(int type,
                              const content::NotificationSource& source,
                              const content::NotificationDetails& details) {
-  switch (type) {
-    case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME:
-      DCHECK_EQ(host()->host_contents(),
-                content::Source<content::WebContents>(source).ptr());
-      // Show when the content finishes loading and its width is computed.
-      ShowBubble();
-      break;
-    case extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE:
-      // If we aren't the host of the popup, then disregard the notification.
-      if (content::Details<extensions::ExtensionHost>(host()) == details)
-        GetWidget()->Close();
-      break;
-    default:
-      NOTREACHED() << "Received unexpected notification";
+  if (type == content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME) {
+    DCHECK_EQ(host()->host_contents(),
+              content::Source<content::WebContents>(source).ptr());
+    // Show when the content finishes loading and its width is computed.
+    ShowBubble();
+    return;
   }
+
+  DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, type);
+  // If we aren't the host of the popup, then disregard the notification.
+  if (content::Details<extensions::ExtensionHost>(host()) == details)
+    GetWidget()->Close();
 }
 
 void ExtensionPopup::OnTabStripModelChanged(
@@ -127,15 +161,13 @@
 void ExtensionPopup::DevToolsAgentHostAttached(
     content::DevToolsAgentHost* agent_host) {
   if (host()->host_contents() == agent_host->GetWebContents())
-    UpdateShowAction(SHOW_AND_INSPECT);
+    show_action_ = SHOW_AND_INSPECT;
 }
 
 void ExtensionPopup::DevToolsAgentHostDetached(
     content::DevToolsAgentHost* agent_host) {
-  if (host()->host_contents() == agent_host->GetWebContents()) {
-    UpdateShowAction(SHOW);
-    observe_next_widget_activation_ = true;
-  }
+  if (host()->host_contents() == agent_host->GetWebContents())
+    show_action_ = SHOW;
 }
 
 ExtensionPopup::ExtensionPopup(extensions::ExtensionViewHost* host,
@@ -145,12 +177,15 @@
     : BubbleDialogDelegateView(anchor_view,
                                arrow,
                                views::BubbleBorder::SMALL_SHADOW),
-      host_(host) {
+      host_(host),
+      show_action_(show_action) {
   set_margins(gfx::Insets());
   SetLayoutManager(std::make_unique<views::FillLayout>());
   AddChildView(GetExtensionView());
   GetExtensionView()->set_container(this);
-  UpdateShowAction(show_action);
+
+  // See comments in OnWidgetActivationChanged().
+  set_close_on_deactivate(false);
 
   // Listen for the containing view calling window.close();
   registrar_.Add(
@@ -171,11 +206,6 @@
   }
 }
 
-void ExtensionPopup::UpdateShowAction(ShowAction show_action) {
-  show_action_ = show_action;
-  set_close_on_deactivate(show_action == SHOW);
-}
-
 void ExtensionPopup::ShowBubble() {
   GetWidget()->Show();
 
@@ -188,6 +218,11 @@
   }
 }
 
+void ExtensionPopup::CloseUnlessUnderInspection() {
+  if (show_action_ != SHOW_AND_INSPECT)
+    GetWidget()->CloseWithReason(views::Widget::ClosedReason::kLostFocus);
+}
+
 ExtensionViewViews* ExtensionPopup::GetExtensionView() {
   return static_cast<ExtensionViewViews*>(host_.get()->view());
 }
diff --git a/chrome/browser/ui/views/extensions/extension_popup.h b/chrome/browser/ui/views/extensions/extension_popup.h
index c429a32..342f067 100644
--- a/chrome/browser/ui/views/extensions/extension_popup.h
+++ b/chrome/browser/ui/views/extensions/extension_popup.h
@@ -18,6 +18,10 @@
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
 #include "url/gurl.h"
 
+#if defined(USE_AURA)
+#include "ui/wm/public/activation_change_observer.h"
+#endif
+
 class ExtensionViewViews;
 
 namespace content {
@@ -30,6 +34,9 @@
 
 // The bubble used for hosting a browser-action popup provided by an extension.
 class ExtensionPopup : public views::BubbleDialogDelegateView,
+#if defined(USE_AURA)
+                       public wm::ActivationChangeObserver,
+#endif
                        public ExtensionViewViews::Container,
                        public content::NotificationObserver,
                        public TabStripModelObserver,
@@ -41,10 +48,12 @@
   };
 
   // The min/max height of popups.
-  static const int kMinWidth;
-  static const int kMinHeight;
-  static const int kMaxWidth;
-  static const int kMaxHeight;
+  // The minimum is just a little larger than the size of the button itself.
+  // The maximum is an arbitrary number and should be smaller than most screens.
+  static constexpr int kMinWidth = 25;
+  static constexpr int kMinHeight = 25;
+  static constexpr int kMaxWidth = 800;
+  static constexpr int kMaxHeight = 600;
 
   // Creates and shows a popup with the given |host| positioned adjacent to
   // |anchor_view|.
@@ -63,28 +72,36 @@
 
   extensions::ExtensionViewHost* host() const { return host_.get(); }
 
-  // views::BubbleDialogDelegateView overrides.
+  // views::BubbleDialogDelegateView:
   gfx::Size CalculatePreferredSize() const override;
   void AddedToWidget() override;
   int GetDialogButtons() const override;
   void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
   bool ShouldHaveRoundCorners() const override;
+#if defined(USE_AURA)
+  void OnWidgetDestroying(views::Widget* widget) override;
 
-  // ExtensionViewViews::Container overrides.
+  // wm::ActivationChangeObserver:
+  void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason,
+                         aura::Window* gained_active,
+                         aura::Window* lost_active) override;
+#endif
+
+  // ExtensionViewViews::Container:
   void OnExtensionSizeChanged(ExtensionViewViews* view) override;
 
-  // content::NotificationObserver overrides.
+  // content::NotificationObserver:
   void Observe(int type,
                const content::NotificationSource& source,
                const content::NotificationDetails& details) override;
 
-  // TabStripModelObserver overrides.
+  // TabStripModelObserver:
   void OnTabStripModelChanged(
       TabStripModel* tab_strip_model,
       const TabStripModelChange& change,
       const TabStripSelectionChange& selection) override;
 
-  // content::DevToolsAgentHostObserver overrides.
+  // content::DevToolsAgentHostObserver:
   void DevToolsAgentHostAttached(
       content::DevToolsAgentHost* agent_host) override;
   void DevToolsAgentHostDetached(
@@ -96,11 +113,12 @@
                  views::BubbleBorder::Arrow arrow,
                  ShowAction show_action);
 
-  // Changes internal state to follow the supplied |show_action|.
-  void UpdateShowAction(ShowAction show_action);
   // Shows the bubble, focuses its content, and registers listeners.
   void ShowBubble();
 
+  // Closes the bubble if the devtools window is not attached.
+  void CloseUnlessUnderInspection();
+
   ExtensionViewViews* GetExtensionView();
 
   // The contained host for the view.
@@ -108,12 +126,6 @@
 
   ShowAction show_action_;
 
-  // When dev tools closes, we should close the popup iff activation isn't going
-  // back to it.  There's no way to know which widget will be activated when dev
-  // tools closes, so this flag is set instead, which causes
-  // OnWidgetActivationChanged() to optionally close the current widget.
-  bool observe_next_widget_activation_ = false;
-
   content::NotificationRegistrar registrar_;
   ScopedObserver<TabStripModel, TabStripModelObserver> observer_{this};
 
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
index 05d1cf39..e96ccd6 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
@@ -809,6 +809,7 @@
       config_properties->rotation = ash::mojom::DisplayRotation::New(rotation);
       ash::mojom::DisplayConfigResult result;
       waiter_for.SetDisplayProperties(display_id, std::move(config_properties),
+                                      ash::mojom::DisplayConfigSource::kUser,
                                       &result);
       EXPECT_EQ(result, ash::mojom::DisplayConfigResult::kSuccess);
 
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc
index def6426..a0e563f 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc
@@ -99,7 +99,8 @@
       config_properties->set_primary = true;
       cros_display_config_ptr_->SetDisplayProperties(
           base::NumberToString(device.target_display_id),
-          std::move(config_properties), base::DoNothing());
+          std::move(config_properties), ash::mojom::DisplayConfigSource::kUser,
+          base::DoNothing());
       break;
     }
   }
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 083f591..3a5adc9c 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
@@ -48,6 +48,7 @@
       GetDisplayUnitInfoListCallback callback) override {}
   void SetDisplayProperties(const std::string& id,
                             ash::mojom::DisplayConfigPropertiesPtr properties,
+                            ash::mojom::DisplayConfigSource source,
                             SetDisplayPropertiesCallback callback) override {
     if (properties->set_primary) {
       int64_t display_id;
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index e842987..1a0d132 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -621,7 +621,8 @@
       sync_blocker_ = service->GetSetupInProgressHandle();
 
     // Mark Sync as requested by the user. It might already be requested, but
-    // it's not e.g. if Sync was reset via the dashboard. This also pokes the
+    // it's not if this is either the first time the user is setting up Sync, or
+    // Sync was set up but then was reset via the dashboard. This also pokes the
     // SyncService to start up immediately, i.e. bypass deferred startup.
     if (service)
       service->GetUserSettings()->SetSyncRequested(true);
@@ -669,7 +670,8 @@
       !service->GetUserSettings()->IsSyncRequested()) {
     // SetSyncRequested(true) does two things:
     // 1) As the name says, it marks Sync as requested by the user (it might not
-    //    be requested yet if Sync was reset via the dashboard).
+    //    be requested yet because either this is the first time they're setting
+    //    it up, or Sync was reset via the dashboard).
     // 2) Pokes the sync service to start *immediately*, i.e. bypass deferred
     //    startup.
     // It's possible that both of these are already the case, i.e. the engine is
diff --git a/chrome/browser/ui/webui/sync_internals_browsertest.js b/chrome/browser/ui/webui/sync_internals_browsertest.js
index 11b09ea..d9be575 100644
--- a/chrome/browser/ui/webui/sync_internals_browsertest.js
+++ b/chrome/browser/ui/webui/sync_internals_browsertest.js
@@ -248,7 +248,8 @@
 // life), so it doesn't make it to sync-internals.
 TEST_F('SyncInternalsWebUITest', 'SignedOut', function() {
   expectTrue(this.hasInDetails(true, 'Transport State', 'Disabled'));
-  expectTrue(this.hasInDetails(true, 'Disable Reasons', 'Not signed in'));
+  expectTrue(
+      this.hasInDetails(true, 'Disable Reasons', 'Not signed in, User choice'));
   expectTrue(this.hasInDetails(true, 'Username', ''));
 });
 
diff --git a/chrome/browser/ui/webui/welcome/nux/constants.cc b/chrome/browser/ui/webui/welcome/nux/constants.cc
index fec9cc9..5ed970a 100644
--- a/chrome/browser/ui/webui/welcome/nux/constants.cc
+++ b/chrome/browser/ui/webui/welcome/nux/constants.cc
@@ -9,21 +9,15 @@
 namespace nux {
 
 const base::Feature kNuxOnboardingFeature{"NuxOnboarding",
-                                          base::FEATURE_ENABLED_BY_DEFAULT};
-
-// nux-ntp-background should not be added here until we can guarantee that
-// kUseGoogleLocalNtp is enabled
-const char kDefaultNewUserModules[] =
-    "nux-google-apps,nux-email,nux-set-as-default,signin-view";
-const char kDefaultReturningUserModules[] = "nux-set-as-default";
+                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
 // The value of these FeatureParam values should be a comma-delimited list
 // of element names whitelisted in the MODULES_WHITELIST list, defined in
 // chrome/browser/resources/welcome/onboarding_welcome/welcome_app.js
 const base::FeatureParam<std::string> kNuxOnboardingNewUserModules{
-    &kNuxOnboardingFeature, "new-user-modules", kDefaultNewUserModules};
+    &kNuxOnboardingFeature, "new-user-modules",
+    "nux-google-apps,nux-email,nux-set-as-default,signin-view"};
 const base::FeatureParam<std::string> kNuxOnboardingReturningUserModules{
-    &kNuxOnboardingFeature, "returning-user-modules",
-    kDefaultReturningUserModules};
+    &kNuxOnboardingFeature, "returning-user-modules", "nux-set-as-default"};
 
 }  // namespace nux
diff --git a/chrome/browser/ui/webui/welcome/nux/constants.h b/chrome/browser/ui/webui/welcome/nux/constants.h
index e79cd970..0ea4f52d 100644
--- a/chrome/browser/ui/webui/welcome/nux/constants.h
+++ b/chrome/browser/ui/webui/welcome/nux/constants.h
@@ -16,9 +16,6 @@
 
 extern const base::Feature kNuxOnboardingFeature;
 
-extern const char kDefaultNewUserModules[];
-extern const char kDefaultReturningUserModules[];
-
 extern const base::FeatureParam<std::string> kNuxOnboardingNewUserModules;
 extern const base::FeatureParam<std::string> kNuxOnboardingReturningUserModules;
 extern const base::FeatureParam<bool> kNuxOnboardingShowEmailInterstitial;
diff --git a/chrome/browser/ui/webui/welcome/nux_helper.cc b/chrome/browser/ui/webui/welcome/nux_helper.cc
index 980426a..603f113 100644
--- a/chrome/browser/ui/webui/welcome/nux_helper.cc
+++ b/chrome/browser/ui/webui/welcome/nux_helper.cc
@@ -13,10 +13,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search/ntp_features.h"
-#include "chrome/browser/search/search.h"
 #include "chrome/browser/ui/webui/welcome/nux/constants.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 
@@ -42,28 +39,10 @@
         &kNuxOnboardingForceEnabled, "returning-user-modules",
         "nux-set-as-default"};
 
-// Our current running experiment of testing the nux-ntp-background module
-// depends on the Local NTP feature/experiment being enabled. To avoid polluting
-// our data with users who cannot use the nux-ntp-background module, we need
-// to check to make sure the Local NTP feature is enabled before running
-// any experiment or even reading any feature params from our experiment.
-bool CanExperimentWithVariations(Profile* profile) {
-  return (base::CommandLine::ForCurrentProcess()->HasSwitch(
-              switches::kForceLocalNtp) ||
-          base::FeatureList::IsEnabled(features::kUseGoogleLocalNtp)) &&
-         search::DefaultSearchProviderIsGoogle(profile);
-}
-
 // Must match study name in configs.
 const char kNuxOnboardingStudyName[] = "NaviOnboarding";
 
-std::string GetOnboardingGroup(Profile* profile) {
-  if (!CanExperimentWithVariations(profile)) {
-    // If we cannot run any variations, we bucket the users into a separate
-    // synthetic group that we will ignore data for.
-    return "NaviNoVariationSynthetic";
-  }
-
+std::string GetOnboardingGroup() {
   // We need to use |base::GetFieldTrialParamValue| instead of
   // |base::FeatureParam| because our control group needs a custom value for
   // this param.
@@ -94,14 +73,9 @@
   std::string onboard_group = prefs->GetString(prefs::kNaviOnboardGroup);
 
   if (onboard_group.empty()) {
-    // Users who onboarded before Navi or are part of an enterprise.
     return false;
   }
 
-  if (!CanExperimentWithVariations(profile)) {
-    return true;  // Default Navi behavior.
-  }
-
   // User will be tied to their original onboarding group, even after
   // experiment ends.
   ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(
@@ -128,14 +102,10 @@
                       kNuxOnboardingForceEnabledNewUserModules.Get());
     modules.SetString("returning-user",
                       kNuxOnboardingForceEnabledReturningUserModules.Get());
-  } else if (CanExperimentWithVariations(profile)) {
+  } else {  // This means |nux::kNuxOnboardingFeature| is enabled.
     modules.SetString("new-user", kNuxOnboardingNewUserModules.Get());
     modules.SetString("returning-user",
                       kNuxOnboardingReturningUserModules.Get());
-  } else {
-    // Default behavior w/o checking feature flag.
-    modules.SetString("new-user", kDefaultNewUserModules);
-    modules.SetString("returning-user", kDefaultReturningUserModules);
   }
 
   return modules;
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json
index 4e065b1..d321c7e2 100644
--- a/chrome/common/extensions/api/_api_features.json
+++ b/chrome/common/extensions/api/_api_features.json
@@ -629,10 +629,6 @@
     "internal": true,
     "contexts": ["blessed_extension"]
   }],
-  "preferencesPrivate": {
-    "dependencies": ["permission:preferencesPrivate"],
-    "contexts": ["blessed_extension"]
-  },
   "privacy": {
     "dependencies": ["permission:privacy"],
     "contexts": ["blessed_extension"]
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 3452d45..dbcbead 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -581,26 +581,6 @@
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app"]
   },
-  "preferencesPrivate": [
-    {
-      "channel": "stable",
-      "extension_types": [
-        "extension"
-      ],
-      "whitelist": [
-        "C41AD9DCD670210295614257EF8C9945AD68D86E",  // Google Now
-        "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2",  // http://crbug.com/312900
-        "D57DE394F36DC1C3220E7604C575D29C51A6C495",  // http://crbug.com/319444
-        "3F65507A3B39259B38C8173C6FFA3D12DF64CCE9",  // http://crbug.com/371562
-        "852290F2442EEE45EF673B8DA6090112079012A2"   // http://crbug.com/375484
-      ]
-    },
-    {
-      "channel": "stable",
-      "extension_types": ["platform_app"],
-      "location": "component"
-    }
-  ],
   "privacy": {
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app"]
diff --git a/chrome/common/extensions/api/api_sources.gni b/chrome/common/extensions/api/api_sources.gni
index 0eecbabb8..c4228d01 100644
--- a/chrome/common/extensions/api/api_sources.gni
+++ b/chrome/common/extensions/api/api_sources.gni
@@ -52,7 +52,6 @@
   "page_capture.json",
   "passwords_private.idl",
   "permissions.json",
-  "preferences_private.json",
   "resources_private.idl",
   "safe_browsing_private.idl",
   "sessions.json",
diff --git a/chrome/common/extensions/api/file_manager_private.idl b/chrome/common/extensions/api/file_manager_private.idl
index 94888c3..9aa76b3 100644
--- a/chrome/common/extensions/api/file_manager_private.idl
+++ b/chrome/common/extensions/api/file_manager_private.idl
@@ -1100,9 +1100,6 @@
   static void computeChecksum([instanceof=Entry] object entry,
                               ComputeChecksumCallback callback);
 
-  // Is UMA enabled?
-  static void isUMAEnabled(BooleanCallback callback);
-
   // Sets a tag on a file or a directory. Only Drive files are supported.
   [nocompile]
   static void setEntryTag([instanceof=Entry] object entry,
diff --git a/chrome/common/extensions/api/preferences_private.json b/chrome/common/extensions/api/preferences_private.json
deleted file mode 100644
index 7aff5bd..0000000
--- a/chrome/common/extensions/api/preferences_private.json
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-[
-  {
-    "namespace": "preferencesPrivate",
-    "description": "none",
-    "types": [{
-      "id": "EasyUnlockProximityRequired",
-      "type": "object",
-      "js_module": "EasyUnlockProximityRequired",
-      "events": [{
-        "name": "onChange",
-        "description": "Fired after the setting changes.",
-        "parameters": [{
-          "type": "object",
-          "name": "details",
-          "properties": {
-            "value": {
-              "description": "The value of the setting after the change.",
-              "type": "any"
-            },
-            "incognitoSpecific": {
-              "description": "Whether the value that has changed is specific to the incognito session.<br/>This property will <em>only</em> be present if the user has enabled the extension in incognito mode.",
-              "type": "boolean",
-              "optional": true
-            }
-          }
-        }]
-      }]
-    }],
-    "properties": {
-      "easyUnlockProximityRequired": {
-        "nocompile": true,
-        "$ref": "EasyUnlockProximityRequired",
-        "value": ["easyUnlockProximityRequired"]
-      }
-    }
-  }
-]
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc
index 6629463..ead064f 100644
--- a/chrome/common/extensions/permissions/chrome_api_permissions.cc
+++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -123,8 +123,6 @@
     {APIPermission::kMediaRouterPrivate, "mediaRouterPrivate",
      APIPermissionInfo::kFlagCannotBeOptional},
     {APIPermission::kNetworkingCastPrivate, "networking.castPrivate"},
-    {APIPermission::kPreferencesPrivate, "preferencesPrivate",
-     APIPermissionInfo::kFlagCannotBeOptional},
     {APIPermission::kSystemPrivate, "systemPrivate",
      APIPermissionInfo::kFlagCannotBeOptional},
     {APIPermission::kCloudPrintPrivate, "cloudPrintPrivate",
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc
index 0c2a9aa..acb917f 100644
--- a/chrome/common/extensions/permissions/permission_set_unittest.cc
+++ b/chrome/common/extensions/permissions/permission_set_unittest.cc
@@ -858,7 +858,6 @@
   skip.insert(APIPermission::kMediaRouterPrivate);
   skip.insert(APIPermission::kMetricsPrivate);
   skip.insert(APIPermission::kNetworkingCastPrivate);
-  skip.insert(APIPermission::kPreferencesPrivate);
   skip.insert(APIPermission::kImageWriterPrivate);
   skip.insert(APIPermission::kResourcesPrivate);
   skip.insert(APIPermission::kRtcPrivate);
diff --git a/chrome/renderer/extensions/custom_types_unittest.cc b/chrome/renderer/extensions/custom_types_unittest.cc
index 635cc8a..971519e1 100644
--- a/chrome/renderer/extensions/custom_types_unittest.cc
+++ b/chrome/renderer/extensions/custom_types_unittest.cc
@@ -100,15 +100,6 @@
                                 });)");
 }
 
-TEST_F(CustomTypesTest, EasyUnlockProximityRequiredUseAfterInvalidation) {
-  RunContextInvalidationTest(
-      "preferencesPrivate",
-      "chrome.preferencesPrivate.easyUnlockProximityRequired",
-      R"((function(setting) {
-           setting.onChange.addListener(function() {});
-         });)");
-}
-
 TEST_F(CustomTypesTest, ContentSettingsInvalidInvocationError) {
   scoped_refptr<const Extension> extension =
       ExtensionBuilder("foo").AddPermission("contentSettings").Build();
diff --git a/chrome/renderer/resources/extensions/chrome_direct_setting.js b/chrome/renderer/resources/extensions/chrome_direct_setting.js
deleted file mode 100644
index 7192b4d..0000000
--- a/chrome/renderer/resources/extensions/chrome_direct_setting.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var Event = require('event_bindings').Event;
-var sendRequest = require('sendRequest').sendRequest;
-var validate = require('schemaUtils').validate;
-
-function extendSchema(schema) {
-  var extendedSchema = $Array.slice(schema);
-  extendedSchema.unshift({'type': 'string'});
-  return extendedSchema;
-}
-
-function ChromeDirectSetting(prefKey, valueSchema, schema) {
-  var getFunctionParameters = function(name) {
-    var f = $Array.filter(
-                schema.functions, function(f) { return f.name === name; })[0];
-    return f.parameters;
-  };
-  this.get = function(details, callback) {
-    var getSchema = getFunctionParameters('get');
-    validate([details, callback], getSchema);
-    return sendRequest('types.private.ChromeDirectSetting.get',
-                       [prefKey, details, callback],
-                       extendSchema(getSchema));
-  };
-  this.set = function(details, callback) {
-    var setSchema = $Array.slice(getFunctionParameters('set'));
-    setSchema[0].properties.value = valueSchema;
-    validate([details, callback], setSchema);
-    return sendRequest('types.private.ChromeDirectSetting.set',
-                       [prefKey, details, callback],
-                       extendSchema(setSchema));
-  };
-  this.clear = function(details, callback) {
-    var clearSchema = getFunctionParameters('clear');
-    validate([details, callback], clearSchema);
-    return sendRequest('types.private.ChromeDirectSetting.clear',
-                       [prefKey, details, callback],
-                       extendSchema(clearSchema));
-  };
-  this.onChange = new Event('types.private.ChromeDirectSetting.' +
-                            prefKey +
-                            '.onChange');
-};
-
-exports.$set('ChromeDirectSetting', ChromeDirectSetting);
-
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 87f264276..936fe05 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1397,7 +1397,6 @@
         "../browser/extensions/api/platform_keys/platform_keys_test_base.cc",
         "../browser/extensions/api/platform_keys/platform_keys_test_base.h",
         "../browser/extensions/api/preference/preference_apitest.cc",
-        "../browser/extensions/api/preference/preferences_private_apitest.cc",
         "../browser/extensions/api/processes/processes_apitest.cc",
         "../browser/extensions/api/proxy/proxy_apitest.cc",
         "../browser/extensions/api/resources_private/resources_private_apitest.cc",
diff --git a/chrome/test/data/extensions/api_test/preference/data_reduction_proxy/manifest.json b/chrome/test/data/extensions/api_test/preference/data_reduction_proxy/manifest.json
index 95051ff..3815b72 100644
--- a/chrome/test/data/extensions/api_test/preference/data_reduction_proxy/manifest.json
+++ b/chrome/test/data/extensions/api_test/preference/data_reduction_proxy/manifest.json
@@ -3,7 +3,7 @@
   "version" : "0.1",
   "manifest_version": 2,
   "description" : "Preferences API Test Extension (dataReductionProxy)",
-  "permissions": [ "dataReductionProxy", "preferencesPrivate" ],
+  "permissions": [ "dataReductionProxy" ],
   "background": {
     "page": "test.html"
   },
diff --git a/chrome/test/data/extensions/api_test/preferences_private/manifest.json b/chrome/test/data/extensions/api_test/preferences_private/manifest.json
deleted file mode 100644
index 68edf13..0000000
--- a/chrome/test/data/extensions/api_test/preferences_private/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "name": "preferences private test",
-  "description": "foo",
-  "manifest_version": 2,
-  "version": "0.1",
-  "permissions": ["preferencesPrivate"],
-  "background": {
-    "scripts": ["test.js"]
-  },
-  "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCXAxIB5iu+XGtMYYJgSwMrqO+zNa3FlWeMJLOV+U1T2VL6wDU3WD9YNlioI6a6wG49AFquEbRxQwwxlvAZC1c95LBvRlnQAkEVum0KbrJ8WHTxxDEPOfITE0J1AP5j8V0WQ9jbYvUxgefIPhDPXHpdPRAxDotygTrPa33x1075wIDAQAB"
-}
diff --git a/chrome/test/data/extensions/api_test/preferences_private/test.js b/chrome/test/data/extensions/api_test/preferences_private/test.js
deleted file mode 100644
index f745f3c..0000000
--- a/chrome/test/data/extensions/api_test/preferences_private/test.js
+++ /dev/null
@@ -1,21 +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.
-
-chrome.test.runTests([
-  function testOnChangedExists() {
-    // Verify that the
-    // chrome.preferencesPrivate.easyUnlockProximityRequired.onChange event
-    // exists. It doesn't need to do anything other than support adding/removing
-    // listeners for backwards compatibility.
-    chrome.test.assertTrue(!!chrome.preferencesPrivate);
-    chrome.test.assertTrue(
-        !!chrome.preferencesPrivate.easyUnlockProximityRequired);
-    var onChange =
-        chrome.preferencesPrivate.easyUnlockProximityRequired.onChange;
-    chrome.test.assertTrue(!!onChange);
-    chrome.test.assertEq('function', typeof onChange.addListener);
-    chrome.test.assertEq('function', typeof onChange.removeListener);
-    chrome.test.succeed();
-  },
-]);
diff --git a/chrome/test/data/lazyload/css-pseudo-background-image.html b/chrome/test/data/lazyload/css-pseudo-background-image.html
new file mode 100644
index 0000000..10427f6c
--- /dev/null
+++ b/chrome/test/data/lazyload/css-pseudo-background-image.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<style>
+body::before {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    background-image: url("images/fruit1.jpg");
+}
+</style>
+<body>
+</body>
+</html>
diff --git a/chromecast/chromecast.gni b/chromecast/chromecast.gni
index e9c0aba..c6ac9e5a 100644
--- a/chromecast/chromecast.gni
+++ b/chromecast/chromecast.gni
@@ -17,11 +17,6 @@
   # when the default value is used.
   cast_build_incremental = "999999"
 
-  # If true, IS_CAST_DEBUG_BUILD() will evaluate to 1 in version.h. Otherwise,
-  # it will evaluate to 0. Overriding this when is_debug=false is useful for
-  # doing engineering builds.
-  cast_is_debug = is_debug
-
   if (is_android) {
     # If true, run receiver apps in an Android service instead of an activity.
     display_web_contents_in_service = is_cast_audio_only
diff --git a/chromecast/public/media/external_audio_pipeline_shlib.h b/chromecast/public/media/external_audio_pipeline_shlib.h
index 7504c53..ce71ebe 100644
--- a/chromecast/public/media/external_audio_pipeline_shlib.h
+++ b/chromecast/public/media/external_audio_pipeline_shlib.h
@@ -128,12 +128,12 @@
 
   // Adds an external media metadata observer.
   static void AddExternalMediaMetadataChangeObserver(
-      ExternalMediaMetadataChangeObserver* observer) __attribute__((__weak__));
+      ExternalMediaMetadataChangeObserver* observer);
 
   // Removes an external media volume observer. After this is called, the
   // implementation must not call any more methods on the observer.
   static void RemoveExternalMediaMetadataChangeObserver(
-      ExternalMediaMetadataChangeObserver* observer) __attribute__((__weak__));
+      ExternalMediaMetadataChangeObserver* observer);
 
   // Returns an instance of MixerOutputStream from the shared library.
   // Caller will take ownership of the returned pointer.
diff --git a/components/browser_sync/BUILD.gn b/components/browser_sync/BUILD.gn
index 4265fc59..430e510 100644
--- a/components/browser_sync/BUILD.gn
+++ b/components/browser_sync/BUILD.gn
@@ -101,8 +101,6 @@
   sources = [
     "abstract_profile_sync_service_test.cc",
     "abstract_profile_sync_service_test.h",
-    "profile_sync_service_mock.cc",
-    "profile_sync_service_mock.h",
     "profile_sync_test_util.cc",
     "profile_sync_test_util.h",
     "test_http_bridge_factory.cc",
diff --git a/components/browser_sync/abstract_profile_sync_service_test.cc b/components/browser_sync/abstract_profile_sync_service_test.cc
index 99656582..2b67e98 100644
--- a/components/browser_sync/abstract_profile_sync_service_test.cc
+++ b/components/browser_sync/abstract_profile_sync_service_test.cc
@@ -146,6 +146,7 @@
   EXPECT_CALL(*components, CreateSyncEngine(_, _, _))
       .WillOnce(Return(ByMove(std::move(engine))));
 
+  sync_service_->sync_prefs()->SetSyncRequested(true);
   sync_service_->sync_prefs()->SetFirstSetupComplete();
 }
 
diff --git a/components/browser_sync/profile_sync_service_mock.cc b/components/browser_sync/profile_sync_service_mock.cc
deleted file mode 100644
index c0692f3..0000000
--- a/components/browser_sync/profile_sync_service_mock.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/browser_sync/profile_sync_service_mock.h"
-
-#include <utility>
-
-#include "components/sync/base/sync_prefs.h"
-
-namespace browser_sync {
-
-ProfileSyncServiceMock::ProfileSyncServiceMock(InitParams init_params)
-    : ProfileSyncService(std::move(init_params)) {}
-
-ProfileSyncServiceMock::~ProfileSyncServiceMock() {}
-
-syncer::SyncUserSettingsMock* ProfileSyncServiceMock::GetUserSettingsMock() {
-  return &user_settings_;
-}
-
-syncer::SyncUserSettings* ProfileSyncServiceMock::GetUserSettings() {
-  return &user_settings_;
-}
-
-const syncer::SyncUserSettings* ProfileSyncServiceMock::GetUserSettings()
-    const {
-  return &user_settings_;
-}
-
-bool ProfileSyncServiceMock::IsAuthenticatedAccountPrimary() const {
-  return true;
-}
-
-syncer::ModelTypeSet ProfileSyncServiceMock::GetPreferredDataTypes() const {
-  return syncer::SyncPrefs::ResolvePrefGroups(
-      user_settings_.GetChosenDataTypes());
-}
-
-std::unique_ptr<syncer::SyncSetupInProgressHandle>
-ProfileSyncServiceMock::GetSetupInProgressHandleConcrete() {
-  return browser_sync::ProfileSyncService::GetSetupInProgressHandle();
-}
-
-}  // namespace browser_sync
diff --git a/components/browser_sync/profile_sync_service_mock.h b/components/browser_sync/profile_sync_service_mock.h
deleted file mode 100644
index 3936f4a..0000000
--- a/components/browser_sync/profile_sync_service_mock.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_MOCK_H_
-#define COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_MOCK_H_
-
-#include <memory>
-#include <string>
-
-#include "base/memory/weak_ptr.h"
-#include "components/browser_sync/profile_sync_service.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/driver/sync_user_settings_mock.h"
-#include "components/sync/protocol/sync_protocol_error.h"
-#include "google_apis/gaia/google_service_auth_error.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace browser_sync {
-
-class ProfileSyncServiceMock : public ProfileSyncService {
- public:
-  explicit ProfileSyncServiceMock(InitParams init_params);
-  ~ProfileSyncServiceMock() override;
-
-  syncer::SyncUserSettingsMock* GetUserSettingsMock();
-
-  // SyncService overrides.
-  syncer::SyncUserSettings* GetUserSettings() override;
-  const syncer::SyncUserSettings* GetUserSettings() const override;
-  MOCK_CONST_METHOD0(GetDisableReasons, int());
-  MOCK_CONST_METHOD0(GetTransportState, TransportState());
-  // TODO(crbug.com/871221): Remove this override. This is overridden here to
-  // return true by default, as a workaround for tests not setting up an
-  // authenticated account and IsSyncFeatureEnabled() therefore returning false.
-  bool IsAuthenticatedAccountPrimary() const override;
-  MOCK_CONST_METHOD0(GetAuthError, GoogleServiceAuthError());
-
-  MOCK_METHOD0(GetSetupInProgressHandle,
-               std::unique_ptr<syncer::SyncSetupInProgressHandle>());
-  MOCK_CONST_METHOD0(IsSetupInProgress, bool());
-
-  MOCK_CONST_METHOD0(GetRegisteredDataTypes, syncer::ModelTypeSet());
-  syncer::ModelTypeSet GetPreferredDataTypes() const override;
-  MOCK_CONST_METHOD0(GetActiveDataTypes, syncer::ModelTypeSet());
-
-  MOCK_METHOD0(StopAndClear, void());
-
-  MOCK_METHOD1(AddObserver, void(syncer::SyncServiceObserver*));
-  MOCK_METHOD1(RemoveObserver, void(syncer::SyncServiceObserver*));
-
-  MOCK_CONST_METHOD0(GetUserShare, syncer::UserShare*());
-
-  MOCK_CONST_METHOD1(QueryDetailedSyncStatusForDebugging,
-                     bool(syncer::SyncStatus* result));
-  MOCK_CONST_METHOD0(GetLastSyncedTime, base::Time());
-  MOCK_CONST_METHOD0(GetLastCycleSnapshot, syncer::SyncCycleSnapshot());
-
-  MOCK_METHOD0(GetJsController, base::WeakPtr<syncer::JsController>());
-
-  // SyncEngineHost overrides.
-  MOCK_METHOD8(
-      OnEngineInitialized,
-      void(syncer::ModelTypeSet initial_types,
-           const syncer::WeakHandle<syncer::JsBackend>&,
-           const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&,
-           const std::string&,
-           const std::string&,
-           const std::string&,
-           const std::string&,
-           bool));
-  MOCK_METHOD1(OnSyncCycleCompleted, void(const syncer::SyncCycleSnapshot&));
-  MOCK_METHOD1(OnActionableError, void(const syncer::SyncProtocolError&));
-
-  // DataTypeManagerObserver overrides.
-  MOCK_METHOD1(OnConfigureDone,
-               void(const syncer::DataTypeManager::ConfigureResult&));
-  MOCK_METHOD0(OnConfigureStart, void());
-
-  // syncer::UnrecoverableErrorHandler overrides.
-  MOCK_METHOD2(OnUnrecoverableError,
-               void(const base::Location& location,
-                    const std::string& message));
-
-  // ProfileSyncService overrides.
-  MOCK_CONST_METHOD1(IsDataTypeControllerRunning, bool(syncer::ModelType));
-
-  MOCK_METHOD0(StartUpSlowEngineComponents, void());
-
-  MOCK_METHOD0(OnSetupInProgressHandleDestroyed, void());
-
-  // Gives access to the real implementation of ProfileSyncService methods:
-  std::unique_ptr<syncer::SyncSetupInProgressHandle>
-  GetSetupInProgressHandleConcrete();
-
- private:
-  testing::NiceMock<syncer::SyncUserSettingsMock> user_settings_;
-};
-
-}  // namespace browser_sync
-
-#endif  // COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_MOCK_H_
diff --git a/components/browser_sync/profile_sync_service_startup_unittest.cc b/components/browser_sync/profile_sync_service_startup_unittest.cc
index 14d5e399..bf77ca8 100644
--- a/components/browser_sync/profile_sync_service_startup_unittest.cc
+++ b/components/browser_sync/profile_sync_service_startup_unittest.cc
@@ -173,7 +173,8 @@
   // Should not actually start, rather just clean things up and wait
   // to be enabled.
   sync_service()->Initialize();
-  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
+  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN |
+                syncer::SyncService::DISABLE_REASON_USER_CHOICE,
             sync_service()->GetDisableReasons());
   EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
             sync_service()->GetTransportState());
@@ -185,6 +186,7 @@
   // This tells the ProfileSyncService that setup is now in progress, which
   // causes it to try starting up the engine. We're not signed in yet though, so
   // that won't work.
+  sync_service()->GetUserSettings()->SetSyncRequested(true);
   auto sync_blocker = sync_service()->GetSetupInProgressHandle();
   EXPECT_FALSE(sync_service()->IsEngineInitialized());
   EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
@@ -262,6 +264,7 @@
 
 TEST_F(ProfileSyncServiceStartupTest, StartInvalidCredentials) {
   SimulateTestUserSignin();
+  sync_prefs()->SetSyncRequested(true);
   sync_prefs()->SetFirstSetupComplete();
 
   CreateSyncService(ProfileSyncService::MANUAL_START);
@@ -387,9 +390,10 @@
 }
 
 TEST_F(ProfileSyncServiceStartupTest, DisableSync) {
+  sync_prefs()->SetSyncRequested(true);
   sync_prefs()->SetFirstSetupComplete();
-  CreateSyncService(ProfileSyncService::MANUAL_START);
   SimulateTestUserSignin();
+  CreateSyncService(ProfileSyncService::MANUAL_START);
   SetUpFakeSyncEngine();
   DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
   ON_CALL(*data_type_manager, state())
@@ -397,6 +401,7 @@
   ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
 
   sync_service()->Initialize();
+  ASSERT_TRUE(sync_service()->IsSyncFeatureActive());
 
   // On StopAndClear(), the sync service will immediately start up again in
   // transport mode.
@@ -460,13 +465,15 @@
 }
 
 TEST_F(ProfileSyncServiceStartupTest, ManagedStartup) {
-  // Service should not be started by Initialize() since it's managed.
+  // Sync is enabled by the user, but disabled by policy.
+  sync_prefs()->SetManagedForTest(true);
+  sync_prefs()->SetSyncRequested(true);
+  sync_prefs()->SetFirstSetupComplete();
+
   SimulateTestUserSignin();
   CreateSyncService(ProfileSyncService::MANUAL_START);
 
-  // Disable sync through policy.
-  sync_prefs()->SetManagedForTest(true);
-
+  // Service should not be started by Initialize() since it's managed.
   EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _)).Times(0);
   EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
       .Times(0);
@@ -476,15 +483,20 @@
 }
 
 TEST_F(ProfileSyncServiceStartupTest, SwitchManaged) {
+  // Sync starts out fully set up and enabled.
+  sync_prefs()->SetSyncRequested(true);
   sync_prefs()->SetFirstSetupComplete();
-  CreateSyncService(ProfileSyncService::MANUAL_START);
   SimulateTestUserSignin();
+  CreateSyncService(ProfileSyncService::MANUAL_START);
   SetUpFakeSyncEngine();
   DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
   EXPECT_CALL(*data_type_manager, Configure(_, _));
   ON_CALL(*data_type_manager, state())
       .WillByDefault(Return(DataTypeManager::CONFIGURED));
   ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
+
+  // Initialize() should be enough to kick off Sync startup (which is instant in
+  // this test).
   sync_service()->Initialize();
   EXPECT_TRUE(sync_service()->IsEngineInitialized());
   EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
@@ -528,12 +540,15 @@
   EXPECT_TRUE(sync_service()->IsEngineInitialized());
   EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
             sync_service()->GetTransportState());
-  // Sync-the-feature is still considered off.
+  // Sync-the-feature is still considered off because disabling Sync through
+  // policy also reset the first-setup-complete flag.
+  EXPECT_FALSE(sync_service()->GetUserSettings()->IsFirstSetupComplete());
   EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
   EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
 }
 
 TEST_F(ProfileSyncServiceStartupTest, StartFailure) {
+  sync_prefs()->SetSyncRequested(true);
   sync_prefs()->SetFirstSetupComplete();
   CreateSyncService(ProfileSyncService::MANUAL_START);
   SimulateTestUserSignin();
@@ -556,6 +571,7 @@
 }
 
 TEST_F(ProfileSyncServiceStartupTest, StartDownloadFailed) {
+  sync_prefs()->SetSyncRequested(true);
   CreateSyncService(ProfileSyncService::MANUAL_START);
   SimulateTestUserSignin();
   FakeSyncEngine* fake_engine = SetUpFakeSyncEngine();
@@ -594,21 +610,28 @@
                     syncer::ModelTypeSet(syncer::SESSIONS));
   sync_service()->Initialize();
 
-  // There is no signed-in user, but nothing else prevents Sync from starting.
-  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
+  // There is no signed-in user, so also nobody has decided that Sync should be
+  // started.
+  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN |
+                syncer::SyncService::DISABLE_REASON_USER_CHOICE,
             sync_service()->GetDisableReasons());
   EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
             sync_service()->GetTransportState());
 
-  // Sign in. Now Sync is ready to start, just waiting for a prod.
+  // Sign in. Now Sync-the-transport could start, but gets deferred by default.
+  // Sync-the-feature still doesn't start until the user says they want it.
   SimulateTestUserSignin();
+  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_USER_CHOICE,
+            sync_service()->GetDisableReasons());
   EXPECT_EQ(syncer::SyncService::TransportState::START_DEFERRED,
             sync_service()->GetTransportState());
+  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
 
   // Once we give the service a prod by initiating Sync setup, it'll start and
   // initialize the engine. Since this is the initial Sync start, this will not
   // be deferred.
   EXPECT_CALL(*sync_engine, Initialize(_));
+  sync_service()->GetUserSettings()->SetSyncRequested(true);
   auto setup_in_progress_handle = sync_service()->GetSetupInProgressHandle();
   EXPECT_EQ(syncer::SyncService::TransportState::INITIALIZING,
             sync_service()->GetTransportState());
diff --git a/components/browser_sync/profile_sync_service_unittest.cc b/components/browser_sync/profile_sync_service_unittest.cc
index 2d78f84..15d069df 100644
--- a/components/browser_sync/profile_sync_service_unittest.cc
+++ b/components/browser_sync/profile_sync_service_unittest.cc
@@ -225,10 +225,11 @@
     // Set first sync time before initialize to simulate a complete sync setup.
     syncer::SyncPrefs sync_prefs(prefs());
     sync_prefs.SetLastSyncedTime(base::Time::Now());
-    sync_prefs.SetFirstSetupComplete();
+    sync_prefs.SetSyncRequested(true);
     sync_prefs.SetDataTypesConfiguration(/*keep_everything_synced=*/true,
                                          syncer::UserTypes(),
                                          syncer::UserSelectableTypes());
+    sync_prefs.SetFirstSetupComplete();
     service_->Initialize();
   }
 
@@ -344,6 +345,7 @@
   syncer::SyncPrefs sync_prefs(prefs());
   base::Time now = base::Time::Now();
   sync_prefs.SetLastSyncedTime(now);
+  sync_prefs.SetSyncRequested(true);
   sync_prefs.SetDataTypesConfiguration(/*keep_everything_synced=*/true,
                                        syncer::UserTypes(),
                                        syncer::UserSelectableTypes());
diff --git a/components/flags_ui/resources/flags.js b/components/flags_ui/resources/flags.js
index c993e96..8cc6672d 100644
--- a/components/flags_ui/resources/flags.js
+++ b/components/flags_ui/resources/flags.js
@@ -16,31 +16,25 @@
  */
 function renderTemplate(experimentalFeaturesData) {
   var templateToProcess = jstGetTemplate('tab-content-available-template');
+  var context = new JsEvalContext(experimentalFeaturesData);
   var content = $('tab-content-available');
 
-  if (content.childNodes > 0) {
-    // Already processed, use the internal content area template.
-    templateToProcess =  content;
-  } else {
-    // Duplicate the template into the content area.
-    // This prevents the misrendering of available flags when the template
-    // is rerendered. Example - resetting flags.
-    content.textContent = '';
-    content.appendChild(templateToProcess);
-  }
+  // Duplicate the template into the content area.
+  // This prevents the misrendering of available flags when the template
+  // is rerendered. Example - resetting flags.
+  content.textContent = '';
+  content.appendChild(templateToProcess);
 
   // Process the templates: available / unavailable flags.
-  jstProcess(new JsEvalContext(experimentalFeaturesData), templateToProcess);
+  jstProcess(context, templateToProcess);
 
   // Unavailable flags are not shown on iOS.
   var unavailableTemplate = $('tab-content-unavailable');
   if (unavailableTemplate) {
-    jstProcess(new JsEvalContext(experimentalFeaturesData),
-        $('tab-content-unavailable'));
+    jstProcess(context, $('tab-content-unavailable'));
   }
 
-  // Update the restart container.
-  jstProcess(new JsEvalContext(experimentalFeaturesData), $('needs-restart'));
+  showRestartToast(experimentalFeaturesData.needsRestart);
 
   // Add handlers to dynamically created HTML elements.
   var elements = document.getElementsByClassName('experiment-select');
@@ -152,10 +146,19 @@
 function resetAllFlags() {
   // Asks the C++ FlagsDOMHandler to reset all flags to default values.
   chrome.send('resetAllFlags');
+  showRestartToast(true);
   requestExperimentalFeaturesData();
 }
 
 /**
+ * Show the restart toast.
+ * @param {boolean} show Setting to toggle showing / hiding the toast.
+ */
+function showRestartToast(show) {
+  $('needs-restart').classList.toggle('show', show);
+}
+
+/**
  * Called by the WebUI to re-populate the page with data representing the
  * current state of all experimental features.
  * @param {Object} experimentalFeaturesData Information about all experimental
@@ -227,7 +230,7 @@
   experimentContainerEl.classList.toggle('experiment-default', isDefault);
   experimentContainerEl.classList.toggle('experiment-switched', !isDefault);
 
-  $('needs-restart').classList.add('show');
+  showRestartToast(true);
 }
 
 /**
@@ -244,7 +247,7 @@
 
 function handleSetOriginListFlag(node, value) {
   chrome.send('setOriginListFlag', [String(node.internal_name), String(value)]);
-  $('needs-restart').classList.add('show');
+  showRestartToast(true);
 }
 
 /**
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc
index db7aa12e..26c1237 100644
--- a/components/sync/base/sync_prefs.cc
+++ b/components/sync/base/sync_prefs.cc
@@ -147,7 +147,7 @@
     user_prefs::PrefRegistrySyncable* registry) {
   // Actual user-controlled preferences.
   registry->RegisterBooleanPref(prefs::kSyncFirstSetupComplete, false);
-  registry->RegisterBooleanPref(prefs::kSyncSuppressStart, false);
+  registry->RegisterBooleanPref(prefs::kSyncSuppressStart, true);
   registry->RegisterBooleanPref(prefs::kSyncKeepEverythingSynced, true);
   for (ModelType type : UserSelectableTypes()) {
     RegisterDataTypePreferredPref(registry, type);
diff --git a/components/sync/base/sync_prefs_unittest.cc b/components/sync/base/sync_prefs_unittest.cc
index 7bcad55..71c1bf6 100644
--- a/components/sync/base/sync_prefs_unittest.cc
+++ b/components/sync/base/sync_prefs_unittest.cc
@@ -77,12 +77,12 @@
   EXPECT_CALL(mock_sync_pref_observer, OnSyncManagedPrefChange(false));
   EXPECT_CALL(mock_sync_pref_observer, OnFirstSetupCompletePrefChange(true));
   EXPECT_CALL(mock_sync_pref_observer, OnFirstSetupCompletePrefChange(false));
-  EXPECT_CALL(mock_sync_pref_observer, OnSyncRequestedPrefChange(false));
   EXPECT_CALL(mock_sync_pref_observer, OnSyncRequestedPrefChange(true));
+  EXPECT_CALL(mock_sync_pref_observer, OnSyncRequestedPrefChange(false));
 
   ASSERT_FALSE(sync_prefs_->IsManaged());
   ASSERT_FALSE(sync_prefs_->IsFirstSetupComplete());
-  ASSERT_TRUE(sync_prefs_->IsSyncRequested());
+  ASSERT_FALSE(sync_prefs_->IsSyncRequested());
 
   sync_prefs_->AddSyncPrefObserver(&mock_sync_pref_observer);
 
@@ -98,10 +98,10 @@
   sync_prefs_->ClearPreferences();
   EXPECT_FALSE(sync_prefs_->IsFirstSetupComplete());
 
-  sync_prefs_->SetSyncRequested(false);
-  EXPECT_FALSE(sync_prefs_->IsSyncRequested());
   sync_prefs_->SetSyncRequested(true);
   EXPECT_TRUE(sync_prefs_->IsSyncRequested());
+  sync_prefs_->SetSyncRequested(false);
+  EXPECT_FALSE(sync_prefs_->IsSyncRequested());
 
   sync_prefs_->RemoveSyncPrefObserver(&mock_sync_pref_observer);
 }
@@ -135,11 +135,11 @@
   sync_prefs_->SetFirstSetupComplete();
   EXPECT_TRUE(sync_prefs_->IsFirstSetupComplete());
 
-  EXPECT_TRUE(sync_prefs_->IsSyncRequested());
-  sync_prefs_->SetSyncRequested(false);
   EXPECT_FALSE(sync_prefs_->IsSyncRequested());
   sync_prefs_->SetSyncRequested(true);
   EXPECT_TRUE(sync_prefs_->IsSyncRequested());
+  sync_prefs_->SetSyncRequested(false);
+  EXPECT_FALSE(sync_prefs_->IsSyncRequested());
 
   EXPECT_EQ(base::Time(), sync_prefs_->GetLastSyncedTime());
   const base::Time& now = base::Time::Now();
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index bda4857..9bccad4 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1644,8 +1644,6 @@
     "service_worker/embedded_worker_status.h",
     "service_worker/payment_handler_support.cc",
     "service_worker/payment_handler_support.h",
-    "service_worker/service_worker_blob_reader.cc",
-    "service_worker/service_worker_blob_reader.h",
     "service_worker/service_worker_cache_writer.cc",
     "service_worker/service_worker_cache_writer.h",
     "service_worker/service_worker_client_info.cc",
@@ -1665,8 +1663,6 @@
     "service_worker/service_worker_context_wrapper.h",
     "service_worker/service_worker_controllee_request_handler.cc",
     "service_worker/service_worker_controllee_request_handler.h",
-    "service_worker/service_worker_data_pipe_reader.cc",
-    "service_worker/service_worker_data_pipe_reader.h",
     "service_worker/service_worker_database.cc",
     "service_worker/service_worker_database.h",
     "service_worker/service_worker_disk_cache.cc",
@@ -1734,10 +1730,6 @@
     "service_worker/service_worker_unregister_job.h",
     "service_worker/service_worker_update_checker.cc",
     "service_worker/service_worker_update_checker.h",
-    "service_worker/service_worker_url_job_wrapper.cc",
-    "service_worker/service_worker_url_job_wrapper.h",
-    "service_worker/service_worker_url_request_job.cc",
-    "service_worker/service_worker_url_request_job.h",
     "service_worker/service_worker_version.cc",
     "service_worker/service_worker_version.h",
     "site_instance_impl.cc",
diff --git a/content/browser/DEPS b/content/browser/DEPS
index f05cdb3..2167d47 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -139,7 +139,6 @@
   "+third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom.h",
   "+third_party/blink/public/platform/modules/webauthn/authenticator.mojom.h",
   "+third_party/blink/public/platform/modules/webauthn/virtual_authenticator.mojom.h",
-  "+third_party/blink/public/platform/modules/webdatabase/web_database.mojom.h",
   "+third_party/blink/public/platform/modules/websockets/websocket.mojom.h",
   "+third_party/blink/public/web/commit_result.mojom.h",
   "+third_party/blink/public/web/devtools_frontend.mojom.h",
diff --git a/content/browser/accessibility/accessibility_auralinux_browsertest.cc b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
index 6ea470f..15340ebf 100644
--- a/content/browser/accessibility/accessibility_auralinux_browsertest.cc
+++ b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
@@ -12,40 +12,24 @@
 
 #include "base/bind_helpers.h"
 #include "base/macros.h"
+#include "content/browser/accessibility/accessibility_browsertest.h"
 #include "content/browser/accessibility/browser_accessibility.h"
 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
 #include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/test/browser_test_utils.h"
-#include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "content/test/accessibility_browser_test_utils.h"
 #include "content/test/content_browser_test_utils_internal.h"
-#include "net/base/escape.h"
 #include "ui/accessibility/platform/ax_platform_node_auralinux.h"
 
 namespace content {
 
-constexpr char kInputContents[] =
-    "Moz/5.0 (ST 6.x; WWW33) "
-    "WebKit  \"KHTML, like\".";
-constexpr char kTextareaContents[] =
-    "Moz/5.0 (ST 6.x; WWW33)\n"
-    "WebKit \n\"KHTML, like\".";
-constexpr int kContentsLength =
-    static_cast<int>((sizeof(kInputContents) - 1) / sizeof(char));
-
-class AccessibilityAuraLinuxBrowserTest : public ContentBrowserTest {
+class AccessibilityAuraLinuxBrowserTest : public AccessibilityBrowserTest {
  public:
   AccessibilityAuraLinuxBrowserTest() = default;
   ~AccessibilityAuraLinuxBrowserTest() override = default;
 
  protected:
-  AtkObject* GetRendererAccessible() {
-    content::WebContents* web_contents = shell()->web_contents();
-    return web_contents->GetRenderWidgetHostView()->GetNativeViewAccessible();
-  }
-
   static bool HasObjectWithAtkRoleFrameInAncestry(AtkObject* object) {
     while (object) {
       if (atk_object_get_role(object) == ATK_ROLE_FRAME)
@@ -55,7 +39,6 @@
     return false;
   }
 
-  void LoadInitialAccessibilityTreeFromHtml(const std::string& html);
   static void CheckTextAtOffset(AtkText* text_object,
                                 int offset,
                                 AtkTextBoundary boundary_type,
@@ -63,10 +46,10 @@
                                 int expected_end_offset,
                                 const char* expected_text);
 
-  void ExecuteScript(const std::string& script);
   AtkText* SetUpInputField();
   AtkText* SetUpTextareaField();
   AtkText* SetUpSampleParagraph();
+  AtkText* SetUpSampleParagraphInScrollableEditable();
 
   AtkText* GetAtkTextForChild(AtkRole expected_role);
 
@@ -74,23 +57,6 @@
   DISALLOW_COPY_AND_ASSIGN(AccessibilityAuraLinuxBrowserTest);
 };
 
-void AccessibilityAuraLinuxBrowserTest::ExecuteScript(
-    const std::string& script) {
-  shell()->web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
-      base::UTF8ToUTF16(script), base::NullCallback());
-}
-
-void AccessibilityAuraLinuxBrowserTest::LoadInitialAccessibilityTreeFromHtml(
-    const std::string& html) {
-  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
-                                         ui::kAXModeComplete,
-                                         ax::mojom::Event::kLoadComplete);
-  GURL html_data_url("data:text/html," +
-                     net::EscapeQueryParamValue(html, false));
-  NavigateToURL(shell(), html_data_url);
-  waiter.WaitForNotification();
-}
-
 AtkText* AccessibilityAuraLinuxBrowserTest::GetAtkTextForChild(
     AtkRole expected_role) {
   AtkObject* document = GetRendererAccessible();
@@ -115,50 +81,38 @@
 
 // Loads a page with  an input text field and places sample text in it.
 AtkText* AccessibilityAuraLinuxBrowserTest::SetUpInputField() {
-  LoadInitialAccessibilityTreeFromHtml(std::string(
-                                           R"HTML(<!DOCTYPE html>
-          <html>
-          <body>
-            <form>
-              <label for="textField">Browser name:</label>
-              <input type="text" id="textField" name="name" value=")HTML") +
-                                       net::EscapeForHTML(kInputContents) +
-                                       std::string(R"HTML(">
-            </form>
-          </body>
-          </html>)HTML"));
-
+  LoadInputField();
   return GetAtkTextForChild(ATK_ROLE_ENTRY);
 }
 
 // Loads a page with  a textarea text field and places sample text in it. Also,
 // places the caret before the last character.
 AtkText* AccessibilityAuraLinuxBrowserTest::SetUpTextareaField() {
-  LoadInitialAccessibilityTreeFromHtml(std::string(R"HTML(<!DOCTYPE html>
-      <html>
-      <body>
-                    <textarea rows="3" cols="60">)HTML") +
-                                       net::EscapeForHTML(kTextareaContents) +
-                                       std::string(R"HTML(</textarea>
-          </body>
-          </html>)HTML"));
-
+  LoadTextareaField();
   return GetAtkTextForChild(ATK_ROLE_ENTRY);
 }
 
-// Loads a page with  a paragraph of sample text.
+// Loads a page with a paragraph of sample text.
 AtkText* AccessibilityAuraLinuxBrowserTest::SetUpSampleParagraph() {
-  LoadInitialAccessibilityTreeFromHtml(
-      R"HTML(<!DOCTYPE html>
-      <html>
-      <body>
-          <p><b>Game theory</b> is "the study of
-              <a href="" title="Mathematical model">mathematical models</a>
-              of conflict and<br>cooperation between intelligent rational
-              decision-makers."
-          </p>
-      </body>
-      </html>)HTML");
+  LoadSampleParagraph();
+
+  AtkObject* document = GetRendererAccessible();
+  EXPECT_EQ(1, atk_object_get_n_accessible_children(document));
+
+  int number_of_children = atk_object_get_n_accessible_children(document);
+  EXPECT_LT(0, number_of_children);
+
+  // The input field is always the last child.
+  AtkObject* input = atk_object_ref_accessible_child(document, 0);
+  EXPECT_EQ(ATK_ROLE_PARAGRAPH, atk_object_get_role(input));
+
+  EXPECT_TRUE(ATK_IS_TEXT(input));
+  return ATK_TEXT(input);
+}
+
+AtkText*
+AccessibilityAuraLinuxBrowserTest::SetUpSampleParagraphInScrollableEditable() {
+  LoadSampleParagraphInScrollableEditable();
 
   AtkObject* document = GetRendererAccessible();
   EXPECT_EQ(1, atk_object_get_n_accessible_children(document));
@@ -231,7 +185,8 @@
 
   // Single line text fields should return the whole text.
   CheckTextAtOffset(atk_text, 0, ATK_TEXT_BOUNDARY_LINE_START, 0,
-                    kContentsLength, kInputContents);
+                    InputContentsString().size(),
+                    InputContentsString().c_str());
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
@@ -247,7 +202,7 @@
 
   // Last line does not have a trailing newline.
   CheckTextAtOffset(atk_text, 32, ATK_TEXT_BOUNDARY_LINE_START, 32,
-                    kContentsLength, "\"KHTML, like\".");
+                    InputContentsString().size(), "\"KHTML, like\".");
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
@@ -277,4 +232,235 @@
   }
 }
 
+IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
+                       TestCharacterExtentsWithInvalidArguments) {
+  AtkText* atk_text = SetUpSampleParagraph();
+
+  int invalid_offset = -3;
+  int x = -1, y = -1;
+  int width = -1, height = -1;
+
+  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
+                                 &height, ATK_XY_SCREEN);
+  EXPECT_EQ(0, x);
+  EXPECT_EQ(0, y);
+  EXPECT_EQ(0, width);
+  EXPECT_EQ(0, height);
+
+  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
+                                 &height, ATK_XY_PARENT);
+  EXPECT_EQ(0, x);
+  EXPECT_EQ(0, y);
+  EXPECT_EQ(0, width);
+  EXPECT_EQ(0, height);
+
+  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
+                                 &height, ATK_XY_WINDOW);
+  EXPECT_EQ(0, x);
+  EXPECT_EQ(0, y);
+  EXPECT_EQ(0, width);
+  EXPECT_EQ(0, height);
+
+  int n_characters = atk_text_get_character_count(atk_text);
+  ASSERT_LT(0, n_characters);
+
+  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
+                                 &height, ATK_XY_SCREEN);
+  EXPECT_EQ(0, x);
+  EXPECT_EQ(0, y);
+  EXPECT_EQ(0, width);
+  EXPECT_EQ(0, height);
+
+  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
+                                 &height, ATK_XY_PARENT);
+  EXPECT_EQ(0, x);
+  EXPECT_EQ(0, y);
+  EXPECT_EQ(0, width);
+  EXPECT_EQ(0, height);
+
+  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
+                                 &height, ATK_XY_WINDOW);
+  EXPECT_EQ(0, x);
+  EXPECT_EQ(0, y);
+  EXPECT_EQ(0, width);
+  EXPECT_EQ(0, height);
+}
+
+AtkCoordType kCoordinateTypes[] = {
+    ATK_XY_SCREEN,
+    ATK_XY_WINDOW,
+    ATK_XY_PARENT,
+};
+
+IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
+                       TestCharacterExtentsInEditable) {
+  AtkText* atk_text = SetUpSampleParagraph();
+
+  constexpr int newline_offset = 46;
+  int n_characters = atk_text_get_character_count(atk_text);
+  ASSERT_EQ(105, n_characters);
+
+  int x, y, width, height;
+  int previous_x, previous_y, previous_height;
+  for (AtkCoordType coordinate_type : kCoordinateTypes) {
+    atk_text_get_character_extents(atk_text, 0, &x, &y, &width, &height,
+                                   coordinate_type);
+    EXPECT_LT(0, x) << "at offset 0";
+    EXPECT_LT(0, y) << "at offset 0";
+    EXPECT_LT(1, width) << "at offset 0";
+    EXPECT_LT(1, height) << "at offset 0";
+
+    gfx::Rect combined_extents(x, y, width, height);
+    for (int offset = 1; offset < newline_offset; ++offset) {
+      testing::Message message;
+      message << "While checking at offset " << offset;
+      SCOPED_TRACE(message);
+
+      previous_x = x;
+      previous_y = y;
+      previous_height = height;
+
+      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
+                                     coordinate_type);
+      EXPECT_LT(previous_x, x);
+      EXPECT_EQ(previous_y, y);
+      EXPECT_LT(1, width);
+      EXPECT_EQ(previous_height, height);
+
+      combined_extents.Union(gfx::Rect(x, y, width, height));
+      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
+                                     coordinate_type);
+
+      AtkTextRectangle atk_rect;
+      atk_text_get_range_extents(atk_text, 0, offset + 1, coordinate_type,
+                                 &atk_rect);
+      EXPECT_EQ(combined_extents.x(), atk_rect.x);
+      EXPECT_EQ(combined_extents.y(), atk_rect.y);
+      EXPECT_EQ(combined_extents.width(), atk_rect.width);
+      EXPECT_EQ(combined_extents.height(), atk_rect.height);
+    }
+
+    {
+      testing::Message message;
+      message << "While checking at offset " << newline_offset + 1;
+      SCOPED_TRACE(message);
+
+      atk_text_get_character_extents(atk_text, newline_offset + 1, &x, &y,
+                                     &width, &height, coordinate_type);
+      EXPECT_LE(0, x);
+      EXPECT_GT(previous_x, x);
+      EXPECT_LT(previous_y, y);
+      EXPECT_LT(1, width);
+      EXPECT_EQ(previous_height, height);
+    }
+
+    combined_extents = gfx::Rect(x, y, width, height);
+    for (int offset = newline_offset + 2; offset < n_characters; ++offset) {
+      testing::Message message;
+      message << "While checking at offset " << offset;
+      SCOPED_TRACE(message);
+
+      previous_x = x;
+      previous_y = y;
+      previous_height = height;
+
+      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
+                                     coordinate_type);
+      EXPECT_LT(previous_x, x);
+      EXPECT_EQ(previous_y, y);
+      EXPECT_LT(1, width);
+      EXPECT_EQ(previous_height, height);
+
+      combined_extents.Union(gfx::Rect(x, y, width, height));
+      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
+                                     coordinate_type);
+
+      AtkTextRectangle atk_rect;
+      atk_text_get_range_extents(atk_text, newline_offset + 1, offset + 1,
+                                 coordinate_type, &atk_rect);
+      EXPECT_EQ(combined_extents.x(), atk_rect.x);
+      EXPECT_EQ(combined_extents.y(), atk_rect.y);
+      EXPECT_EQ(combined_extents.width(), atk_rect.width);
+      EXPECT_EQ(combined_extents.height(), atk_rect.height);
+    }
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
+                       TestCharacterExtentsInScrollableEditable) {
+  // By construction, only the first line of the content editable is visible.
+  AtkText* atk_text = SetUpSampleParagraphInScrollableEditable();
+
+  constexpr int first_line_end = 5;
+  constexpr int last_line_start = 8;
+
+  int n_characters = atk_text_get_character_count(atk_text);
+  ASSERT_EQ(13, n_characters);
+
+  int x, y, width, height;
+  int previous_x, previous_y, previous_height;
+  for (AtkCoordType coordinate_type : kCoordinateTypes) {
+    // Test that non offscreen characters have increasing x coordinates and a
+    // height that is greater than 1px.
+    {
+      testing::Message message;
+      message << "While checking at offset 0";
+      SCOPED_TRACE(message);
+
+      atk_text_get_character_extents(atk_text, 0, &x, &y, &width, &height,
+                                     coordinate_type);
+      EXPECT_LT(0, x);
+      EXPECT_LT(0, y);
+      EXPECT_LT(1, width);
+      EXPECT_LT(1, height);
+    }
+
+    for (int offset = 1; offset < first_line_end; ++offset) {
+      testing::Message message;
+      message << "While checking at offset " << offset;
+      SCOPED_TRACE(message);
+
+      previous_x = x;
+      previous_y = y;
+      previous_height = height;
+
+      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
+                                     coordinate_type);
+      EXPECT_LT(previous_x, x);
+      EXPECT_EQ(previous_y, y);
+      EXPECT_LT(1, width);
+      EXPECT_EQ(previous_height, height);
+    }
+
+    {
+      testing::Message message;
+      message << "While checking at offset " << last_line_start;
+      SCOPED_TRACE(message);
+
+      atk_text_get_character_extents(atk_text, last_line_start, &x, &y, &width,
+                                     &height, coordinate_type);
+      EXPECT_LT(0, x);
+      EXPECT_LT(previous_y, y);
+      EXPECT_LT(1, width);
+      EXPECT_EQ(previous_height, height);
+    }
+
+    for (int offset = last_line_start + 1; offset < n_characters; ++offset) {
+      testing::Message message;
+      message << "While checking at offset " << offset;
+      SCOPED_TRACE(message);
+
+      previous_x = x;
+      previous_y = y;
+
+      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
+                                     coordinate_type);
+      EXPECT_LT(previous_x, x);
+      EXPECT_EQ(previous_y, y);
+      EXPECT_LT(1, width);
+      EXPECT_EQ(previous_height, height);
+    }
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/accessibility_browsertest.cc b/content/browser/accessibility/accessibility_browsertest.cc
new file mode 100644
index 0000000..6f43f20
--- /dev/null
+++ b/content/browser/accessibility/accessibility_browsertest.cc
@@ -0,0 +1,126 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/accessibility/accessibility_browsertest.h"
+#include "base/macros.h"
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/accessibility_browser_test_utils.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "net/base/escape.h"
+
+namespace content {
+
+constexpr char kInputContents[] =
+    "Moz/5.0 (ST 6.x; WWW33) "
+    "WebKit  \"KHTML, like\".";
+constexpr char kTextareaContents[] =
+    "Moz/5.0 (ST 6.x; WWW33)\n"
+    "WebKit \n\"KHTML, like\".";
+
+gfx::NativeViewAccessible AccessibilityBrowserTest::GetRendererAccessible() {
+  content::WebContents* web_contents = shell()->web_contents();
+  return web_contents->GetRenderWidgetHostView()->GetNativeViewAccessible();
+}
+
+void AccessibilityBrowserTest::ExecuteScript(const base::string16& script) {
+  shell()->web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+      script, base::NullCallback());
+}
+
+void AccessibilityBrowserTest::LoadInitialAccessibilityTreeFromHtml(
+    const std::string& html,
+    ui::AXMode accessibility_mode) {
+  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+                                         accessibility_mode,
+                                         ax::mojom::Event::kLoadComplete);
+  GURL html_data_url("data:text/html," +
+                     net::EscapeQueryParamValue(html, false));
+  NavigateToURL(shell(), html_data_url);
+  waiter.WaitForNotification();
+}
+
+void AccessibilityBrowserTest::LoadInputField() {
+  LoadInitialAccessibilityTreeFromHtml(std::string(
+                                           R"HTML(<!DOCTYPE html>
+          <html>
+          <body>
+            <form>
+              <label for="textField">Browser name:</label>
+              <input type="text" id="textField" name="name" value=")HTML") +
+                                       net::EscapeForHTML(kInputContents) +
+                                       std::string(R"HTML(">
+            </form>
+          </body>
+          </html>)HTML"));
+}
+
+void AccessibilityBrowserTest::LoadTextareaField() {
+  LoadInitialAccessibilityTreeFromHtml(std::string(R"HTML(<!DOCTYPE html>
+      <html>
+      <body>
+                    <textarea rows="3" cols="60">)HTML") +
+                                       net::EscapeForHTML(kTextareaContents) +
+                                       std::string(R"HTML(</textarea>
+          </body>
+          </html>)HTML"));
+}
+
+void AccessibilityBrowserTest::LoadSampleParagraph(
+    ui::AXMode accessibility_mode) {
+  LoadInitialAccessibilityTreeFromHtml(
+      R"HTML(<!DOCTYPE html>
+      <html>
+      <body>
+          <p><b>Game theory</b> is "the study of
+              <a href="" title="Mathematical model">mathematical models</a>
+              of conflict and<br>cooperation between intelligent rational
+              decision-makers."
+          </p>
+      </body>
+      </html>)HTML",
+      accessibility_mode);
+}
+
+// Loads a page with a content editable whose text overflows its height.
+// Places the caret at the beginning of the editable's last line but doesn't
+// scroll the editable.
+void AccessibilityBrowserTest::LoadSampleParagraphInScrollableEditable() {
+  LoadInitialAccessibilityTreeFromHtml(
+      R"HTML(<p contenteditable="true"
+          style="height: 30px; overflow: scroll;">
+          hello<br><br><br>hello
+      </p>)HTML");
+
+  AccessibilityNotificationWaiter selection_waiter(
+      shell()->web_contents(), ui::kAXModeComplete,
+      ax::mojom::Event::kTextSelectionChanged);
+  ExecuteScript(base::UTF8ToUTF16(
+      "let selection=document.getSelection();"
+      "let range=document.createRange();"
+      "let editable=document.querySelector('p[contenteditable=\"true\"]');"
+      "editable.focus();"
+      "range.setStart(editable.lastChild, 0);"
+      "range.setEnd(editable.lastChild, 0);"
+      "selection.removeAllRanges();"
+      "selection.addRange(range);"));
+  selection_waiter.WaitForNotification();
+}
+
+// static
+std::string AccessibilityBrowserTest::InputContentsString() {
+  return kInputContents;
+}
+
+// static
+std::string AccessibilityBrowserTest::TextAreaContentsString() {
+  return kTextareaContents;
+}
+
+}  // namespace content
diff --git a/content/browser/accessibility/accessibility_browsertest.h b/content/browser/accessibility/accessibility_browsertest.h
new file mode 100644
index 0000000..56a7392
--- /dev/null
+++ b/content/browser/accessibility/accessibility_browsertest.h
@@ -0,0 +1,43 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/macros.h"
+#include "content/public/test/content_browser_test.h"
+#include "ui/accessibility/ax_mode.h"
+#include "ui/gfx/native_widget_types.h"
+
+#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_BROWSERTEST_H_
+#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_BROWSERTEST_H_
+
+namespace content {
+
+class AccessibilityBrowserTest : public ContentBrowserTest {
+ public:
+  AccessibilityBrowserTest() = default;
+  ~AccessibilityBrowserTest() override = default;
+
+ protected:
+  gfx::NativeViewAccessible GetRendererAccessible();
+  void ExecuteScript(const base::string16& script);
+  void LoadInitialAccessibilityTreeFromHtml(
+      const std::string& html,
+      ui::AXMode accessibility_mode = ui::kAXModeComplete);
+
+  void LoadInputField();
+  void LoadTextareaField();
+  void LoadSampleParagraph(ui::AXMode accessibility_mode = ui::kAXModeComplete);
+  void LoadSampleParagraphInScrollableEditable();
+
+  static std::string InputContentsString();
+  static std::string TextAreaContentsString();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AccessibilityBrowserTest);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_BROWSERTEST_H_
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index 9814367..5f444cea 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -20,6 +20,7 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/win/scoped_bstr.h"
 #include "base/win/scoped_variant.h"
+#include "content/browser/accessibility/accessibility_browsertest.h"
 #include "content/browser/accessibility/accessibility_event_recorder.h"
 #include "content/browser/accessibility/accessibility_tree_formatter.h"
 #include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
@@ -34,7 +35,6 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
-#include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "content/test/accessibility_browser_test_utils.h"
@@ -51,30 +51,16 @@
 
 namespace {
 
-constexpr char kInputContents[] =
-    "Moz/5.0 (ST 6.x; WWW33) "
-    "WebKit  \"KHTML, like\".";
-constexpr char kTextareaContents[] =
-    "Moz/5.0 (ST 6.x; WWW33)\n"
-    "WebKit \n\"KHTML, like\".";
-constexpr LONG kContentsLength =
-    static_cast<LONG>((sizeof(kInputContents) - 1) / sizeof(char));
-
 // AccessibilityWinBrowserTest ------------------------------------------------
 
-class AccessibilityWinBrowserTest : public ContentBrowserTest {
+class AccessibilityWinBrowserTest : public AccessibilityBrowserTest {
  public:
   AccessibilityWinBrowserTest();
   ~AccessibilityWinBrowserTest() override;
 
  protected:
   class AccessibleChecker;
-  void LoadInitialAccessibilityTreeFromHtml(
-      const std::string& html,
-      ui::AXMode accessibility_mode = ui::kAXModeComplete);
-  IAccessible* GetRendererAccessible();
   base::string16 PrintAXTree() const;
-  void ExecuteScript(const std::wstring& script);
   void SetUpInputField(Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
   void SetUpScrollableInputField(
       Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
@@ -97,8 +83,7 @@
       Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
       ui::AXMode accessibility_mode = ui::kAXModeComplete);
   void SetUpSampleParagraphInScrollableEditable(
-      Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
-      ui::AXMode accessibility_mode = ui::kAXModeComplete);
+      Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text);
   BrowserAccessibility* FindNode(ax::mojom::Role role,
                                  const std::string& name_or_value);
   BrowserAccessibilityManager* GetManager();
@@ -136,18 +121,6 @@
 
 AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() {}
 
-void AccessibilityWinBrowserTest::LoadInitialAccessibilityTreeFromHtml(
-    const std::string& html,
-    ui::AXMode accessibility_mode) {
-  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
-                                         accessibility_mode,
-                                         ax::mojom::Event::kLoadComplete);
-  GURL html_data_url("data:text/html," +
-                     net::EscapeQueryParamValue(html, false));
-  NavigateToURL(shell(), html_data_url);
-  waiter.WaitForNotification();
-}
-
 base::string16 AccessibilityWinBrowserTest::PrintAXTree() const {
   std::unique_ptr<AccessibilityTreeFormatter> formatter(
       AccessibilityTreeFormatter::Create());
@@ -165,36 +138,12 @@
   return str;
 }
 
-// Retrieve the MSAA client accessibility object for the Render Widget Host View
-// of the selected tab.
-IAccessible* AccessibilityWinBrowserTest::GetRendererAccessible() {
-  content::WebContents* web_contents = shell()->web_contents();
-  return web_contents->GetRenderWidgetHostView()->GetNativeViewAccessible();
-}
-
-void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) {
-  shell()->web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
-      script, base::NullCallback());
-}
-
 // Loads a page with  an input text field and places sample text in it. Also,
 // places the caret before the last character.
 void AccessibilityWinBrowserTest::SetUpInputField(
     Microsoft::WRL::ComPtr<IAccessibleText>* input_text) {
   ASSERT_NE(nullptr, input_text);
-  LoadInitialAccessibilityTreeFromHtml(std::string(
-                                           R"HTML(<!DOCTYPE html>
-          <html>
-          <body>
-            <form>
-              <label for="textField">Browser name:</label>
-              <input type="text" id="textField" name="name" value=")HTML") +
-                                       net::EscapeForHTML(kInputContents) +
-                                       std::string(R"HTML(">
-            </form>
-          </body>
-          </html>)HTML"));
-
+  LoadInputField();
   SetUpInputFieldHelper(input_text);
 }
 
@@ -203,13 +152,13 @@
 void AccessibilityWinBrowserTest::SetUpScrollableInputField(
     Microsoft::WRL::ComPtr<IAccessibleText>* input_text) {
   ASSERT_NE(nullptr, input_text);
-  LoadInitialAccessibilityTreeFromHtml(std::string(
-                                           R"HTML(<!DOCTYPE html>
+  LoadInitialAccessibilityTreeFromHtml(
+      std::string(
+          R"HTML(<!DOCTYPE html>
           <html>
           <body>
             <input type="text" style="width: 150px;" value=")HTML") +
-                                       net::EscapeForHTML(kInputContents) +
-                                       std::string(R"HTML(">
+      net::EscapeForHTML(InputContentsString()) + std::string(R"HTML(">
           </body>
           </html>)HTML"));
 
@@ -315,8 +264,8 @@
   AccessibilityNotificationWaiter waiter(
       shell()->web_contents(), ui::kAXModeComplete,
       ax::mojom::Event::kTextSelectionChanged);
-  std::wstring caret_offset =
-      base::UTF16ToWide(base::NumberToString16(kContentsLength - 1));
+  std::wstring caret_offset = base::UTF16ToWide(
+      base::NumberToString16(InputContentsString().size() - 1));
   ExecuteScript(
       std::wstring(L"let textField = document.querySelector('input,textarea');"
                    L"textField.focus();"
@@ -332,14 +281,7 @@
 void AccessibilityWinBrowserTest::SetUpTextareaField(
     Microsoft::WRL::ComPtr<IAccessibleText>* textarea_text) {
   ASSERT_NE(nullptr, textarea_text);
-  LoadInitialAccessibilityTreeFromHtml(std::string(R"HTML(<!DOCTYPE html>
-      <html>
-      <body>
-                    <textarea rows="3" cols="60">)HTML") +
-                                       net::EscapeForHTML(kTextareaContents) +
-                                       std::string(R"HTML(</textarea>
-          </body>
-          </html>)HTML"));
+  LoadTextareaField();
 
   // Retrieve the IAccessible interface for the web page.
   Microsoft::WRL::ComPtr<IAccessible> document(GetRendererAccessible());
@@ -373,8 +315,8 @@
   AccessibilityNotificationWaiter waiter(
       shell()->web_contents(), ui::kAXModeComplete,
       ax::mojom::Event::kTextSelectionChanged);
-  std::wstring caret_offset =
-      base::UTF16ToWide(base::NumberToString16(kContentsLength - 1));
+  std::wstring caret_offset = base::UTF16ToWide(
+      base::NumberToString16(InputContentsString().size() - 1));
   ExecuteScript(
       std::wstring(L"var textField = document.querySelector('textarea');"
                    L"textField.focus();"
@@ -387,19 +329,7 @@
 void AccessibilityWinBrowserTest::SetUpSampleParagraph(
     Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
     ui::AXMode accessibility_mode) {
-  LoadInitialAccessibilityTreeFromHtml(
-      R"HTML(<!DOCTYPE html>
-      <html>
-      <body>
-        <p><b>Game theory</b> is "the study of
-            <a href="" title="Mathematical model">mathematical models</a>
-            of conflict and<br>cooperation between intelligent rational
-            decision-makers."
-        </p>
-      </body>
-      </html>)HTML",
-      accessibility_mode);
-
+  LoadSampleParagraph(accessibility_mode);
   SetUpSampleParagraphHelper(accessible_text);
 }
 
@@ -425,33 +355,9 @@
   SetUpSampleParagraphHelper(accessible_text);
 }
 
-// Loads a page with a content editable whose text overflows its height.
-// Places the caret at the beginning of the editable's last line but doesn't
-// scroll the editable.
 void AccessibilityWinBrowserTest::SetUpSampleParagraphInScrollableEditable(
-    Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
-    ui::AXMode accessibility_mode) {
-  LoadInitialAccessibilityTreeFromHtml(
-      R"HTML(<p contenteditable="true"
-          style="height: 30px; overflow: scroll;">
-          hello<br><br><br>hello
-      </p>)HTML",
-      accessibility_mode);
-
-  AccessibilityNotificationWaiter selection_waiter(
-      shell()->web_contents(), ui::kAXModeComplete,
-      ax::mojom::Event::kTextSelectionChanged);
-  ExecuteScript(
-      L"let selection=document.getSelection();"
-      L"let range=document.createRange();"
-      L"let editable=document.querySelector('p[contenteditable=\"true\"]');"
-      L"editable.focus();"
-      L"range.setStart(editable.lastChild, 0);"
-      L"range.setEnd(editable.lastChild, 0);"
-      L"selection.removeAllRanges();"
-      L"selection.addRange(range);");
-  selection_waiter.WaitForNotification();
-
+    Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text) {
+  LoadSampleParagraphInScrollableEditable();
   SetUpSampleParagraphHelper(accessible_text);
 }
 
@@ -1432,13 +1338,14 @@
   Microsoft::WRL::ComPtr<IAccessibleText> input_text;
   SetUpScrollableInputField(&input_text);
 
+  int contents_string_length = int{InputContentsString().size()};
   constexpr LONG visible_characters_start = 21;
   LONG n_characters;
   ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
-  ASSERT_EQ(kContentsLength, n_characters);
+  ASSERT_EQ(contents_string_length, n_characters);
   LONG caret_offset;
   ASSERT_HRESULT_SUCCEEDED(input_text->get_caretOffset(&caret_offset));
-  ASSERT_EQ(kContentsLength - 1, caret_offset);
+  ASSERT_EQ(contents_string_length - 1, caret_offset);
 
   LONG x, y, width, height;
   LONG previous_x, previous_y, previous_height;
@@ -1938,7 +1845,7 @@
   LONG caret_offset = 0;
   HRESULT hr = input_text->get_caretOffset(&caret_offset);
   EXPECT_EQ(S_OK, hr);
-  EXPECT_EQ(kContentsLength - 1, caret_offset);
+  EXPECT_EQ(static_cast<LONG>(InputContentsString().size() - 1), caret_offset);
 
   AccessibilityNotificationWaiter waiter(
       shell()->web_contents(), ui::kAXModeComplete,
@@ -1961,7 +1868,7 @@
   LONG caret_offset = 0;
   HRESULT hr = textarea_text->get_caretOffset(&caret_offset);
   EXPECT_EQ(S_OK, hr);
-  EXPECT_EQ(kContentsLength - 1, caret_offset);
+  EXPECT_EQ(static_cast<LONG>(InputContentsString().size() - 1), caret_offset);
 
   AccessibilityNotificationWaiter waiter(
       shell()->web_contents(), ui::kAXModeComplete,
@@ -1990,8 +1897,9 @@
   AccessibilityNotificationWaiter waiter(
       shell()->web_contents(), ui::kAXModeComplete,
       ax::mojom::Event::kTextSelectionChanged);
+  int contents_string_length = int{InputContentsString().size()};
   start_offset = 0;
-  end_offset = kContentsLength;
+  end_offset = contents_string_length;
   EXPECT_HRESULT_FAILED(input_text->setSelection(1, start_offset, end_offset));
   EXPECT_HRESULT_SUCCEEDED(
       input_text->setSelection(0, start_offset, end_offset));
@@ -2000,9 +1908,9 @@
   hr = input_text->get_selection(0, &start_offset, &end_offset);
   EXPECT_EQ(S_OK, hr);
   EXPECT_EQ(0, start_offset);
-  EXPECT_EQ(kContentsLength, end_offset);
+  EXPECT_EQ(contents_string_length, end_offset);
 
-  start_offset = kContentsLength;
+  start_offset = contents_string_length;
   end_offset = 1;
   EXPECT_HRESULT_SUCCEEDED(
       input_text->setSelection(0, start_offset, end_offset));
@@ -2012,7 +1920,7 @@
   EXPECT_EQ(S_OK, hr);
   // Start and end offsets are always swapped to be in ascending order.
   EXPECT_EQ(1, start_offset);
-  EXPECT_EQ(kContentsLength, end_offset);
+  EXPECT_EQ(contents_string_length, end_offset);
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
@@ -2025,16 +1933,17 @@
   LONG n_ranges = 1;
   IA2Range* ranges =
       reinterpret_cast<IA2Range*>(CoTaskMemAlloc(sizeof(IA2Range)));
+  int contents_string_length = int{InputContentsString().size()};
   ranges[0].anchor = ax_input.Get();
   ranges[0].anchorOffset = -1;
   ranges[0].active = ax_input.Get();
-  ranges[0].activeOffset = kContentsLength;
+  ranges[0].activeOffset = contents_string_length;
   EXPECT_HRESULT_FAILED(ax_input->setSelectionRanges(n_ranges, ranges));
   ranges[0].anchorOffset = 0;
-  ranges[0].activeOffset = kContentsLength + 1;
+  ranges[0].activeOffset = contents_string_length + 1;
   EXPECT_HRESULT_FAILED(ax_input->setSelectionRanges(n_ranges, ranges));
 
-  ranges[0].activeOffset = kContentsLength;
+  ranges[0].activeOffset = contents_string_length;
   AccessibilityNotificationWaiter waiter(
       shell()->web_contents(), ui::kAXModeComplete,
       ax::mojom::Event::kTextSelectionChanged);
@@ -2051,13 +1960,13 @@
   EXPECT_EQ(ax_input.Get(), ranges[0].anchor);
   EXPECT_EQ(0, ranges[0].anchorOffset);
   EXPECT_EQ(ax_input.Get(), ranges[0].active);
-  EXPECT_EQ(kContentsLength, ranges[0].activeOffset);
+  EXPECT_EQ(contents_string_length, ranges[0].activeOffset);
 
   n_ranges = 1;
   ranges =
       reinterpret_cast<IA2Range*>(CoTaskMemRealloc(ranges, sizeof(IA2Range)));
   ranges[0].anchor = ax_input.Get();
-  ranges[0].anchorOffset = kContentsLength;
+  ranges[0].anchorOffset = contents_string_length;
   ranges[0].active = ax_input.Get();
   ranges[0].activeOffset = 1;
   EXPECT_HRESULT_SUCCEEDED(ax_input->setSelectionRanges(n_ranges, ranges));
@@ -2071,7 +1980,7 @@
   EXPECT_EQ(1, n_ranges);
   ASSERT_NE(nullptr, ranges);
   EXPECT_EQ(ax_input.Get(), ranges[0].anchor);
-  EXPECT_EQ(kContentsLength, ranges[0].anchorOffset);
+  EXPECT_EQ(contents_string_length, ranges[0].anchorOffset);
   EXPECT_EQ(ax_input.Get(), ranges[0].active);
   EXPECT_EQ(1, ranges[0].activeOffset);
   CoTaskMemFree(ranges);
@@ -2089,11 +1998,12 @@
   // There is no selection, just a caret.
   EXPECT_EQ(E_INVALIDARG, hr);
 
+  int contents_string_length = int{InputContentsString().size()};
   AccessibilityNotificationWaiter waiter(
       shell()->web_contents(), ui::kAXModeComplete,
       ax::mojom::Event::kTextSelectionChanged);
   start_offset = 0;
-  end_offset = kContentsLength;
+  end_offset = contents_string_length;
   EXPECT_HRESULT_FAILED(
       textarea_text->setSelection(1, start_offset, end_offset));
   EXPECT_HRESULT_SUCCEEDED(
@@ -2103,9 +2013,9 @@
   hr = textarea_text->get_selection(0, &start_offset, &end_offset);
   EXPECT_EQ(S_OK, hr);
   EXPECT_EQ(0, start_offset);
-  EXPECT_EQ(kContentsLength, end_offset);
+  EXPECT_EQ(contents_string_length, end_offset);
 
-  start_offset = kContentsLength - 1;
+  start_offset = contents_string_length - 1;
   end_offset = 0;
   EXPECT_HRESULT_SUCCEEDED(
       textarea_text->setSelection(0, start_offset, end_offset));
@@ -2115,7 +2025,7 @@
   EXPECT_EQ(S_OK, hr);
   // Start and end offsets are always swapped to be in ascending order.
   EXPECT_EQ(0, start_offset);
-  EXPECT_EQ(kContentsLength - 1, end_offset);
+  EXPECT_EQ(contents_string_length - 1, end_offset);
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
@@ -2125,19 +2035,20 @@
   Microsoft::WRL::ComPtr<IAccessible2_4> ax_textarea;
   ASSERT_HRESULT_SUCCEEDED(textarea_text.CopyTo(IID_PPV_ARGS(&ax_textarea)));
 
+  int contents_string_length = int{InputContentsString().size()};
   LONG n_ranges = 1;
   IA2Range* ranges =
       reinterpret_cast<IA2Range*>(CoTaskMemAlloc(sizeof(IA2Range)));
   ranges[0].anchor = ax_textarea.Get();
   ranges[0].anchorOffset = -1;
   ranges[0].active = ax_textarea.Get();
-  ranges[0].activeOffset = kContentsLength;
+  ranges[0].activeOffset = contents_string_length;
   EXPECT_HRESULT_FAILED(ax_textarea->setSelectionRanges(n_ranges, ranges));
   ranges[0].anchorOffset = 0;
-  ranges[0].activeOffset = kContentsLength + 1;
+  ranges[0].activeOffset = contents_string_length + 1;
   EXPECT_HRESULT_FAILED(ax_textarea->setSelectionRanges(n_ranges, ranges));
 
-  ranges[0].activeOffset = kContentsLength;
+  ranges[0].activeOffset = contents_string_length;
   AccessibilityNotificationWaiter waiter(
       shell()->web_contents(), ui::kAXModeComplete,
       ax::mojom::Event::kTextSelectionChanged);
@@ -2154,13 +2065,13 @@
   EXPECT_EQ(ax_textarea.Get(), ranges[0].anchor);
   EXPECT_EQ(0, ranges[0].anchorOffset);
   EXPECT_EQ(ax_textarea.Get(), ranges[0].active);
-  EXPECT_EQ(kContentsLength, ranges[0].activeOffset);
+  EXPECT_EQ(contents_string_length, ranges[0].activeOffset);
 
   n_ranges = 1;
   ranges =
       reinterpret_cast<IA2Range*>(CoTaskMemRealloc(ranges, sizeof(IA2Range)));
   ranges[0].anchor = ax_textarea.Get();
-  ranges[0].anchorOffset = kContentsLength - 1;
+  ranges[0].anchorOffset = contents_string_length - 1;
   ranges[0].active = ax_textarea.Get();
   ranges[0].activeOffset = 0;
   EXPECT_HRESULT_SUCCEEDED(ax_textarea->setSelectionRanges(n_ranges, ranges));
@@ -2174,7 +2085,7 @@
   EXPECT_EQ(1, n_ranges);
   ASSERT_NE(nullptr, ranges);
   EXPECT_EQ(ax_textarea.Get(), ranges[0].anchor);
-  EXPECT_EQ(kContentsLength - 1, ranges[0].anchorOffset);
+  EXPECT_EQ(contents_string_length - 1, ranges[0].anchorOffset);
   EXPECT_EQ(ax_textarea.Get(), ranges[0].active);
   EXPECT_EQ(0, ranges[0].activeOffset);
   CoTaskMemFree(ranges);
@@ -2279,7 +2190,8 @@
   EXPECT_EQ(1, n_ranges);
   ASSERT_NE(nullptr, ranges);
   EXPECT_EQ(ax_paragraph.Get(), ranges[0].anchor);
-  EXPECT_EQ(kContentsLength - 1, ranges[0].anchorOffset);
+  EXPECT_EQ(static_cast<LONG>(InputContentsString().size() - 1),
+            ranges[0].anchorOffset);
   EXPECT_EQ(ax_paragraph.Get(), ranges[0].active);
   EXPECT_EQ(0, ranges[0].activeOffset);
   CoTaskMemFree(ranges);
@@ -2305,7 +2217,7 @@
   EXPECT_EQ(0, start_offset);
   EXPECT_EQ(0, end_offset);
   EXPECT_EQ(nullptr, static_cast<BSTR>(text));
-  invalid_offset = kContentsLength + 1;
+  invalid_offset = InputContentsString().size() + 1;
   hr = input_text->get_textAtOffset(invalid_offset, IA2_TEXT_BOUNDARY_WORD,
                                     &start_offset, &end_offset, text.Receive());
   EXPECT_EQ(E_INVALIDARG, hr);
@@ -2315,7 +2227,7 @@
 
   // According to the IA2 Spec, only line boundaries should succeed when
   // the offset is one past the end of the text.
-  invalid_offset = kContentsLength;
+  invalid_offset = InputContentsString().size();
   hr = input_text->get_textAtOffset(invalid_offset, IA2_TEXT_BOUNDARY_CHAR,
                                     &start_offset, &end_offset, text.Receive());
   EXPECT_EQ(S_FALSE, hr);
@@ -2393,7 +2305,7 @@
   EXPECT_EQ(0, start_offset);
   EXPECT_EQ(0, end_offset);
   EXPECT_EQ(nullptr, static_cast<BSTR>(text));
-  invalid_offset = kContentsLength + 1;
+  invalid_offset = InputContentsString().size() + 1;
   hr = textarea_text->get_textAtOffset(invalid_offset, IA2_TEXT_BOUNDARY_WORD,
                                        &start_offset, &end_offset,
                                        text.Receive());
@@ -2404,7 +2316,7 @@
 
   // According to the IA2 Spec, only line boundaries should succeed when
   // the offset is one past the end of the text.
-  invalid_offset = kContentsLength;
+  invalid_offset = InputContentsString().size();
   hr = textarea_text->get_textAtOffset(invalid_offset, IA2_TEXT_BOUNDARY_CHAR,
                                        &start_offset, &end_offset,
                                        text.Receive());
@@ -2470,8 +2382,10 @@
                        TestTextAtOffsetWithBoundaryCharacter) {
   Microsoft::WRL::ComPtr<IAccessibleText> input_text;
   SetUpInputField(&input_text);
-  for (LONG offset = 0; offset < kContentsLength; ++offset) {
-    std::wstring expected_text(1, kInputContents[offset]);
+
+  int contents_string_length = int{InputContentsString().size()};
+  for (LONG offset = 0; offset < contents_string_length; ++offset) {
+    std::wstring expected_text(1, InputContentsString()[offset]);
     LONG expected_start_offset = offset;
     LONG expected_end_offset = offset + 1;
     CheckTextAtOffset(input_text, offset, IA2_TEXT_BOUNDARY_CHAR,
@@ -2479,8 +2393,8 @@
                       expected_text);
   }
 
-  for (LONG offset = kContentsLength - 1; offset >= 0; --offset) {
-    std::wstring expected_text(1, kInputContents[offset]);
+  for (LONG offset = contents_string_length - 1; offset >= 0; --offset) {
+    std::wstring expected_text(1, InputContentsString()[offset]);
     LONG expected_start_offset = offset;
     LONG expected_end_offset = offset + 1;
     CheckTextAtOffset(input_text, offset, IA2_TEXT_BOUNDARY_CHAR,
@@ -2489,15 +2403,17 @@
   }
 
   CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET, IA2_TEXT_BOUNDARY_CHAR,
-                    kContentsLength - 1, kContentsLength, L".");
+                    contents_string_length - 1, contents_string_length, L".");
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                        TestMultiLineTextAtOffsetWithBoundaryCharacter) {
   Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
   SetUpTextareaField(&textarea_text);
-  for (LONG offset = 0; offset < kContentsLength; ++offset) {
-    std::wstring expected_text(1, kTextareaContents[offset]);
+
+  int contents_string_length = InputContentsString().size();
+  for (LONG offset = 0; offset < contents_string_length; ++offset) {
+    std::wstring expected_text(1, TextAreaContentsString()[offset]);
     LONG expected_start_offset = offset;
     LONG expected_end_offset = offset + 1;
     CheckTextAtOffset(textarea_text, offset, IA2_TEXT_BOUNDARY_CHAR,
@@ -2505,8 +2421,8 @@
                       expected_text);
   }
 
-  for (LONG offset = kContentsLength - 1; offset >= 0; --offset) {
-    std::wstring expected_text(1, kTextareaContents[offset]);
+  for (LONG offset = contents_string_length - 1; offset >= 0; --offset) {
+    std::wstring expected_text(1, TextAreaContentsString()[offset]);
     LONG expected_start_offset = offset;
     LONG expected_end_offset = offset + 1;
     CheckTextAtOffset(textarea_text, offset, IA2_TEXT_BOUNDARY_CHAR,
@@ -2515,8 +2431,8 @@
   }
 
   CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET,
-                    IA2_TEXT_BOUNDARY_CHAR, kContentsLength - 1,
-                    kContentsLength, L".");
+                    IA2_TEXT_BOUNDARY_CHAR, contents_string_length - 1,
+                    contents_string_length, L".");
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
@@ -2566,14 +2482,15 @@
   CheckTextAtOffset(input_text, 38, IA2_TEXT_BOUNDARY_WORD, 33, 40, L"KHTML, ");
 
   // Trailing final punctuation should be part of the last word.
-  CheckTextAtOffset(input_text, 41, IA2_TEXT_BOUNDARY_WORD, 40, kContentsLength,
-                    L"like\".");
-  CheckTextAtOffset(input_text, 45, IA2_TEXT_BOUNDARY_WORD, 40, kContentsLength,
-                    L"like\".");
+  int contents_string_length = int{InputContentsString().size()};
+  CheckTextAtOffset(input_text, 41, IA2_TEXT_BOUNDARY_WORD, 40,
+                    contents_string_length, L"like\".");
+  CheckTextAtOffset(input_text, 45, IA2_TEXT_BOUNDARY_WORD, 40,
+                    contents_string_length, L"like\".");
 
   // Test special offsets.
   CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET, IA2_TEXT_BOUNDARY_WORD,
-                    40, kContentsLength, L"like\".");
+                    40, contents_string_length, L"like\".");
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
@@ -2627,14 +2544,16 @@
                     L"KHTML, ");
 
   // Trailing final punctuation should be part of the last word.
+  int contents_string_length = int{InputContentsString().size()};
   CheckTextAtOffset(textarea_text, 41, IA2_TEXT_BOUNDARY_WORD, 40,
-                    kContentsLength, L"like\".");
+                    contents_string_length, L"like\".");
   CheckTextAtOffset(textarea_text, 45, IA2_TEXT_BOUNDARY_WORD, 40,
-                    kContentsLength, L"like\".");
+                    contents_string_length, L"like\".");
 
   // Test special offsets.
   CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET,
-                    IA2_TEXT_BOUNDARY_WORD, 40, kContentsLength, L"like\".");
+                    IA2_TEXT_BOUNDARY_WORD, 40, contents_string_length,
+                    L"like\".");
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
@@ -2713,14 +2632,18 @@
   SetUpInputField(&input_text);
 
   // Single line text fields should return the whole text.
-  CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_LINE, 0, kContentsLength,
-                    base::SysUTF8ToWide(kInputContents));
+  int contents_string_length = int{InputContentsString().size()};
+  CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_LINE, 0,
+                    contents_string_length,
+                    base::SysUTF8ToWide(InputContentsString()));
 
   // Test special offsets.
   CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_LINE,
-                    0, kContentsLength, base::SysUTF8ToWide(kInputContents));
+                    0, contents_string_length,
+                    base::SysUTF8ToWide(InputContentsString()));
   CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET, IA2_TEXT_BOUNDARY_LINE,
-                    0, kContentsLength, base::SysUTF8ToWide(kInputContents));
+                    0, contents_string_length,
+                    base::SysUTF8ToWide(InputContentsString()));
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
@@ -2736,19 +2659,21 @@
                     L"WebKit \n");
 
   // Last line does not have a trailing newline.
+  int contents_string_length = int{InputContentsString().size()};
   CheckTextAtOffset(textarea_text, 32, IA2_TEXT_BOUNDARY_LINE, 32,
-                    kContentsLength, L"\"KHTML, like\".");
+                    contents_string_length, L"\"KHTML, like\".");
 
   // An offset one past the last character should return the last line.
-  CheckTextAtOffset(textarea_text, kContentsLength, IA2_TEXT_BOUNDARY_LINE, 32,
-                    kContentsLength, L"\"KHTML, like\".");
+  CheckTextAtOffset(textarea_text, contents_string_length,
+                    IA2_TEXT_BOUNDARY_LINE, 32, contents_string_length,
+                    L"\"KHTML, like\".");
 
   // Test special offsets.
   CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_LENGTH,
-                    IA2_TEXT_BOUNDARY_LINE, 32, kContentsLength,
+                    IA2_TEXT_BOUNDARY_LINE, 32, contents_string_length,
                     L"\"KHTML, like\".");
   CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET,
-                    IA2_TEXT_BOUNDARY_LINE, 32, kContentsLength,
+                    IA2_TEXT_BOUNDARY_LINE, 32, contents_string_length,
                     L"\"KHTML, like\".");
 }
 
@@ -2785,8 +2710,9 @@
   Microsoft::WRL::ComPtr<IAccessibleText> input_text;
   SetUpInputField(&input_text);
 
-  CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_ALL, 0, kContentsLength,
-                    base::SysUTF8ToWide(kInputContents));
+  CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_ALL, 0,
+                    InputContentsString().size(),
+                    base::SysUTF8ToWide(InputContentsString()));
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
@@ -2794,8 +2720,9 @@
   Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
   SetUpTextareaField(&textarea_text);
 
-  CheckTextAtOffset(textarea_text, kContentsLength - 1, IA2_TEXT_BOUNDARY_ALL,
-                    0, kContentsLength, base::SysUTF8ToWide(kTextareaContents));
+  CheckTextAtOffset(textarea_text, InputContentsString().size() - 1,
+                    IA2_TEXT_BOUNDARY_ALL, 0, InputContentsString().size(),
+                    base::SysUTF8ToWide(TextAreaContentsString()));
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestIAccessibleAction) {
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 1750b4e..1d7c18b 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -364,6 +364,36 @@
   return RelativeToAbsoluteBounds(gfx::RectF(), false, offscreen, clip_bounds);
 }
 
+gfx::Rect BrowserAccessibility::GetTextRangeBoundsRect(
+    int start_offset,
+    int end_offset,
+    ui::AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem
+        coordinate_system) const {
+  const base::string16& text_str = GetText();
+  if (start_offset == end_offset)
+    return gfx::Rect();
+
+  if (start_offset > end_offset)
+    std::swap(start_offset, end_offset);
+
+  if (start_offset < 0 || start_offset >= static_cast<int>(text_str.size()))
+    return gfx::Rect();
+  if (end_offset < 0 || end_offset > static_cast<int>(text_str.size()))
+    return gfx::Rect();
+
+  switch (coordinate_system) {
+    case ui::AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem::Screen:
+      return GetScreenBoundsForRange(start_offset, end_offset - start_offset);
+    case ui::AXPlatformNodeDelegate::Window:
+      return GetPageBoundsForRange(start_offset, end_offset - start_offset);
+    case ui::AXPlatformNodeDelegate::Parent:
+      if (!PlatformGetParent())
+        return gfx::Rect();
+      return GetPageBoundsForRange(start_offset, end_offset - start_offset) -
+             PlatformGetParent()->GetPageBoundsRect().OffsetFromOrigin();
+  }
+}
+
 gfx::Rect BrowserAccessibility::GetPageBoundsForRange(int start,
                                                       int len,
                                                       bool clipped) const {
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index e58caa5..b4b6626 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -360,6 +360,11 @@
   gfx::Rect GetScreenBoundsForRange(int start,
                                     int len,
                                     bool clipped = false) const override;
+  gfx::Rect GetTextRangeBoundsRect(
+      int start_offset,
+      int end_offset,
+      ui::AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem
+          coordinate_system) const override;
   gfx::NativeViewAccessible HitTestSync(int x, int y) override;
   gfx::NativeViewAccessible GetFocus() override;
   ui::AXPlatformNode* GetFromNodeID(int32_t id) override;
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index 7c523d7..d2506a0 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -16,6 +16,7 @@
 #include "content/browser/accessibility/browser_accessibility.h"
 #include "content/common/accessibility_messages.h"
 #include "content/public/common/use_zoom_for_dsf_policy.h"
+#include "ui/accessibility/ax_language_info.h"
 #include "ui/accessibility/ax_node_position.h"
 #include "ui/accessibility/ax_tree_data.h"
 #include "ui/accessibility/ax_tree_manager_map.h"
@@ -428,6 +429,16 @@
     if (!event_target || !event_target->CanFireEvents())
       continue;
 
+    // Perform initial run of language detection if we have seen a LOAD_COMPLETE
+    // event.
+    // TODO(chrishall): we will want to run this more often for dynamic pages.
+    if (targeted_event.event_params.event ==
+        ui::AXEventGenerator::Event::LOAD_COMPLETE) {
+      DetectLanguageForSubtree(tree_->root(), tree_.get());
+      if (!LabelLanguageForSubtree(tree_->root(), tree_.get()))
+        LOG(FATAL) << "Language detection failed at step: Label";
+    }
+
     FireGeneratedEvent(targeted_event.event_params.event, event_target);
   }
   event_generator_.ClearEvents();
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 9c6b5c959..7622e76c 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -1953,7 +1953,7 @@
 
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                        LanguageDetectionLangDetectionBasic) {
-  RunLanguageDetectionTest(FILE_PATH_LITERAL("lang-detection-basic.html"));
+  RunLanguageDetectionTest(FILE_PATH_LITERAL("basic.html"));
 }
 
 //
diff --git a/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc b/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
index 19758f7..0968b2b 100644
--- a/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
+++ b/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
@@ -108,6 +108,7 @@
 class FontUniqueNameBrowserTest : public DevToolsProtocolTest {
  public:
   void SetUpCommandLine(base::CommandLine* command_line) override {
+    DevToolsProtocolTest::SetUpCommandLine(command_line);
     feature_list_.InitAndEnableFeature(features::kFontSrcLocalMatching);
   }
 
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc
index ea4a842..704f321 100644
--- a/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -341,9 +341,7 @@
     urls[i] = GURL(base::StringPrintf("http://www.a.com/%d", i));
   }
 
-  main_test_rfh()->SendRendererInitiatedNavigationRequest(urls[0], true);
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(0, true, urls[0]);
+  NavigationSimulator::NavigateAndCommitFromDocument(urls[0], main_test_rfh());
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
   EXPECT_EQ(urls[0], controller.GetVisibleEntry()->GetVirtualURL());
@@ -352,9 +350,8 @@
   EXPECT_FALSE(controller.CanGoToOffset(1));
 
   for (int i = 1; i <= 4; ++i) {
-    main_test_rfh()->SendRendererInitiatedNavigationRequest(urls[i], true);
-    main_test_rfh()->PrepareForCommit();
-    main_test_rfh()->SendNavigate(0, true, urls[i]);
+    NavigationSimulator::NavigateAndCommitFromDocument(urls[i],
+                                                       main_test_rfh());
     EXPECT_EQ(1U, navigation_entry_committed_counter_);
     navigation_entry_committed_counter_ = 0;
     EXPECT_EQ(urls[i], controller.GetVisibleEntry()->GetVirtualURL());
@@ -385,15 +382,13 @@
 
   for (int test = 0; test < NUM_TESTS; ++test) {
     int offset = test_offsets[test];
-    controller.GoToOffset(offset);
-    int entry_id = controller.GetPendingEntry()->GetUniqueID();
+    auto navigation =
+        NavigationSimulator::CreateHistoryNavigation(offset, contents());
+    navigation->Start();
     url_index += offset;
     // Check that the GoToOffset will land on the expected page.
     EXPECT_EQ(urls[url_index], controller.GetPendingEntry()->GetVirtualURL());
-    main_test_rfh()->PrepareForCommit();
-    main_test_rfh()->SendNavigateWithTransition(
-        entry_id, false, urls[url_index],
-        controller.GetPendingEntry()->GetTransitionType());
+    navigation->Commit();
     EXPECT_EQ(1U, navigation_entry_committed_counter_);
     navigation_entry_committed_counter_ = 0;
     // Check that we can go to any valid offset into the history.
@@ -479,8 +474,8 @@
   EXPECT_EQ(0U, navigation_entry_changed_counter_);
   EXPECT_EQ(0U, navigation_list_pruned_counter_);
 
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url1);
+  auto navigation1 = NavigationSimulator::CreateFromPending(contents());
+  navigation1->Commit();
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
@@ -516,10 +511,8 @@
 
   EXPECT_TRUE(controller.GetPendingEntry()->GetTimestamp().is_null());
 
-  // Simulate the beforeunload ack for the cross-site transition, and then the
-  // commit.
-  main_test_rfh()->PrepareForCommit();
-  contents()->GetPendingMainFrame()->SendNavigate(entry_id, true, url2);
+  auto navigation2 = NavigationSimulator::CreateFromPending(contents());
+  navigation2->Commit();
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
@@ -935,20 +928,12 @@
 
   // First make some history.
   const GURL kExistingURL1("http://foo/eh");
-  controller.LoadURL(
-      kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, kExistingURL1);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kExistingURL1);
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
   const GURL kExistingURL2("http://foo/bee");
-  controller.LoadURL(
-      kExistingURL2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, kExistingURL2);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kExistingURL2);
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
@@ -962,9 +947,7 @@
 
   // Before that commits, do a new navigation.
   const GURL kNewURL("http://foo/see");
-  main_test_rfh()->SendRendererInitiatedNavigationRequest(kNewURL, true);
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(0, true, kNewURL);
+  NavigationSimulator::NavigateAndCommitFromDocument(kNewURL, main_test_rfh());
 
   // There should no longer be any pending entry, and the new navigation we
   // just made should be committed.
@@ -1242,37 +1225,26 @@
   const GURL url2("http://foo2");
 
   // Navigate to a first, unprivileged URL.
-  controller.LoadURL(
-      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  EXPECT_EQ(NavigationEntryImpl::kInvalidBindings,
-            controller.GetPendingEntry()->bindings());
-  int entry1_id = controller.GetPendingEntry()->GetUniqueID();
-
-  // Commit.
-  TestRenderFrameHost* orig_rfh = contents()->GetMainFrame();
-  orig_rfh->PrepareForCommit();
-  orig_rfh->SendNavigate(entry1_id, true, url1);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
   EXPECT_EQ(controller.GetEntryCount(), 1);
   EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
   EXPECT_EQ(0, controller.GetLastCommittedEntry()->bindings());
-  entry1_id = controller.GetLastCommittedEntry()->GetUniqueID();
 
   // Manually increase the number of active frames in the SiteInstance
   // that orig_rfh belongs to, to prevent it from being destroyed when
   // it gets swapped out, so that we can reuse orig_rfh when the
   // controller goes back.
-  orig_rfh->GetSiteInstance()->IncrementActiveFrameCount();
+  main_test_rfh()->GetSiteInstance()->IncrementActiveFrameCount();
 
   // Navigate to a second URL, simulate the beforeunload ack for the cross-site
-  // transition, and set bindings on the pending RenderViewHost to simulate a
+  // transition, and set bindings on the pending RenderFrameHost to simulate a
   // privileged url.
-  controller.LoadURL(
-      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
-  orig_rfh->PrepareForCommit();
+  auto navigation =
+      NavigationSimulator::CreateBrowserInitiated(url2, contents());
+  navigation->ReadyToCommit();
   TestRenderFrameHost* new_rfh = contents()->GetPendingMainFrame();
   new_rfh->AllowBindings(BINDINGS_POLICY_WEB_UI);
-  new_rfh->SendNavigate(entry_id, true, url2);
+  navigation->Commit();
 
   // The second load should be committed, and bindings should be remembered.
   EXPECT_EQ(controller.GetEntryCount(), 2);
@@ -1281,11 +1253,7 @@
   EXPECT_EQ(1, controller.GetLastCommittedEntry()->bindings());
 
   // Going back, the first entry should still appear unprivileged.
-  controller.GoBack();
-  new_rfh->PrepareForCommit();
-  contents()->GetPendingMainFrame()->SendNavigateWithTransition(
-      entry1_id, false, url1,
-      controller.GetPendingEntry()->GetTransitionType());
+  NavigationSimulator::GoBack(contents());
   EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
   EXPECT_EQ(0, controller.GetLastCommittedEntry()->bindings());
 }
@@ -1349,24 +1317,17 @@
   const GURL url1("http://foo1");
   const GURL url2("http://foo2");
 
-  controller.LoadURL(
-      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url1);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
-  entry_id = controller.GetLastCommittedEntry()->GetUniqueID();
 
   controller.Reload(ReloadType::NORMAL, true);
   EXPECT_EQ(0U, navigation_entry_changed_counter_);
   EXPECT_EQ(0U, navigation_list_pruned_counter_);
 
-  main_test_rfh()->PrepareForCommitWithServerRedirect(url2);
-
-  TestRenderFrameHost* navigating_rfh = GetNavigatingRenderFrameHost();
-  navigating_rfh->SendNavigate(entry_id, false, url2);
-
+  auto reload = NavigationSimulator::CreateFromPending(contents());
+  reload->Redirect(url2);
+  reload->Commit();
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
@@ -1387,11 +1348,7 @@
   NavigationControllerImpl& controller = controller_impl();
 
   const GURL url1("http://foo1");
-  controller.LoadURL(
-      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url1);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
   ASSERT_TRUE(controller.GetVisibleEntry());
 
   // Make the entry believe its RenderProcessHost is a guest.
@@ -1537,9 +1494,9 @@
   NavigationControllerImpl& controller = controller_impl();
   const GURL url1("http://foo1");
   const GURL url2("http://foo2");
-  controller.LoadURL(
-      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
+  auto navigation =
+      NavigationSimulator::CreateBrowserInitiated(url1, contents());
+  navigation->Start();
 
   // Set up some redirect values.
   std::vector<GURL> redirects;
@@ -1553,9 +1510,8 @@
   EXPECT_EQ(url2, pending_entry->GetRedirectChain()[0]);
 
   // Normal navigation will preserve redirects in the committed entry.
-  main_test_rfh()->PrepareForCommitWithServerRedirect(url2);
-  main_test_rfh()->SendNavigateWithModificationCallback(
-      entry_id, true, url2, std::move(set_redirects_callback));
+  navigation->Redirect(url2);
+  navigation->Commit();
   NavigationEntryImpl* committed_entry = controller.GetLastCommittedEntry();
   ASSERT_EQ(1U, committed_entry->GetRedirectChain().size());
   EXPECT_EQ(url2, committed_entry->GetRedirectChain()[0]);
@@ -1569,24 +1525,24 @@
   const GURL url1("http://foo/1");
   const GURL url2("http://foo/2");
 
-  controller.LoadURL(url1, Referrer(), ui::PAGE_TRANSITION_TYPED,
-                     std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
+  auto navigation1 =
+      NavigationSimulator::CreateBrowserInitiated(url1, contents());
+  navigation1->Start();
   EXPECT_FALSE(controller.GetPendingEntry()->GetIsOverridingUserAgent());
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url1);
+  navigation1->Commit();
 
-  controller.LoadURL(url2, Referrer(), ui::PAGE_TRANSITION_TYPED,
-                     std::string());
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
+  auto navigation2 =
+      NavigationSimulator::CreateBrowserInitiated(url2, contents());
+  navigation2->Start();
   EXPECT_FALSE(controller.GetPendingEntry()->GetIsOverridingUserAgent());
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url2);
+  navigation2->Commit();
 
   // Simulate the behavior of "Request Desktop Site" being checked in
   // NavigationControllerAndroid::SetUseDesktopUserAgent.
   controller.GetVisibleEntry()->SetIsOverridingUserAgent(true);
   controller.Reload(ReloadType::ORIGINAL_REQUEST_URL, true);
+  auto reload = NavigationSimulator::CreateFromPending(contents());
+  reload->Commit();
   EXPECT_TRUE(controller.GetLastCommittedEntry()->GetIsOverridingUserAgent());
 
   // Test that OnWebkitPreferencesChanged is called when going back to propagate
@@ -1594,12 +1550,11 @@
   int change_counter = 0;
   test_rvh()->set_webkit_preferences_changed_counter(&change_counter);
 
-  controller.GoBack();
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
+  auto back_navigation =
+      NavigationSimulator::CreateHistoryNavigation(-1, contents());
+  back_navigation->Start();
   EXPECT_FALSE(controller.GetPendingEntry()->GetIsOverridingUserAgent());
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigateWithTransition(
-      entry_id, false, url1, controller.GetPendingEntry()->GetTransitionType());
+  back_navigation->Commit();
 
   EXPECT_EQ(1, change_counter);
 }
@@ -2608,11 +2563,7 @@
   // Load up to the max count, all entries should be there.
   for (url_index = 0; url_index < kMaxEntryCount; url_index++) {
     GURL url(base::StringPrintf("http://www.a.com/%d", url_index));
-    controller.LoadURL(
-        url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-    int entry_id = controller.GetPendingEntry()->GetUniqueID();
-    main_test_rfh()->PrepareForCommit();
-    main_test_rfh()->SendNavigate(entry_id, true, url);
+    NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
   }
 
   EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount);
@@ -2620,11 +2571,7 @@
 
   // Navigate some more.
   GURL url(base::StringPrintf("http://www.a.com/%d", url_index));
-  controller.LoadURL(
-      url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
   url_index++;
 
   // We should have got a pruned navigation.
@@ -2640,11 +2587,7 @@
   // More navigations.
   for (int i = 0; i < 3; i++) {
     url = GURL(base::StringPrintf("http://www.a.com/%d", url_index));
-    controller.LoadURL(
-        url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-    int entry_id = controller.GetPendingEntry()->GetUniqueID();
-    main_test_rfh()->PrepareForCommit();
-    main_test_rfh()->SendNavigate(entry_id, true, url);
+    NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
     url_index++;
   }
   EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount);
@@ -2837,31 +2780,11 @@
   const GURL pending_url("http://foo/pending");
   const GURL default_url("http://foo/default");
 
-  controller.LoadURL(
-      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url1);
-  controller.LoadURL(
-      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url2);
-  controller.LoadURL(
-      url3, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url3);
-  controller.LoadURL(
-      url4, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url4);
-  controller.LoadURL(
-      url5, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url5);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url2);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url3);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url4);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url5);
 
   // Try to remove the last entry.  Will fail because it is the current entry.
   EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1));
@@ -2870,15 +2793,14 @@
 
   // Go back, but don't commit yet. Check that we can't delete the current
   // and pending entries.
-  controller.GoBack();
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
+  auto back_navigation =
+      NavigationSimulator::CreateHistoryNavigation(-1, contents());
+  back_navigation->Start();
   EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1));
   EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 2));
 
   // Now commit and delete the last entry.
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigateWithTransition(
-      entry_id, false, url4, controller.GetPendingEntry()->GetTransitionType());
+  back_navigation->Commit();
   EXPECT_TRUE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1));
   EXPECT_EQ(4, controller.GetEntryCount());
   EXPECT_EQ(3, controller.GetLastCommittedEntryIndex());
@@ -2906,28 +2828,15 @@
   const GURL url3("http://foo/3");
   const GURL default_url("http://foo/default");
 
-  controller.LoadURL(
-      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url1);
-  controller.LoadURL(
-      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url2);
-  controller.LoadURL(
-      url3, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url3);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url2);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url3);
 
   // Go back, but don't commit yet. Check that we can't delete the current
   // and pending entries.
-  controller.GoBack();
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
-  ui::PageTransition entry_transition =
-      controller.GetPendingEntry()->GetTransitionType();
+  auto back_navigation =
+      NavigationSimulator::CreateHistoryNavigation(-1, contents());
+  back_navigation->Start();
   EXPECT_FALSE(controller.RemoveEntryAtIndex(2));
   EXPECT_FALSE(controller.RemoveEntryAtIndex(1));
 
@@ -2941,9 +2850,7 @@
   EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
 
   // Now commit and ensure we land on the right entry.
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigateWithTransition(entry_id, false, url2,
-                                              entry_transition);
+  back_navigation->Commit();
   EXPECT_EQ(2, controller.GetEntryCount());
   EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
   EXPECT_FALSE(controller.GetPendingEntry());
@@ -4414,9 +4321,9 @@
   NavigateAndCommit(url2);
 
   // Create a pending entry that is not in the entry list.
-  controller.LoadURL(
-      url3, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
+  auto navigation =
+      NavigationSimulator::CreateBrowserInitiated(url3, contents());
+  navigation->Start();
   EXPECT_TRUE(controller.GetPendingEntry());
   EXPECT_EQ(2, controller.GetEntryCount());
 
@@ -4432,8 +4339,7 @@
   EXPECT_EQ(1, controller.GetEntryCount());
 
   // Try to commit the pending entry.
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url3);
+  navigation->Commit();
   EXPECT_EQ(-1, controller.GetPendingEntryIndex());
   EXPECT_FALSE(controller.GetPendingEntry());
   EXPECT_EQ(2, controller.GetEntryCount());
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index 0f34eb4..0df214a9 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -592,7 +592,7 @@
   std::vector<FaviconURL> icons;
 
   // Navigate our first tab to a chrome url and then to the destination.
-  NavigateActiveAndCommit(kChromeURL);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kChromeURL);
   TestRenderFrameHost* ntp_rfh = contents()->GetMainFrame();
 
   // Send an update favicon message and make sure it works.
@@ -608,7 +608,10 @@
   ntp_rfh->GetSiteInstance()->IncrementActiveFrameCount();
 
   // Navigate to a cross-site URL (don't swap out to keep |ntp_rfh| alive).
-  NavigateActiveAndCommit(kDestUrl, true /* dont_swap_out */);
+  auto navigation =
+      NavigationSimulatorImpl::CreateBrowserInitiated(kDestUrl, contents());
+  navigation->set_drop_swap_out_ack(true);
+  navigation->Commit();
   TestRenderFrameHost* dest_rfh = contents()->GetMainFrame();
   ASSERT_TRUE(dest_rfh);
   EXPECT_NE(ntp_rfh, dest_rfh);
@@ -641,37 +644,35 @@
   std::vector<FaviconURL> icons;
 
   // Navigate our first tab to a chrome url and then to the destination.
-  NavigateActiveAndCommit(kChromeURL);
-  TestRenderFrameHost* rfh1 = contents()->GetMainFrame();
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kChromeURL);
+  TestRenderFrameHost* ntp_rfh = contents()->GetMainFrame();
 
   // Send an update favicon message and make sure it works.
   {
     PluginFaviconMessageObserver observer(contents());
-    EXPECT_TRUE(rfh1->OnMessageReceived(
-        FrameHostMsg_UpdateFaviconURL(rfh1->GetRoutingID(), icons)));
+    EXPECT_TRUE(ntp_rfh->OnMessageReceived(
+        FrameHostMsg_UpdateFaviconURL(ntp_rfh->GetRoutingID(), icons)));
     EXPECT_TRUE(observer.favicon_received());
   }
 
-  // Create one more frame in the same SiteInstance where |rfh1| exists so that
-  // it doesn't get deleted on navigation to another site.
-  rfh1->GetSiteInstance()->IncrementActiveFrameCount();
+  // Create one more frame in the same SiteInstance where |ntp_rfh| exists so
+  // that it doesn't get deleted on navigation to another site.
+  ntp_rfh->GetSiteInstance()->IncrementActiveFrameCount();
 
   // Navigate to a cross-site URL and commit the new page.
-  controller().LoadURL(
-      kDestUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
-  int entry_id = controller().GetPendingEntry()->GetUniqueID();
-  contents()->GetMainFrame()->PrepareForCommit();
-  TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
-  contents()->TestDidNavigate(rfh2, entry_id, true, kDestUrl,
-                              ui::PAGE_TRANSITION_TYPED);
-  EXPECT_FALSE(rfh1->is_active());
-  EXPECT_TRUE(rfh2->is_active());
+  auto navigation =
+      NavigationSimulatorImpl::CreateBrowserInitiated(kDestUrl, contents());
+  navigation->set_drop_swap_out_ack(true);
+  navigation->Commit();
+  TestRenderFrameHost* dest_rfh = contents()->GetMainFrame();
+  EXPECT_FALSE(ntp_rfh->is_active());
+  EXPECT_TRUE(dest_rfh->is_active());
 
   // The new RVH should be able to update its favicons.
   {
     PluginFaviconMessageObserver observer(contents());
-    EXPECT_TRUE(rfh2->OnMessageReceived(
-        FrameHostMsg_UpdateFaviconURL(rfh2->GetRoutingID(), icons)));
+    EXPECT_TRUE(dest_rfh->OnMessageReceived(
+        FrameHostMsg_UpdateFaviconURL(dest_rfh->GetRoutingID(), icons)));
     EXPECT_TRUE(observer.favicon_received());
   }
 
@@ -679,8 +680,8 @@
   // be ignored.
   {
     PluginFaviconMessageObserver observer(contents());
-    EXPECT_TRUE(rfh1->OnMessageReceived(
-        FrameHostMsg_UpdateFaviconURL(rfh1->GetRoutingID(), icons)));
+    EXPECT_TRUE(ntp_rfh->OnMessageReceived(
+        FrameHostMsg_UpdateFaviconURL(ntp_rfh->GetRoutingID(), icons)));
     EXPECT_FALSE(observer.favicon_received());
   }
 }
@@ -1182,26 +1183,19 @@
   // Now go back, but suppose the SwapOut_ACK isn't received.  This shouldn't
   // happen, but we have seen it when going back quickly across many entries
   // (http://crbug.com/93427).
-  contents()->GetController().GoBack();
-  EXPECT_TRUE(rfh2->is_waiting_for_beforeunload_ack());
-  contents()->GetMainFrame()->PrepareForCommit();
+  auto back_navigation1 =
+      NavigationSimulatorImpl::CreateHistoryNavigation(-1, contents());
+  back_navigation1->ReadyToCommit();
   EXPECT_FALSE(rfh2->is_waiting_for_beforeunload_ack());
 
   // The back navigation commits.
-  NavigationEntry* entry1 = contents()->GetController().GetPendingEntry();
-  contents()->GetPendingMainFrame()->SendNavigateWithTransition(
-      entry1->GetUniqueID(), false, entry1->GetURL(),
-      entry1->GetTransitionType());
+  back_navigation1->set_drop_swap_out_ack(true);
+  back_navigation1->Commit();
   EXPECT_TRUE(rfh2->IsWaitingForUnloadACK());
   EXPECT_FALSE(rfh2->is_active());
 
   // We should be able to navigate forward.
-  contents()->GetController().GoForward();
-  contents()->GetMainFrame()->PrepareForCommit();
-  NavigationEntry* entry2 = contents()->GetController().GetPendingEntry();
-  contents()->GetPendingMainFrame()->SendNavigateWithTransition(
-      entry2->GetUniqueID(), false, entry2->GetURL(),
-      entry2->GetTransitionType());
+  NavigationSimulator::GoForward(contents());
   EXPECT_TRUE(main_test_rfh()->is_active());
 }
 
@@ -1697,9 +1691,8 @@
 
   // Navigate to new site, simulating onbeforeunload approval.
   auto navigation =
-      NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
+      NavigationSimulatorImpl::CreateBrowserInitiated(kUrl2, contents());
   navigation->ReadyToCommit();
-  int entry_id = controller().GetPendingEntry()->GetUniqueID();
   EXPECT_TRUE(contents()->CrossProcessNavigationPending());
   EXPECT_TRUE(rfh1->is_active());
   TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
@@ -1711,8 +1704,8 @@
   EXPECT_TRUE(rfh1->is_active());
 
   // The new page commits.
-  contents()->TestDidNavigate(rfh2, entry_id, true, kUrl2,
-                              ui::PAGE_TRANSITION_TYPED);
+  navigation->set_drop_swap_out_ack(true);
+  navigation->Commit();
   EXPECT_FALSE(contents()->CrossProcessNavigationPending());
   EXPECT_EQ(rfh2, contents()->GetMainFrame());
   EXPECT_TRUE(contents()->GetPendingMainFrame() == nullptr);
@@ -1745,16 +1738,15 @@
 
   // Navigate to new site, simulating onbeforeunload approval.
   auto navigation =
-      NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
+      NavigationSimulatorImpl::CreateBrowserInitiated(kUrl2, contents());
   navigation->ReadyToCommit();
-  int entry_id = controller().GetPendingEntry()->GetUniqueID();
   EXPECT_TRUE(contents()->CrossProcessNavigationPending());
   EXPECT_TRUE(rfh1->is_active());
   TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
 
   // The new page commits.
-  contents()->TestDidNavigate(rfh2, entry_id, true, kUrl2,
-                              ui::PAGE_TRANSITION_TYPED);
+  navigation->set_drop_swap_out_ack(true);
+  navigation->Commit();
   EXPECT_FALSE(contents()->CrossProcessNavigationPending());
   EXPECT_EQ(rfh2, contents()->GetMainFrame());
   EXPECT_TRUE(contents()->GetPendingMainFrame() == nullptr);
@@ -1790,16 +1782,15 @@
 
   // Navigate to new site, simulating onbeforeunload approval.
   auto navigation =
-      NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
+      NavigationSimulatorImpl::CreateBrowserInitiated(kUrl2, contents());
   navigation->ReadyToCommit();
-  int entry_id = controller().GetPendingEntry()->GetUniqueID();
   EXPECT_TRUE(contents()->CrossProcessNavigationPending());
   EXPECT_TRUE(rfh1->is_active());
   TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
 
   // The new page commits.
-  contents()->TestDidNavigate(rfh2, entry_id, true, kUrl2,
-                              ui::PAGE_TRANSITION_TYPED);
+  navigation->set_drop_swap_out_ack(true);
+  navigation->Commit();
   EXPECT_FALSE(contents()->CrossProcessNavigationPending());
   EXPECT_EQ(rfh2, contents()->GetMainFrame());
   EXPECT_TRUE(contents()->GetPendingMainFrame() == nullptr);
@@ -3151,13 +3142,10 @@
 
   // Navigate cross-site but don't simulate the swap out ACK. The initial RFH
   // should be pending delete.
-  RenderFrameHostManager* manager =
-      main_test_rfh()->frame_tree_node()->render_manager();
   auto navigation_to_kUrl2 =
-      NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
-  navigation_to_kUrl2->ReadyToCommit();
-  static_cast<TestRenderFrameHost*>(manager->speculative_frame_host())
-      ->SimulateNavigationCommit(kUrl2);
+      NavigationSimulatorImpl::CreateBrowserInitiated(kUrl2, contents());
+  navigation_to_kUrl2->set_drop_swap_out_ack(true);
+  navigation_to_kUrl2->Commit();
   EXPECT_NE(initial_rfh, main_test_rfh());
   ASSERT_FALSE(delete_observer.deleted());
   EXPECT_FALSE(initial_rfh->is_active());
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 819f665..e06d2a5 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -821,7 +821,7 @@
     if (blob_context) {
       // Get BlobHandles to request_body to prevent blobs and any attached
       // shareable files from being freed until upload completion. These data
-      // will be used in UploadDataStream and ServiceWorkerURLRequestJob.
+      // will be used in UploadDataStream.
       if (!GetBodyBlobDataHandles(request_data.request_body.get(),
                                   resource_context, &blob_handles)) {
         AbortRequestBeforeItStarts(requester_info->filter(), request_id,
diff --git a/content/browser/renderer_host/web_database_host_impl.h b/content/browser/renderer_host/web_database_host_impl.h
index 7a136b5..546eac43 100644
--- a/content/browser/renderer_host/web_database_host_impl.h
+++ b/content/browser/renderer_host/web_database_host_impl.h
@@ -10,9 +10,10 @@
 #include "base/callback_forward.h"
 #include "base/strings/string16.h"
 #include "build/build_config.h"
+#include "content/common/content_export.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "storage/browser/database/database_tracker.h"
-#include "third_party/blink/public/platform/modules/webdatabase/web_database.mojom.h"
+#include "third_party/blink/public/mojom/webdatabase/web_database.mojom.h"
 
 namespace url {
 class Origin;
diff --git a/content/browser/service_worker/service_worker_blob_reader.cc b/content/browser/service_worker/service_worker_blob_reader.cc
deleted file mode 100644
index 842cb46..0000000
--- a/content/browser/service_worker/service_worker_blob_reader.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/service_worker/service_worker_blob_reader.h"
-
-#include <utility>
-
-#include "storage/browser/blob/blob_data_handle.h"
-#include "storage/browser/blob/blob_url_request_job_factory.h"
-
-namespace content {
-
-ServiceWorkerBlobReader::ServiceWorkerBlobReader(
-    ServiceWorkerURLRequestJob* owner)
-    : owner_(owner) {}
-
-ServiceWorkerBlobReader::~ServiceWorkerBlobReader() {}
-
-void ServiceWorkerBlobReader::Start(
-    std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
-    const net::URLRequestContext* request_context) {
-  blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
-      std::move(blob_data_handle), request_context, this);
-  blob_request_->Start();
-}
-
-void ServiceWorkerBlobReader::OnReceivedRedirect(
-    net::URLRequest* request,
-    const net::RedirectInfo& redirect_info,
-    bool* defer_redirect) {
-  NOTREACHED();
-}
-
-void ServiceWorkerBlobReader::OnAuthRequired(
-    net::URLRequest* request,
-    net::AuthChallengeInfo* auth_info) {
-  NOTREACHED();
-}
-
-void ServiceWorkerBlobReader::OnCertificateRequested(
-    net::URLRequest* request,
-    net::SSLCertRequestInfo* cert_request_info) {
-  NOTREACHED();
-}
-
-void ServiceWorkerBlobReader::OnSSLCertificateError(
-    net::URLRequest* request,
-    const net::SSLInfo& ssl_info,
-    bool fatal) {
-  NOTREACHED();
-}
-
-void ServiceWorkerBlobReader::OnResponseStarted(net::URLRequest* request,
-                                                int net_error) {
-  // TODO(falken): This should check net_error per URLRequest::Delegate
-  // contract.
-  // TODO(falken): Add Content-Length, Content-Type if they were not provided in
-  // the ServiceWorkerResponse.
-  owner_->OnResponseStarted();
-}
-
-void ServiceWorkerBlobReader::OnReadCompleted(net::URLRequest* request,
-                                              int bytes_read) {
-  if (!request->status().is_success()) {
-    owner_->RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_BLOB_READ);
-  } else if (bytes_read == 0) {
-    owner_->RecordResult(ServiceWorkerMetrics::REQUEST_JOB_BLOB_RESPONSE);
-  }
-  net::URLRequestStatus status = request->status();
-  owner_->OnReadRawDataComplete(status.is_success() ? bytes_read
-                                                    : status.error());
-}
-
-int ServiceWorkerBlobReader::ReadRawData(net::IOBuffer* buf, int buf_size) {
-  int bytes_read = 0;
-  blob_request_->Read(buf, buf_size, &bytes_read);
-  net::URLRequestStatus status = blob_request_->status();
-  if (status.status() != net::URLRequestStatus::SUCCESS)
-    return status.error();
-  if (bytes_read == 0) {
-    owner_->RecordResult(ServiceWorkerMetrics::REQUEST_JOB_BLOB_RESPONSE);
-  }
-  return bytes_read;
-}
-
-}  // namespace content
diff --git a/content/browser/service_worker/service_worker_blob_reader.h b/content/browser/service_worker/service_worker_blob_reader.h
deleted file mode 100644
index 80d629b..0000000
--- a/content/browser/service_worker/service_worker_blob_reader.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_BLOB_READER_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_BLOB_READER_H_
-
-#include <memory>
-
-#include "content/browser/service_worker/service_worker_url_request_job.h"
-#include "net/base/io_buffer.h"
-#include "net/url_request/url_request.h"
-
-namespace storage {
-class BlobDataHandle;
-}
-
-namespace content {
-
-// Reads a blob response for ServiceWorkerURLRequestJob.
-// Owned by ServiceWorkerURLRequestJob.
-class ServiceWorkerBlobReader : public net::URLRequest::Delegate {
- public:
-  explicit ServiceWorkerBlobReader(ServiceWorkerURLRequestJob* owner);
-  ~ServiceWorkerBlobReader() override;
-
-  // Starts reading the blob. owner_->OnResponseStarted will be called when the
-  // response starts.
-  void Start(std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
-             const net::URLRequestContext* request_context);
-
-  scoped_refptr<net::IOBufferWithSize> response_metadata() {
-    return blob_request_->response_info().metadata;
-  }
-
-  // Same as URLRequestJob::ReadRawData. If ERR_IO_PENDING is returned,
-  // owner_->OnReadRawDataComplete will be called when the read completes.
-  int ReadRawData(net::IOBuffer* buf, int buf_size);
-
-  // net::URLRequest::Delegate overrides
-  void OnReceivedRedirect(net::URLRequest* request,
-                          const net::RedirectInfo& redirect_info,
-                          bool* defer_redirect) override;
-  void OnAuthRequired(net::URLRequest* request,
-                      net::AuthChallengeInfo* auth_info) override;
-  void OnCertificateRequested(
-      net::URLRequest* request,
-      net::SSLCertRequestInfo* cert_request_info) override;
-  void OnSSLCertificateError(net::URLRequest* request,
-                             const net::SSLInfo& ssl_info,
-                             bool fatal) override;
-  void OnResponseStarted(net::URLRequest* request, int net_error) override;
-  void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
-
- private:
-  ServiceWorkerURLRequestJob* owner_;
-  std::unique_ptr<net::URLRequest> blob_request_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerBlobReader);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_BLOB_READER_H_
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc
index 06aff19..b67829d 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler.cc
+++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -12,11 +12,10 @@
 #include "components/offline_pages/buildflags/buildflags.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_metrics.h"
+#include "content/browser/service_worker/service_worker_navigation_loader.h"
 #include "content/browser/service_worker/service_worker_provider_host.h"
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_response_info.h"
-#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
 #include "content/common/navigation_subresource_loader_params.h"
 #include "content/common/service_worker/service_worker_utils.h"
 #include "content/public/browser/content_browser_client.h"
@@ -26,11 +25,9 @@
 #include "content/public/common/content_client.h"
 #include "net/base/load_flags.h"
 #include "net/base/url_util.h"
-#include "net/url_request/url_request.h"
 #include "services/network/public/cpp/resource_request_body.h"
 #include "services/network/public/cpp/resource_response_info.h"
 #include "third_party/blink/public/common/service_worker/service_worker_utils.h"
-#include "ui/base/page_transition_types.h"
 
 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
 #include "components/offline_pages/core/request_header/offline_page_header.h"
@@ -40,22 +37,6 @@
 
 namespace {
 
-bool MaybeForwardToServiceWorker(ServiceWorkerURLJobWrapper* job,
-                                 const ServiceWorkerVersion* version) {
-  DCHECK(job);
-  DCHECK(version);
-  DCHECK_NE(version->fetch_handler_existence(),
-            ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN);
-  if (version->fetch_handler_existence() ==
-      ServiceWorkerVersion::FetchHandlerExistence::EXISTS) {
-    job->ForwardToServiceWorker();
-    return true;
-  }
-
-  job->FallbackToNetworkOrRenderer();
-  return false;
-}
-
 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
 // A web page, regardless of whether the service worker is used or not, could
 // be downloaded with the offline snapshot captured. The user can then open
@@ -198,7 +179,7 @@
   }
 #endif  // BUILDFLAG(ENABLE_OFFLINE_PAGES)
 
-  url_job_ = std::make_unique<ServiceWorkerURLJobWrapper>(
+  loader_wrapper_ = std::make_unique<ServiceWorkerNavigationLoaderWrapper>(
       std::make_unique<ServiceWorkerNavigationLoader>(
           std::move(callback), std::move(fallback_callback), this,
           tentative_resource_request, provider_host_,
@@ -209,7 +190,7 @@
   PrepareForMainResource(tentative_resource_request.url,
                          tentative_resource_request.site_for_cookies);
 
-  if (url_job_->ShouldFallbackToNetwork()) {
+  if (loader()->ShouldFallbackToNetwork()) {
     // The job already fell back to network. Clear the job now.
     ClearJob();
     return;
@@ -220,10 +201,8 @@
 
 base::Optional<SubresourceLoaderParams>
 ServiceWorkerControlleeRequestHandler::MaybeCreateSubresourceLoaderParams() {
-  DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
-
   // We didn't create URLLoader for this request.
-  if (!url_job_)
+  if (!loader())
     return base::nullopt;
 
   // DidLookupRegistrationForMainResource() for the request didn't find
@@ -256,6 +235,9 @@
     params.controller_service_worker_object_host = object_host;
     controller_info->object_info = object_host->CreateIncompleteObjectInfo();
   }
+  for (const auto feature : provider_host_->controller()->used_features()) {
+    controller_info->used_features.push_back(feature);
+  }
   params.controller_service_worker_info = std::move(controller_info);
   return base::Optional<SubresourceLoaderParams>(std::move(params));
 }
@@ -263,7 +245,7 @@
 void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
     const GURL& url,
     const GURL& site_for_cookies) {
-  DCHECK(IsJobAlive());
+  DCHECK(loader());
   DCHECK(context_);
   DCHECK(provider_host_);
   TRACE_EVENT_ASYNC_BEGIN1(
@@ -296,11 +278,11 @@
         blink::ServiceWorkerStatusCode status,
         scoped_refptr<ServiceWorkerRegistration> registration) {
   // The job may have been destroyed before this was invoked.
-  if (!IsJobAlive())
+  if (!loader())
     return;
 
   if (status != blink::ServiceWorkerStatusCode::kOk) {
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     TRACE_EVENT_ASYNC_END1(
         "ServiceWorker",
         "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
@@ -310,7 +292,7 @@
   DCHECK(registration);
 
   if (!provider_host_) {
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     TRACE_EVENT_ASYNC_END1(
         "ServiceWorker",
         "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
@@ -320,7 +302,7 @@
   provider_host_->AddMatchingRegistration(registration.get());
 
   if (!context_) {
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     TRACE_EVENT_ASYNC_END1(
         "ServiceWorker",
         "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
@@ -331,7 +313,7 @@
   if (!GetContentClient()->browser()->AllowServiceWorker(
           registration->scope(), provider_host_->site_for_cookies(),
           resource_context_, provider_host_->web_contents_getter())) {
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     TRACE_EVENT_ASYNC_END1(
         "ServiceWorker",
         "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
@@ -342,7 +324,7 @@
   if (!provider_host_->IsContextSecureForServiceWorker()) {
     // TODO(falken): Figure out a way to surface in the page's DevTools
     // console that the service worker was blocked for security.
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     TRACE_EVENT_ASYNC_END1(
         "ServiceWorker",
         "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
@@ -373,7 +355,7 @@
   scoped_refptr<ServiceWorkerVersion> active_version =
       registration->active_version();
   if (!active_version) {
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     TRACE_EVENT_ASYNC_END1(
         "ServiceWorker",
         "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
@@ -410,8 +392,8 @@
         std::unique_ptr<ScopedDisallowSetControllerRegistration>
             disallow_controller) {
   // The job may have been destroyed before this was invoked. In that
-  // case, |url_job_| can't be used, so return.
-  if (!IsJobAlive()) {
+  // case, |loader()| can't be used, so return.
+  if (!loader()) {
     TRACE_EVENT_ASYNC_END1(
         "ServiceWorker",
         "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
@@ -420,7 +402,7 @@
   }
 
   if (!provider_host_) {
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     TRACE_EVENT_ASYNC_END1(
         "ServiceWorker",
         "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
@@ -447,7 +429,7 @@
     //      retries.
     //   3) If the provider host does not have an active version, just fail the
     //      load.
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     TRACE_EVENT_ASYNC_END2(
         "ServiceWorker",
         "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
@@ -471,18 +453,23 @@
       active_version->site_for_uma(), stripped_url_,
       resource_type_ == RESOURCE_TYPE_MAIN_FRAME);
 
-  if (blink::ServiceWorkerUtils::IsServicificationEnabled() &&
-      IsResourceTypeFrame(resource_type_)) {
+  if (IsResourceTypeFrame(resource_type_))
     provider_host_->AddServiceWorkerToUpdate(active_version);
-  }
-  bool is_forwarded =
-      MaybeForwardToServiceWorker(url_job_.get(), active_version.get());
+
+  bool should_forward = active_version->fetch_handler_existence() ==
+                        ServiceWorkerVersion::FetchHandlerExistence::EXISTS;
+  if (should_forward)
+    loader()->ForwardToServiceWorker();
+  else
+    loader()->FallbackToNetwork();
+
   TRACE_EVENT_ASYNC_END1(
       "ServiceWorker",
       "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
       "Info",
-      (is_forwarded) ? "Forwarded to the ServiceWorker"
-                     : "Skipped the ServiceWorker which has no fetch handler");
+      (should_forward)
+          ? "Forwarded to the ServiceWorker"
+          : "Skipped the ServiceWorker which has no fetch handler");
 }
 
 void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration(
@@ -495,11 +482,11 @@
   DCHECK(force_update_started_);
 
   // The job may have been destroyed before this was invoked.
-  if (!IsJobAlive())
+  if (!loader())
     return;
 
   if (!context_) {
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     return;
   }
   if (status != blink::ServiceWorkerStatusCode::kOk ||
@@ -530,11 +517,11 @@
     std::unique_ptr<ScopedDisallowSetControllerRegistration>
         disallow_controller) {
   // The job may have been destroyed before this was invoked.
-  if (!IsJobAlive())
+  if (!loader())
     return;
 
   if (!context_) {
-    url_job_->FallbackToNetwork();
+    loader()->FallbackToNetwork();
     return;
   }
   if (version->status() == ServiceWorkerVersion::ACTIVATED ||
@@ -594,15 +581,11 @@
 void ServiceWorkerControlleeRequestHandler::ClearJob() {
   // Invalidate weak pointers to cancel RegisterStatusChangeCallback().
   // Otherwise we may end up calling ForwardToServiceWorer()
-  // or FallbackToNetwork() twice on the same |url_job_|.
+  // or FallbackToNetwork() twice on the same |loader()|.
   // TODO(bashi): Consider not to reuse this handler when restarting the
   // request after S13nServiceWorker is shipped.
   weak_factory_.InvalidateWeakPtrs();
-  url_job_.reset();
-}
-
-bool ServiceWorkerControlleeRequestHandler::IsJobAlive() const {
-  return url_job_ && url_job_->IsAlive();
+  loader_wrapper_.reset();
 }
 
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.h b/content/browser/service_worker/service_worker_controllee_request_handler.h
index 326b12ac..5ff9416 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler.h
+++ b/content/browser/service_worker/service_worker_controllee_request_handler.h
@@ -16,8 +16,6 @@
 #include "base/time/time.h"
 #include "content/browser/service_worker/service_worker_navigation_loader.h"
 #include "content/browser/service_worker/service_worker_request_handler.h"
-#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/public/common/resource_type.h"
 #include "services/network/public/mojom/fetch_api.mojom.h"
@@ -38,7 +36,7 @@
 // shared workers).
 class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
     : public ServiceWorkerRequestHandler,
-      public ServiceWorkerURLJobWrapper::Delegate {
+      public ServiceWorkerNavigationLoader::Delegate {
  public:
   ServiceWorkerControlleeRequestHandler(
       base::WeakPtr<ServiceWorkerContextCore> context,
@@ -55,10 +53,11 @@
       scoped_refptr<network::ResourceRequestBody> body);
   ~ServiceWorkerControlleeRequestHandler() override;
 
+  // NavigationLoaderInterceptor overrides:
+
   // This could get called multiple times during the lifetime in redirect
   // cases. (In fallback-to-network cases we basically forward the request
   // to the request to the next request handler)
-  // NavigationLoaderInterceptor overrides:
   void MaybeCreateLoader(const network::ResourceRequest& tentative_request,
                          ResourceContext* resource_context,
                          LoaderCallback callback,
@@ -70,14 +69,17 @@
       override;
 
   // Exposed for testing.
-  ServiceWorkerURLJobWrapper* url_job() const { return url_job_.get(); }
+  ServiceWorkerNavigationLoader* loader() {
+    return loader_wrapper_ ? loader_wrapper_->get() : nullptr;
+  }
 
  private:
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerControlleeRequestHandlerTest,
                            ActivateWaitingVersion);
   class ScopedDisallowSetControllerRegistration;
 
-  // For main resource case.
+  // TODO(falken): Remove the "MainResource" names, they are redundant as this
+  // handler is for main resources only.
   void PrepareForMainResource(const GURL& url, const GURL& site_for_cookies);
   void DidLookupRegistrationForMainResource(
       std::unique_ptr<ScopedDisallowSetControllerRegistration>
@@ -104,7 +106,7 @@
       std::unique_ptr<ScopedDisallowSetControllerRegistration>
           disallow_controller);
 
-  // ServiceWorkerURLJobWrapper::Delegate implementation:
+  // ServiceWorkerNavigationLoader::Delegate implementation:
   void OnPrepareToRestart() override;
   ServiceWorkerVersion* GetServiceWorkerVersion(
       ServiceWorkerMetrics::URLRequestJobResult* result) override;
@@ -116,14 +118,12 @@
   // that job, except for timing information.
   void ClearJob();
 
-  bool IsJobAlive() const;
-
   // Schedules a service worker update to occur shortly after the page and its
   // initial subresources load, if this handler was for a navigation.
   void MaybeScheduleUpdate();
 
   const ResourceType resource_type_;
-  std::unique_ptr<ServiceWorkerURLJobWrapper> url_job_;
+  std::unique_ptr<ServiceWorkerNavigationLoaderWrapper> loader_wrapper_;
   network::mojom::FetchRequestMode request_mode_;
   network::mojom::FetchCredentialsMode credentials_mode_;
   network::mojom::FetchRedirectMode redirect_mode_;
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
index f4150f5..d25f766 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
+++ b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -20,7 +20,6 @@
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_response_type.h"
 #include "content/browser/service_worker/service_worker_test_utils.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/public/browser/resource_context.h"
 #include "content/public/common/resource_type.h"
@@ -66,21 +65,16 @@
               type,
               blink::mojom::RequestContextType::HYPERLINK,
               network::mojom::RequestContextFrameType::kTopLevel,
-              scoped_refptr<network::ResourceRequestBody>())),
-          job_(nullptr) {}
+              scoped_refptr<network::ResourceRequestBody>())) {}
 
-    void MaybeCreateLoader() {
+    ServiceWorkerNavigationLoader* MaybeCreateLoader() {
       network::ResourceRequest resource_request;
       resource_request.url = request_->url();
       resource_request.resource_type = resource_type_;
       resource_request.headers = request()->extra_request_headers();
       handler_->MaybeCreateLoader(resource_request, nullptr,
                                   base::DoNothing(), base::DoNothing());
-    }
-
-    ServiceWorkerURLJobWrapper* MaybeCreateJobWrapper() {
-      MaybeCreateLoader();
-      return handler_->url_job();
+      return handler_->loader();
     }
 
     void ResetHandler() { handler_.reset(nullptr); }
@@ -91,11 +85,6 @@
     const ResourceType resource_type_;
     std::unique_ptr<net::URLRequest> request_;
     std::unique_ptr<ServiceWorkerControlleeRequestHandler> handler_;
-    // |job_| and |job_wrapper_| are only for non-S13nServiceWorker cases.
-    // When S13nServiceWorker is enabled we use a job wrapper which is owned by
-    // |handler_|.
-    std::unique_ptr<net::URLRequestJob> job_;
-    std::unique_ptr<ServiceWorkerURLJobWrapper> job_wrapper_;
   };
 
   ServiceWorkerControlleeRequestHandlerTest()
@@ -193,17 +182,17 @@
   // Conduct a main resource load.
   ServiceWorkerRequestTestResources test_resources(
       this, GURL("https://host/scope/doc"), RESOURCE_TYPE_MAIN_FRAME);
-  ServiceWorkerURLJobWrapper* sw_job = test_resources.MaybeCreateJobWrapper();
-  ASSERT_TRUE(sw_job);
+  ServiceWorkerNavigationLoader* loader = test_resources.MaybeCreateLoader();
+  ASSERT_TRUE(loader);
 
-  EXPECT_FALSE(sw_job->ShouldFallbackToNetwork());
-  EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
+  EXPECT_FALSE(loader->ShouldFallbackToNetwork());
+  EXPECT_FALSE(loader->ShouldForwardToServiceWorker());
   EXPECT_FALSE(version_->HasControllee());
   base::RunLoop().RunUntilIdle();
 
   // Verify we did not use the worker.
-  EXPECT_TRUE(sw_job->ShouldFallbackToNetwork());
-  EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
+  EXPECT_TRUE(loader->ShouldFallbackToNetwork());
+  EXPECT_FALSE(loader->ShouldForwardToServiceWorker());
   EXPECT_FALSE(version_->HasControllee());
 
   SetBrowserClientForTesting(old_browser_client);
@@ -224,17 +213,17 @@
   // Conduct a main resource load.
   ServiceWorkerRequestTestResources test_resources(
       this, GURL("https://host/scope/doc"), RESOURCE_TYPE_MAIN_FRAME);
-  ServiceWorkerURLJobWrapper* sw_job = test_resources.MaybeCreateJobWrapper();
-  ASSERT_TRUE(sw_job);
+  ServiceWorkerNavigationLoader* loader = test_resources.MaybeCreateLoader();
+  ASSERT_TRUE(loader);
 
-  EXPECT_FALSE(sw_job->ShouldFallbackToNetwork());
-  EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
+  EXPECT_FALSE(loader->ShouldFallbackToNetwork());
+  EXPECT_FALSE(loader->ShouldForwardToServiceWorker());
   EXPECT_FALSE(version_->HasControllee());
   base::RunLoop().RunUntilIdle();
 
   // Verify we did not use the worker.
-  EXPECT_TRUE(sw_job->ShouldFallbackToNetwork());
-  EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
+  EXPECT_TRUE(loader->ShouldFallbackToNetwork());
+  EXPECT_FALSE(loader->ShouldForwardToServiceWorker());
   EXPECT_FALSE(version_->HasControllee());
 }
 
@@ -251,18 +240,18 @@
   // Conduct a main resource load.
   ServiceWorkerRequestTestResources test_resources(
       this, GURL("https://host/scope/doc"), RESOURCE_TYPE_MAIN_FRAME);
-  ServiceWorkerURLJobWrapper* sw_job = test_resources.MaybeCreateJobWrapper();
-  ASSERT_TRUE(sw_job);
+  ServiceWorkerNavigationLoader* loader = test_resources.MaybeCreateLoader();
+  ASSERT_TRUE(loader);
 
-  EXPECT_FALSE(sw_job->ShouldFallbackToNetwork());
-  EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
+  EXPECT_FALSE(loader->ShouldFallbackToNetwork());
+  EXPECT_FALSE(loader->ShouldForwardToServiceWorker());
   EXPECT_FALSE(version_->HasControllee());
 
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(ServiceWorkerVersion::ACTIVATED, version_->status());
-  EXPECT_FALSE(sw_job->ShouldFallbackToNetwork());
-  EXPECT_TRUE(sw_job->ShouldForwardToServiceWorker());
+  EXPECT_FALSE(loader->ShouldFallbackToNetwork());
+  EXPECT_TRUE(loader->ShouldForwardToServiceWorker());
   EXPECT_TRUE(version_->HasControllee());
 
   test_resources.ResetHandler();
@@ -280,7 +269,7 @@
   // Conduct a main resource load.
   ServiceWorkerRequestTestResources test_resources(
       this, GURL("https://host/scope/doc"), RESOURCE_TYPE_MAIN_FRAME);
-  ServiceWorkerURLJobWrapper* job = test_resources.MaybeCreateJobWrapper();
+  ServiceWorkerNavigationLoader* job = test_resources.MaybeCreateLoader();
 
   base::RunLoop().RunUntilIdle();
 
@@ -311,19 +300,19 @@
   // Conduct a main resource load.
   ServiceWorkerRequestTestResources test_resources(
       this, GURL("https://host/scope/doc"), RESOURCE_TYPE_MAIN_FRAME);
-  ServiceWorkerURLJobWrapper* sw_job = test_resources.MaybeCreateJobWrapper();
-  ASSERT_TRUE(sw_job);
+  ServiceWorkerNavigationLoader* loader = test_resources.MaybeCreateLoader();
+  ASSERT_TRUE(loader);
 
-  EXPECT_FALSE(sw_job->ShouldFallbackToNetwork());
-  EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
+  EXPECT_FALSE(loader->ShouldFallbackToNetwork());
+  EXPECT_FALSE(loader->ShouldForwardToServiceWorker());
 
   // Shouldn't crash if the ProviderHost is deleted prior to completion of
   // the database lookup.
   context()->RemoveProviderHost(provider_host_->provider_id());
   EXPECT_FALSE(provider_host_.get());
   base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(sw_job->ShouldFallbackToNetwork());
-  EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
+  EXPECT_TRUE(loader->ShouldFallbackToNetwork());
+  EXPECT_FALSE(loader->ShouldForwardToServiceWorker());
 }
 
 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
@@ -343,9 +332,9 @@
   // Sets an offline header to indicate force loading offline page.
   test_resources.request()->SetExtraRequestHeaderByName(
       "X-Chrome-offline", "reason=download", true);
-  ServiceWorkerURLJobWrapper* sw_job = test_resources.MaybeCreateJobWrapper();
+  ServiceWorkerNavigationLoader* loader = test_resources.MaybeCreateLoader();
 
-  EXPECT_FALSE(sw_job);
+  EXPECT_FALSE(loader);
 }
 
 TEST_F(ServiceWorkerControlleeRequestHandlerTest, FallbackWithNoOfflineHeader) {
@@ -364,9 +353,9 @@
   // Empty offline header value should not cause fallback.
   test_resources.request()->SetExtraRequestHeaderByName("X-Chrome-offline", "",
                                                         true);
-  ServiceWorkerURLJobWrapper* sw_job = test_resources.MaybeCreateJobWrapper();
+  ServiceWorkerNavigationLoader* loader = test_resources.MaybeCreateLoader();
 
-  EXPECT_TRUE(sw_job);
+  EXPECT_TRUE(loader);
 }
 #endif  // BUILDFLAG(ENABLE_OFFLINE_PAGE)
 
diff --git a/content/browser/service_worker/service_worker_data_pipe_reader.cc b/content/browser/service_worker/service_worker_data_pipe_reader.cc
deleted file mode 100644
index 308a82b..0000000
--- a/content/browser/service_worker/service_worker_data_pipe_reader.cc
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/service_worker/service_worker_data_pipe_reader.h"
-
-#include "base/bind.h"
-#include "base/trace_event/trace_event.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
-#include "net/base/io_buffer.h"
-
-namespace content {
-
-ServiceWorkerDataPipeReader::ServiceWorkerDataPipeReader(
-    ServiceWorkerURLRequestJob* owner,
-    blink::mojom::ServiceWorkerStreamHandlePtr stream_handle)
-    : owner_(owner),
-      stream_pending_buffer_size_(0),
-      handle_watcher_(FROM_HERE,
-                      mojo::SimpleWatcher::ArmingPolicy::MANUAL,
-                      base::SequencedTaskRunnerHandle::Get()),
-      stream_(std::move(stream_handle->stream)),
-      binding_(this, std::move(stream_handle->callback_request)),
-      producer_state_(State::kStreaming) {
-  TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", "ServiceWorkerDataPipeReader", this,
-                           "Url", owner->request()->url().spec());
-  binding_.set_connection_error_handler(base::BindOnce(
-      &ServiceWorkerDataPipeReader::OnAborted, base::Unretained(this)));
-}
-
-ServiceWorkerDataPipeReader::~ServiceWorkerDataPipeReader() {
-  TRACE_EVENT_ASYNC_END0("ServiceWorker", "ServiceWorkerDataPipeReader", this);
-}
-
-void ServiceWorkerDataPipeReader::Start() {
-  TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker", "ServiceWorkerDataPipeReader",
-                               this, "Start");
-  handle_watcher_.Watch(
-      stream_.get(),
-      MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
-      base::BindRepeating(&ServiceWorkerDataPipeReader::OnHandleGotSignal,
-                          base::Unretained(this)));
-  owner_->OnResponseStarted();
-}
-
-void ServiceWorkerDataPipeReader::OnHandleGotSignal(MojoResult) {
-  TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker", "ServiceWorkerDataPipeReader",
-                               this, "OnHandleGotSignal");
-  DCHECK(stream_pending_buffer_);
-
-  // If state() is not STREAMING, it means the data pipe was disconnected and
-  // OnCompleted/OnAborted has already been called.
-  if (state() != State::kStreaming) {
-    handle_watcher_.Cancel();
-    AsyncComplete();
-  }
-
-  // |stream_pending_buffer_| is set to the IOBuffer instance provided to
-  // ReadRawData() by URLRequestJob.
-  uint32_t size_to_pass = stream_pending_buffer_size_;
-  MojoResult mojo_result = stream_->ReadData(
-      stream_pending_buffer_->data(), &size_to_pass, MOJO_READ_DATA_FLAG_NONE);
-
-  switch (mojo_result) {
-    case MOJO_RESULT_OK:
-      stream_pending_buffer_ = nullptr;
-      stream_pending_buffer_size_ = 0;
-      owner_->OnReadRawDataComplete(size_to_pass);
-      return;
-    case MOJO_RESULT_FAILED_PRECONDITION:
-      stream_.reset();
-      handle_watcher_.Cancel();
-      // If OnCompleted/OnAborted has already been called, let this request
-      // complete.
-      if (state() != State::kStreaming)
-        AsyncComplete();
-      return;
-    case MOJO_RESULT_SHOULD_WAIT:
-    // MOJO_RESULT_SHOULD_WAIT should not be returned since
-    // OnHandleGotSignal should be called by readable or closed signals.
-    case MOJO_RESULT_INVALID_ARGUMENT:
-    case MOJO_RESULT_OUT_OF_RANGE:
-    case MOJO_RESULT_BUSY:
-      break;
-  }
-  NOTREACHED();
-}
-
-int ServiceWorkerDataPipeReader::ReadRawData(net::IOBuffer* buf, int buf_size) {
-  TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker", "ServiceWorkerDataPipeReader",
-                               this, "ReadRawData");
-  DCHECK(!stream_pending_buffer_);
-  // If state() is not STREAMING, it means the data pipe was disconnected and
-  // OnCompleted/OnAborted has already been called.
-  if (state() != State::kStreaming)
-    return SyncComplete();
-
-  uint32_t size_to_pass = buf_size;
-  MojoResult mojo_result =
-      stream_->ReadData(buf->data(), &size_to_pass, MOJO_READ_DATA_FLAG_NONE);
-  switch (mojo_result) {
-    case MOJO_RESULT_OK:
-      return size_to_pass;
-    case MOJO_RESULT_FAILED_PRECONDITION:
-      stream_.reset();
-      handle_watcher_.Cancel();
-      // Complete/Abort asynchronously if OnCompleted/OnAborted has not been
-      // called yet.
-      if (state() == State::kStreaming) {
-        stream_pending_buffer_ = buf;
-        stream_pending_buffer_size_ = buf_size;
-        return net::ERR_IO_PENDING;
-      }
-      return SyncComplete();
-    case MOJO_RESULT_SHOULD_WAIT:
-      stream_pending_buffer_ = buf;
-      stream_pending_buffer_size_ = buf_size;
-      handle_watcher_.ArmOrNotify();
-      return net::ERR_IO_PENDING;
-    case MOJO_RESULT_INVALID_ARGUMENT:
-    case MOJO_RESULT_OUT_OF_RANGE:
-    case MOJO_RESULT_BUSY:
-      break;
-  }
-  NOTREACHED();
-  return net::ERR_FAILED;
-}
-
-void ServiceWorkerDataPipeReader::OnCompleted() {
-  producer_state_ = State::kCompleted;
-  if (stream_pending_buffer_ && state() != State::kStreaming)
-    AsyncComplete();
-}
-
-void ServiceWorkerDataPipeReader::OnAborted() {
-  producer_state_ = State::kAborted;
-  if (stream_pending_buffer_ && state() != State::kStreaming)
-    AsyncComplete();
-}
-
-void ServiceWorkerDataPipeReader::AsyncComplete() {
-  // This works only after ReadRawData returns net::ERR_IO_PENDING.
-  DCHECK(stream_pending_buffer_);
-
-  switch (state()) {
-    case State::kStreaming:
-      NOTREACHED();
-      break;
-    case State::kCompleted:
-      stream_pending_buffer_ = nullptr;
-      stream_pending_buffer_size_ = 0;
-      handle_watcher_.Cancel();
-      owner_->RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE);
-      owner_->OnReadRawDataComplete(net::OK);
-      return;
-    case State::kAborted:
-      stream_pending_buffer_ = nullptr;
-      stream_pending_buffer_size_ = 0;
-      handle_watcher_.Cancel();
-      owner_->RecordResult(
-          ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED);
-      owner_->OnReadRawDataComplete(net::ERR_CONNECTION_RESET);
-      return;
-  }
-}
-
-int ServiceWorkerDataPipeReader::SyncComplete() {
-  // This works only in ReadRawData.
-  DCHECK(!stream_pending_buffer_);
-
-  switch (state()) {
-    case State::kStreaming:
-      break;
-    case State::kCompleted:
-      owner_->RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE);
-      return net::OK;
-    case State::kAborted:
-      owner_->RecordResult(
-          ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED);
-      return net::ERR_CONNECTION_RESET;
-  }
-  NOTREACHED();
-  return net::ERR_FAILED;
-}
-
-ServiceWorkerDataPipeReader::State ServiceWorkerDataPipeReader::state() {
-  if (!stream_.is_valid())
-    return producer_state_;
-  return State::kStreaming;
-}
-
-}  // namespace content
diff --git a/content/browser/service_worker/service_worker_data_pipe_reader.h b/content/browser/service_worker/service_worker_data_pipe_reader.h
deleted file mode 100644
index c0272d2..0000000
--- a/content/browser/service_worker/service_worker_data_pipe_reader.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATA_PIPE_READER_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATA_PIPE_READER_H_
-
-#include "base/memory/ref_counted.h"
-#include "content/common/content_export.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/system/data_pipe.h"
-#include "mojo/public/cpp/system/simple_watcher.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_stream_handle.mojom.h"
-
-namespace net {
-class IOBuffer;
-}  // namespace net
-
-namespace content {
-
-class ServiceWorkerURLRequestJob;
-
-// Reads a stream response for ServiceWorkerURLRequestJob passed through
-// Mojo's data pipe. Owned by ServiceWorkerURLRequestJob.
-class CONTENT_EXPORT ServiceWorkerDataPipeReader
-    : public blink::mojom::ServiceWorkerStreamCallback {
- public:
-  ServiceWorkerDataPipeReader(
-      ServiceWorkerURLRequestJob* owner,
-      blink::mojom::ServiceWorkerStreamHandlePtr stream_handle);
-  ~ServiceWorkerDataPipeReader() override;
-
-  // Starts reading the stream. Calls owner_->OnResponseStarted.
-  void Start();
-
-  // Same as URLRequestJob::ReadRawData. If ERR_IO_PENDING is returned,
-  // owner_->OnReadRawDataComplete will be called when the read completes.
-  int ReadRawData(net::IOBuffer* buf, int buf_size);
-
-  // Implements mojom::ServiceWorkerStreamCallback.
-  void OnCompleted() override;
-  void OnAborted() override;
-
- private:
-  enum class State { kStreaming, kCompleted, kAborted };
-
-  // Callback method for |handle_watcher_|.
-  void OnHandleGotSignal(MojoResult);
-
-  // Finalizes the job. These must be called when state() is not
-  // State::STREAMING.
-  int SyncComplete();
-  void AsyncComplete();
-
-  State state();
-
-  ServiceWorkerURLRequestJob* owner_;
-  scoped_refptr<net::IOBuffer> stream_pending_buffer_;
-  int stream_pending_buffer_size_;
-  mojo::SimpleWatcher handle_watcher_;
-  mojo::ScopedDataPipeConsumerHandle stream_;
-  mojo::Binding<blink::mojom::ServiceWorkerStreamCallback> binding_;
-  // State notified via ServiceWorkerStreamCallback. |producer_state_| is
-  // STREAMING until OnCompleted or OnAborted is called. Note that |stream_|
-  // might be closed even if |producer_state_| is STREAMING. In order to see the
-  // state of ServiceWorkerDataPipeReader, use state() instead.
-  State producer_state_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDataPipeReader);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATA_PIPE_READER_H_
diff --git a/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc b/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc
deleted file mode 100644
index 580c48e..0000000
--- a/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/service_worker/service_worker_data_pipe_reader.h"
-
-#include <utility>
-#include "base/run_loop.h"
-#include "content/browser/service_worker/embedded_worker_test_helper.h"
-#include "content/browser/service_worker/service_worker_context_core.h"
-#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/base/io_buffer.h"
-#include "services/network/public/cpp/resource_request_body.h"
-#include "services/network/public/mojom/request_context_frame_type.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-namespace {
-
-const char kTestData[] = "Here is sample text for the blob.";
-
-}  // namespace
-
-class MockServiceWorkerURLRequestJob : public ServiceWorkerURLRequestJob {
- public:
-  explicit MockServiceWorkerURLRequestJob(
-      ServiceWorkerURLRequestJob::Delegate* delegate)
-      : ServiceWorkerURLRequestJob(
-            nullptr,
-            nullptr,
-            nullptr,
-            nullptr,
-            nullptr,
-            network::mojom::FetchRequestMode::kNoCors,
-            network::mojom::FetchCredentialsMode::kOmit,
-            network::mojom::FetchRedirectMode::kFollow,
-            std::string() /* integrity */,
-            false /* keepalive */,
-            RESOURCE_TYPE_MAIN_FRAME,
-            blink::mojom::RequestContextType::HYPERLINK,
-            network::mojom::RequestContextFrameType::kTopLevel,
-            scoped_refptr<network::ResourceRequestBody>(),
-            delegate),
-        is_response_started_(false) {}
-
-  void OnResponseStarted() override { is_response_started_ = true; }
-
-  void OnReadRawDataComplete(int bytes_read) override {
-    async_read_bytes_.push_back(bytes_read);
-  }
-
-  void RecordResult(ServiceWorkerMetrics::URLRequestJobResult result) override {
-    results_.push_back(result);
-  }
-
-  bool is_response_started() { return is_response_started_; }
-  const std::vector<int>& async_read_bytes() { return async_read_bytes_; }
-  const std::vector<ServiceWorkerMetrics::URLRequestJobResult>& results() {
-    return results_;
-  }
-
- private:
-  bool is_response_started_;
-  std::vector<int> async_read_bytes_;
-  std::vector<ServiceWorkerMetrics::URLRequestJobResult> results_;
-};
-
-class ServiceWorkerDataPipeReaderTest
-    : public testing::Test,
-      public ServiceWorkerURLRequestJob::Delegate {
- public:
-  ServiceWorkerDataPipeReaderTest()
-      : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
-
-  void SetUp() override {
-    helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
-    mock_url_request_job_ =
-        std::make_unique<MockServiceWorkerURLRequestJob>(this);
-  }
-
-  std::unique_ptr<ServiceWorkerDataPipeReader> CreateTargetDataPipeReader(
-      blink::mojom::ServiceWorkerStreamCallbackPtr* stream_callback,
-      mojo::DataPipe* data_pipe) {
-    blink::mojom::ServiceWorkerStreamHandlePtr stream_handle =
-        blink::mojom::ServiceWorkerStreamHandle::New();
-    stream_handle->stream = std::move(data_pipe->consumer_handle);
-    stream_handle->callback_request = mojo::MakeRequest(stream_callback);
-    return std::make_unique<ServiceWorkerDataPipeReader>(
-        mock_url_request_job_.get(), std::move(stream_handle));
-  }
-
-  // Implements ServiceWorkerURLRequestJob::Delegate.
-  void OnPrepareToRestart() override { NOTREACHED(); }
-
-  ServiceWorkerVersion* GetServiceWorkerVersion(
-      ServiceWorkerMetrics::URLRequestJobResult*) override {
-    NOTREACHED();
-    return nullptr;
-  }
-
-  bool RequestStillValid(ServiceWorkerMetrics::URLRequestJobResult*) override {
-    NOTREACHED();
-    return false;
-  }
-
-  void TearDown() override { helper_.reset(); }
-
-  MockServiceWorkerURLRequestJob* mock_url_request_job() {
-    return mock_url_request_job_.get();
-  }
-
- protected:
-  TestBrowserThreadBundle thread_bundle_;
-
-  std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
-  std::unique_ptr<MockServiceWorkerURLRequestJob> mock_url_request_job_;
-};
-
-class ServiceWorkerDataPipeReaderTestP
-    : public ServiceWorkerDataPipeReaderTest,
-      public testing::WithParamInterface<
-          std::tuple<bool /* should_close_connection_first */,
-                     bool /* has_body */>> {
- public:
-  ServiceWorkerDataPipeReaderTestP() {}
-  virtual ~ServiceWorkerDataPipeReaderTestP() {}
-
- protected:
-  bool should_close_connection_first() const { return std::get<0>(GetParam()); }
-  bool has_body() const { return std::get<1>(GetParam()); }
-};
-
-TEST_P(ServiceWorkerDataPipeReaderTestP, SyncRead) {
-  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
-  mojo::DataPipe data_pipe;
-  std::unique_ptr<ServiceWorkerDataPipeReader> data_pipe_reader =
-      CreateTargetDataPipeReader(&stream_callback, &data_pipe);
-
-  // Push enough data.
-  if (has_body()) {
-    std::string expected_response;
-    expected_response.reserve((sizeof(kTestData) - 1) * 1024);
-    for (int i = 0; i < 1024; ++i) {
-      expected_response += kTestData;
-      uint32_t written_bytes = sizeof(kTestData) - 1;
-      MojoResult result = data_pipe.producer_handle->WriteData(
-          kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
-      ASSERT_EQ(MOJO_RESULT_OK, result);
-      EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);
-    }
-  }
-  data_pipe.producer_handle.reset();
-  stream_callback->OnCompleted();
-  base::RunLoop().RunUntilIdle();
-
-  // Nothing has started.
-  EXPECT_FALSE(mock_url_request_job()->is_response_started());
-  EXPECT_EQ(0UL, mock_url_request_job()->async_read_bytes().size());
-  EXPECT_EQ(0UL, mock_url_request_job()->results().size());
-
-  // Start to read.
-  data_pipe_reader->Start();
-  EXPECT_TRUE(mock_url_request_job()->is_response_started());
-  const int buffer_size = sizeof(kTestData);
-  scoped_refptr<net::IOBuffer> buffer =
-      base::MakeRefCounted<net::IOBuffer>(buffer_size);
-  buffer->data()[buffer_size - 1] = '\0';
-
-  // Read successfully.
-  if (has_body()) {
-    std::string retrieved_response;
-    retrieved_response.reserve(buffer_size * 1024);
-    for (int i = 0; i < 1024; ++i) {
-      EXPECT_EQ(buffer_size - 1,
-                data_pipe_reader->ReadRawData(buffer.get(), buffer_size - 1));
-      EXPECT_STREQ(kTestData, buffer->data());
-      retrieved_response += buffer->data();
-    }
-  }
-
-  // Finish successfully.
-  EXPECT_EQ(net::OK,
-            data_pipe_reader->ReadRawData(buffer.get(), buffer_size - 1));
-  EXPECT_EQ(0UL, mock_url_request_job()->async_read_bytes().size());
-  ASSERT_EQ(1UL, mock_url_request_job()->results().size());
-  EXPECT_EQ(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE,
-            mock_url_request_job()->results()[0]);
-}
-
-TEST_P(ServiceWorkerDataPipeReaderTestP, SyncAbort) {
-  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
-  mojo::DataPipe data_pipe;
-  std::unique_ptr<ServiceWorkerDataPipeReader> data_pipe_reader =
-      CreateTargetDataPipeReader(&stream_callback, &data_pipe);
-
-  // Push enough data.
-  if (has_body()) {
-    std::string expected_response;
-    expected_response.reserve((sizeof(kTestData) - 1) * 1024);
-    for (int i = 0; i < 1024; ++i) {
-      expected_response += kTestData;
-      uint32_t written_bytes = sizeof(kTestData) - 1;
-      MojoResult result = data_pipe.producer_handle->WriteData(
-          kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
-      ASSERT_EQ(MOJO_RESULT_OK, result);
-      EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);
-    }
-  }
-  data_pipe.producer_handle.reset();
-  stream_callback->OnAborted();
-  base::RunLoop().RunUntilIdle();
-
-  // Nothing has started.
-  EXPECT_FALSE(mock_url_request_job()->is_response_started());
-  EXPECT_EQ(0UL, mock_url_request_job()->async_read_bytes().size());
-  EXPECT_EQ(0UL, mock_url_request_job()->results().size());
-
-  // Start to read.
-  data_pipe_reader->Start();
-  EXPECT_TRUE(mock_url_request_job()->is_response_started());
-  const int buffer_size = sizeof(kTestData);
-  scoped_refptr<net::IOBuffer> buffer =
-      base::MakeRefCounted<net::IOBuffer>(buffer_size);
-  buffer->data()[buffer_size - 1] = '\0';
-
-  // Read successfully.
-  if (has_body()) {
-    std::string retrieved_response;
-    retrieved_response.reserve(buffer_size * 1024);
-    for (int i = 0; i < 1024; ++i) {
-      EXPECT_EQ(buffer_size - 1,
-                data_pipe_reader->ReadRawData(buffer.get(), buffer_size - 1));
-      EXPECT_STREQ(kTestData, buffer->data());
-      retrieved_response += buffer->data();
-    }
-  }
-
-  // Abort after all data has been read.
-  EXPECT_EQ(net::ERR_CONNECTION_RESET,
-            data_pipe_reader->ReadRawData(buffer.get(), buffer_size - 1));
-  EXPECT_EQ(0UL, mock_url_request_job()->async_read_bytes().size());
-  ASSERT_EQ(1UL, mock_url_request_job()->results().size());
-  EXPECT_EQ(ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED,
-            mock_url_request_job()->results()[0]);
-}
-
-TEST_P(ServiceWorkerDataPipeReaderTestP, AsyncRead) {
-  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
-  mojo::DataPipe data_pipe;
-  std::unique_ptr<ServiceWorkerDataPipeReader> data_pipe_reader =
-      CreateTargetDataPipeReader(&stream_callback, &data_pipe);
-
-  // Nothing has started.
-  EXPECT_FALSE(mock_url_request_job()->is_response_started());
-  EXPECT_EQ(0UL, mock_url_request_job()->async_read_bytes().size());
-  EXPECT_EQ(0UL, mock_url_request_job()->results().size());
-
-  // Start to read.
-  data_pipe_reader->Start();
-  EXPECT_TRUE(mock_url_request_job()->is_response_started());
-  scoped_refptr<net::IOBuffer> buffer =
-      base::MakeRefCounted<net::IOBuffer>(sizeof(kTestData));
-  buffer->data()[sizeof(kTestData) - 1] = '\0';
-  std::string expected_response;
-  std::string retrieved_response;
-  expected_response.reserve((sizeof(kTestData) - 1) * 1024);
-  retrieved_response.reserve((sizeof(kTestData) - 1) * 1024);
-
-  if (has_body()) {
-    for (int i = 0; i < 1024; ++i) {
-      // Data is not coming. It should be pending state.
-      EXPECT_EQ(net::ERR_IO_PENDING, data_pipe_reader->ReadRawData(
-                                         buffer.get(), sizeof(kTestData) - 1));
-
-      // Push a portion of data.
-      uint32_t written_bytes = sizeof(kTestData) - 1;
-      MojoResult result = data_pipe.producer_handle->WriteData(
-          kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
-      ASSERT_EQ(MOJO_RESULT_OK, result);
-      EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);
-      expected_response += kTestData;
-      base::RunLoop().RunUntilIdle();
-
-      // Read the pushed data correctly.
-      ASSERT_EQ(static_cast<size_t>(i + 1),
-                mock_url_request_job()->async_read_bytes().size());
-      EXPECT_EQ(static_cast<int>(sizeof(kTestData) - 1),
-                mock_url_request_job()->async_read_bytes()[i]);
-      EXPECT_STREQ(kTestData, buffer->data());
-    }
-  }
-
-  // Data is not coming. It should be pending state.
-  EXPECT_EQ(net::ERR_IO_PENDING,
-            data_pipe_reader->ReadRawData(buffer.get(), sizeof(kTestData) - 1));
-
-  // Finish successfully when connection is closed AND OnCompleted is delivered.
-  size_t num_read = mock_url_request_job()->async_read_bytes().size();
-  if (should_close_connection_first()) {
-    data_pipe.producer_handle.reset();
-  } else {
-    stream_callback->OnCompleted();
-  }
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(num_read, mock_url_request_job()->async_read_bytes().size());
-  EXPECT_EQ(0UL, mock_url_request_job()->results().size());
-
-  if (should_close_connection_first()) {
-    stream_callback->OnCompleted();
-  } else {
-    data_pipe.producer_handle.reset();
-  }
-  base::RunLoop().RunUntilIdle();
-  ASSERT_EQ(num_read + 1, mock_url_request_job()->async_read_bytes().size());
-  EXPECT_EQ(net::OK, mock_url_request_job()->async_read_bytes().back());
-  ASSERT_EQ(1UL, mock_url_request_job()->results().size());
-  EXPECT_EQ(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE,
-            mock_url_request_job()->results()[0]);
-}
-
-TEST_P(ServiceWorkerDataPipeReaderTestP, AsyncAbort) {
-  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
-  mojo::DataPipe data_pipe;
-  std::unique_ptr<ServiceWorkerDataPipeReader> data_pipe_reader =
-      CreateTargetDataPipeReader(&stream_callback, &data_pipe);
-
-  // Nothing has started.
-  EXPECT_FALSE(mock_url_request_job()->is_response_started());
-  EXPECT_EQ(0UL, mock_url_request_job()->async_read_bytes().size());
-  EXPECT_EQ(0UL, mock_url_request_job()->results().size());
-
-  // Start to read.
-  data_pipe_reader->Start();
-  EXPECT_TRUE(mock_url_request_job()->is_response_started());
-  scoped_refptr<net::IOBuffer> buffer =
-      base::MakeRefCounted<net::IOBuffer>(sizeof(kTestData));
-  buffer->data()[sizeof(kTestData) - 1] = '\0';
-  std::string expected_response;
-  std::string retrieved_response;
-  expected_response.reserve((sizeof(kTestData) - 1) * 1024);
-  retrieved_response.reserve((sizeof(kTestData) - 1) * 1024);
-
-  if (has_body()) {
-    for (int i = 0; i < 1024; ++i) {
-      // Data is not coming. It should be pending state.
-      EXPECT_EQ(net::ERR_IO_PENDING, data_pipe_reader->ReadRawData(
-                                         buffer.get(), sizeof(kTestData) - 1));
-
-      // Push a portion of data.
-      uint32_t written_bytes = sizeof(kTestData) - 1;
-      MojoResult result = data_pipe.producer_handle->WriteData(
-          kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
-      ASSERT_EQ(MOJO_RESULT_OK, result);
-      EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);
-      expected_response += kTestData;
-      base::RunLoop().RunUntilIdle();
-
-      // Read the pushed data correctly.
-      ASSERT_EQ(static_cast<size_t>(i + 1),
-                mock_url_request_job()->async_read_bytes().size());
-      EXPECT_EQ(static_cast<int>(sizeof(kTestData) - 1),
-                mock_url_request_job()->async_read_bytes()[i]);
-      EXPECT_STREQ(kTestData, buffer->data());
-    }
-  }
-
-  // Data is not coming. It should be pending state.
-  EXPECT_EQ(net::ERR_IO_PENDING,
-            data_pipe_reader->ReadRawData(buffer.get(), sizeof(kTestData) - 1));
-
-  // Abort when connection is closed AND OnAborted is delivered.
-  size_t num_read = mock_url_request_job()->async_read_bytes().size();
-  if (should_close_connection_first()) {
-    data_pipe.producer_handle.reset();
-  } else {
-    stream_callback->OnAborted();
-  }
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(num_read, mock_url_request_job()->async_read_bytes().size());
-  EXPECT_EQ(0UL, mock_url_request_job()->results().size());
-
-  if (should_close_connection_first()) {
-    stream_callback->OnAborted();
-  } else {
-    data_pipe.producer_handle.reset();
-  }
-  base::RunLoop().RunUntilIdle();
-  ASSERT_EQ(num_read + 1, mock_url_request_job()->async_read_bytes().size());
-  EXPECT_EQ(net::ERR_CONNECTION_RESET,
-            mock_url_request_job()->async_read_bytes().back());
-  ASSERT_EQ(1UL, mock_url_request_job()->results().size());
-  EXPECT_EQ(ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED,
-            mock_url_request_job()->results()[0]);
-}
-
-INSTANTIATE_TEST_SUITE_P(ServiceWorkerDataPipeReaderTest,
-                         ServiceWorkerDataPipeReaderTestP,
-                         testing::Combine(testing::Bool(), testing::Bool()));
-
-}  // namespace content
diff --git a/content/browser/service_worker/service_worker_navigation_loader.cc b/content/browser/service_worker/service_worker_navigation_loader.cc
index 6b4d11d..1ba0cc47 100644
--- a/content/browser/service_worker/service_worker_navigation_loader.cc
+++ b/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -130,9 +130,9 @@
   TRACE_EVENT_WITH_FLOW0(
       "ServiceWorker", "ServiceWorkerNavigationLoader::FallbackToNetwork", this,
       TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
-  // The URLJobWrapper only calls this if this loader never intercepted the
-  // request. Fallback to network after interception uses |fallback_callback_|
-  // instead.
+  // ServiceWorkerControlleeRequestHandler only calls this if this loader never
+  // intercepted the request. Fallback to network after interception uses
+  // |fallback_callback_| instead.
   DCHECK_EQ(response_type_, ResponseType::NOT_DETERMINED);
   response_type_ = ResponseType::FALLBACK_TO_NETWORK;
 
@@ -661,4 +661,13 @@
     completion_time_ = base::TimeTicks::Now();
 }
 
+ServiceWorkerNavigationLoaderWrapper::ServiceWorkerNavigationLoaderWrapper(
+    std::unique_ptr<ServiceWorkerNavigationLoader> loader)
+    : loader_(std::move(loader)) {}
+
+ServiceWorkerNavigationLoaderWrapper::~ServiceWorkerNavigationLoaderWrapper() {
+  if (loader_)
+    loader_.release()->DetachedFromRequest();
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_navigation_loader.h b/content/browser/service_worker/service_worker_navigation_loader.h
index 88b1a1b..8c657f3 100644
--- a/content/browser/service_worker/service_worker_navigation_loader.h
+++ b/content/browser/service_worker/service_worker_navigation_loader.h
@@ -6,6 +6,7 @@
 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_LOADER_H_
 
 #include <memory>
+#include <string>
 #include <vector>
 
 #include "base/macros.h"
@@ -15,7 +16,6 @@
 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
 #include "content/browser/service_worker/service_worker_metrics.h"
 #include "content/browser/service_worker/service_worker_response_type.h"
-#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
 #include "content/browser/url_loader_factory_getter.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "mojo/public/cpp/system/data_pipe.h"
@@ -37,28 +37,50 @@
 // request; once the response is delivered, the resulting client loads
 // subresources via ServiceWorkerSubresourceLoader.
 //
-// This class works similarly to ServiceWorkerURLRequestJob but with
-// network::mojom::URLLoader instead of URLRequest.
-//
-// This class is owned by the job wrapper until it is bound to a URLLoader
-// request. After it is bound |this| is kept alive until the Mojo connection to
-// this URLLoader is dropped.
+// This class is owned by ServiceWorkerControlleeRequestHandler until it is
+// bound to a URLLoader request. After it is bound |this| is kept alive until
+// the Mojo connection to this URLLoader is dropped.
 class CONTENT_EXPORT ServiceWorkerNavigationLoader
     : public network::mojom::URLLoader {
  public:
-  using Delegate = ServiceWorkerURLJobWrapper::Delegate;
   using ResponseType = ServiceWorkerResponseType;
 
+  class CONTENT_EXPORT Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // Will be invoked before the request is restarted. The caller can use this
+    // opportunity to grab state from the ServiceWorkerNavigationLoader to
+    // determine how it should behave when the request is restarted.
+    virtual void OnPrepareToRestart() = 0;
+
+    // Returns the ServiceWorkerVersion fetch events for this request job should
+    // be dispatched to. If no appropriate worker can be determined, returns
+    // nullptr and sets |*result| to an appropriate error.
+    virtual ServiceWorkerVersion* GetServiceWorkerVersion(
+        ServiceWorkerMetrics::URLRequestJobResult* result) = 0;
+
+    // Called after dispatching the fetch event to determine if processing of
+    // the request should still continue, or if processing should be aborted.
+    // When false is returned, this sets |*result| to an appropriate error.
+    virtual bool RequestStillValid(
+        ServiceWorkerMetrics::URLRequestJobResult* result) = 0;
+
+    // Called to signal that loading failed, and that the resource being loaded
+    // was a main resource.
+    virtual void MainResourceLoadFailed() = 0;
+  };
+
   // Created by ServiceWorkerControlleeRequestHandler::MaybeCreateLoader
   // when starting to load a main resource.
   //
   // For the navigation case, this job typically works in the following order:
-  // 1. One of the FallbackTo* or ForwardTo* methods are called via
-  //    URLJobWrapper by ServiceWorkerControlleeRequestHandler, which
-  //    determines how the request should be served (e.g. should fallback
-  //    to network or should be sent to the SW). If it decides to fallback
-  //    to the network this will call |loader_callback| with a null
-  //    RequestHandler, which will be then handled by NavigationURLLoaderImpl.
+  // 1. One of the FallbackTo* or ForwardTo* methods are called by
+  //    ServiceWorkerControlleeRequestHandler, which determines how the request
+  //    should be served (e.g. should fallback to network or should be sent to
+  //    the SW). If it decides to fallback to the network this will call
+  //    |loader_callback| with a null RequestHandler, which will be then handled
+  //    by NavigationURLLoaderImpl.
   // 2. If it is decided that the request should be sent to the SW,
   //    this job calls |loader_callback|, passing StartRequest as the
   //    RequestHandler.
@@ -86,7 +108,7 @@
 
   ~ServiceWorkerNavigationLoader() override;
 
-  // Called via URLJobWrapper.
+  // Called via ServiceWorkerControlleeRequestHandler.
   void FallbackToNetwork();
   void ForwardToServiceWorker();
   bool ShouldFallbackToNetwork();
@@ -214,6 +236,21 @@
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationLoader);
 };
 
+// Owns a loader and calls DetachedFromRequest() to release it.
+class ServiceWorkerNavigationLoaderWrapper {
+ public:
+  explicit ServiceWorkerNavigationLoaderWrapper(
+      std::unique_ptr<ServiceWorkerNavigationLoader> loader);
+  ~ServiceWorkerNavigationLoaderWrapper();
+
+  ServiceWorkerNavigationLoader* get() { return loader_.get(); }
+
+ private:
+  std::unique_ptr<ServiceWorkerNavigationLoader> loader_;
+
+  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationLoaderWrapper);
+};
+
 }  // namespace content
 
 #endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_LOADER_H_
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index 35bce25..1272e45 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -828,7 +828,7 @@
 
   if (!controller_) {
     container_->SetController(std::move(controller_info),
-                              {} /* used_features */, notify_controllerchange);
+                              notify_controllerchange);
     return;
   }
 
@@ -850,12 +850,10 @@
         object_host->CreateCompleteObjectInfoToSend();
 
   // Populate used features for UseCounter purposes.
-  std::vector<blink::mojom::WebFeature> used_features;
   for (const blink::mojom::WebFeature feature : controller_->used_features())
-    used_features.push_back(feature);
+    controller_info->used_features.push_back(feature);
 
-
-  container_->SetController(std::move(controller_info), used_features,
+  container_->SetController(std::move(controller_info),
                             notify_controllerchange);
 }
 
diff --git a/content/browser/service_worker/service_worker_provider_host_unittest.cc b/content/browser/service_worker/service_worker_provider_host_unittest.cc
index 5352e94..a18d110 100644
--- a/content/browser/service_worker/service_worker_provider_host_unittest.cc
+++ b/content/browser/service_worker/service_worker_provider_host_unittest.cc
@@ -441,7 +441,6 @@
 
   void SetController(
       blink::mojom::ControllerServiceWorkerInfoPtr controller_info,
-      const std::vector<blink::mojom::WebFeature>& used_features,
       bool should_notify_controllerchange) override {
     was_set_controller_called_ = true;
   }
diff --git a/content/browser/service_worker/service_worker_request_handler.cc b/content/browser/service_worker/service_worker_request_handler.cc
index ae6a418..eb11e70b 100644
--- a/content/browser/service_worker/service_worker_request_handler.cc
+++ b/content/browser/service_worker/service_worker_request_handler.cc
@@ -15,7 +15,6 @@
 #include "content/browser/service_worker/service_worker_navigation_handle_core.h"
 #include "content/browser/service_worker/service_worker_provider_host.h"
 #include "content/browser/service_worker/service_worker_registration.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/public/browser/resource_context.h"
 #include "content/public/common/child_process_host.h"
diff --git a/content/browser/service_worker/service_worker_url_job_wrapper.cc b/content/browser/service_worker/service_worker_url_job_wrapper.cc
deleted file mode 100644
index 9df6d06..0000000
--- a/content/browser/service_worker/service_worker_url_job_wrapper.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
-
-#include "content/browser/service_worker/service_worker_navigation_loader.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
-#include "content/public/browser/resource_request_info.h"
-#include "content/public/common/content_switches.h"
-
-namespace content {
-
-ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper(
-    base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job)
-    : url_request_job_(std::move(url_request_job)) {}
-
-ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper(
-    std::unique_ptr<ServiceWorkerNavigationLoader> url_loader_job)
-    : url_loader_job_(std::move(url_loader_job)) {}
-
-ServiceWorkerURLJobWrapper::~ServiceWorkerURLJobWrapper() {
-  if (url_loader_job_) {
-    // Detach the URLLoader from this wrapper (and therefore
-    // from the request handler). This may delete the
-    // |url_loader_job_| or may make it self-owned if it is
-    // bound to a Mojo endpoint.
-    url_loader_job_.release()->DetachedFromRequest();
-  }
-}
-
-void ServiceWorkerURLJobWrapper::FallbackToNetwork() {
-  if (url_loader_job_) {
-    url_loader_job_->FallbackToNetwork();
-  } else {
-    url_request_job_->FallbackToNetwork();
-  }
-}
-
-void ServiceWorkerURLJobWrapper::FallbackToNetworkOrRenderer() {
-  if (url_loader_job_) {
-    // Fallback to renderer is used when CORS checks need to be performed on the
-    // request. CORS doesn't apply to navigations, and |url_loader_job_| is for
-    // navigations, so just use FallbackToNetwork().
-    url_loader_job_->FallbackToNetwork();
-  } else {
-    url_request_job_->FallbackToNetworkOrRenderer();
-  }
-}
-
-void ServiceWorkerURLJobWrapper::ForwardToServiceWorker() {
-  if (url_loader_job_) {
-    url_loader_job_->ForwardToServiceWorker();
-  } else {
-    url_request_job_->ForwardToServiceWorker();
-  }
-}
-
-bool ServiceWorkerURLJobWrapper::ShouldFallbackToNetwork() {
-  if (url_loader_job_) {
-    return url_loader_job_->ShouldFallbackToNetwork();
-  } else {
-    return url_request_job_->ShouldFallbackToNetwork();
-  }
-}
-
-bool ServiceWorkerURLJobWrapper::ShouldForwardToServiceWorker() {
-  if (url_loader_job_) {
-    return url_loader_job_->ShouldForwardToServiceWorker();
-  } else {
-    return url_request_job_->ShouldForwardToServiceWorker();
-  }
-}
-
-void ServiceWorkerURLJobWrapper::FailDueToLostController() {
-  // This function is only called for subresource requests, so it can't
-  // be called for |url_loader_job_|, which is for navigations.
-  DCHECK(!url_loader_job_);
-  url_request_job_->FailDueToLostController();
-}
-
-bool ServiceWorkerURLJobWrapper::IsAlive() const {
-  return url_loader_job_ || url_request_job_;
-}
-
-}  // namespace content
diff --git a/content/browser/service_worker/service_worker_url_job_wrapper.h b/content/browser/service_worker/service_worker_url_job_wrapper.h
deleted file mode 100644
index a35209e..0000000
--- a/content/browser/service_worker/service_worker_url_job_wrapper.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_JOB_WRAPPER_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_JOB_WRAPPER_H_
-
-#include "base/macros.h"
-#include "content/browser/loader/navigation_loader_interceptor.h"
-#include "content/browser/service_worker/service_worker_metrics.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-class ServiceWorkerURLRequestJob;
-class ServiceWorkerNavigationLoader;
-class ServiceWorkerVersion;
-
-// This class is a helper to support having
-// ServiceWorkerControlleeRequestHandler work with both URLRequestJobs and
-// network::mojom::URLLoaders (that is, both for S13nServiceWorker and
-// non-S13nServiceWorker). It wraps either a
-// ServiceWorkerURLRequestJob or a callback for URLLoader and forwards to the
-// underlying implementation.
-class CONTENT_EXPORT ServiceWorkerURLJobWrapper {
- public:
-  // A helper used by the ServiceWorkerNavigationLoader or
-  // ServiceWorkerURLRequestJob.
-  class CONTENT_EXPORT Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // Will be invoked before the request is restarted. The caller
-    // can use this opportunity to grab state from the
-    // ServiceWorkerNavigationLoader or ServiceWorkerURLRequestJob to determine
-    // how it should behave when the request is restarted.
-    virtual void OnPrepareToRestart() = 0;
-
-    // Returns the ServiceWorkerVersion fetch events for this request job should
-    // be dispatched to. If no appropriate worker can be determined, returns
-    // nullptr and sets |*result| to an appropriate error.
-    virtual ServiceWorkerVersion* GetServiceWorkerVersion(
-        ServiceWorkerMetrics::URLRequestJobResult* result) = 0;
-
-    // Called after dispatching the fetch event to determine if processing of
-    // the request should still continue, or if processing should be aborted.
-    // When false is returned, this sets |*result| to an appropriate error.
-    virtual bool RequestStillValid(
-        ServiceWorkerMetrics::URLRequestJobResult* result) = 0;
-
-    // Called to signal that loading failed, and that the resource being loaded
-    // was a main resource.
-    virtual void MainResourceLoadFailed() {}
-  };
-
-  // Non-S13nServiceWorker.
-  explicit ServiceWorkerURLJobWrapper(
-      base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job);
-
-  // S13nServiceWorker.
-  explicit ServiceWorkerURLJobWrapper(
-      std::unique_ptr<ServiceWorkerNavigationLoader> url_loader_job);
-
-  ~ServiceWorkerURLJobWrapper();
-
-  // Sets the response type.
-  void FallbackToNetwork();
-  void FallbackToNetworkOrRenderer();
-  void ForwardToServiceWorker();
-
-  // Returns true if this job should not be handled by a service worker, but
-  // instead should fallback to the network.
-  bool ShouldFallbackToNetwork();
-
-  // Returns true if this job should be forwarded to a service worker.
-  bool ShouldForwardToServiceWorker();
-
-  // Tells the job to abort with a start error. Currently this is only called
-  // because the controller was lost. This function could be made more generic
-  // if needed later.
-  void FailDueToLostController();
-
-  // Returns true if the underlying job has not been destroyed. This only useful
-  // in the non-S13nServiceWorker case, since this wrapper owns the job in the
-  // S13nServiceWorker case.
-  bool IsAlive() const;
-
- private:
-  enum class JobType { kURLRequest, kURLLoader };
-  base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job_;
-  std::unique_ptr<ServiceWorkerNavigationLoader> url_loader_job_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerURLJobWrapper);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_JOB_WRAPPER_H_
diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc
deleted file mode 100644
index 395bea7..0000000
--- a/content/browser/service_worker/service_worker_url_request_job.cc
+++ /dev/null
@@ -1,877 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/service_worker/service_worker_url_request_job.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
-#include "base/guid.h"
-#include "base/location.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/task/post_task.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "content/browser/resource_context_impl.h"
-#include "content/browser/service_worker/embedded_worker_instance.h"
-#include "content/browser/service_worker/service_worker_blob_reader.h"
-#include "content/browser/service_worker/service_worker_data_pipe_reader.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
-#include "content/browser/service_worker/service_worker_response_info.h"
-#include "content/common/fetch/fetch_request_type_converters.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/browser/blob_handle.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/resource_request_info.h"
-#include "content/public/browser/service_worker_context.h"
-#include "content/public/common/content_features.h"
-#include "content/public/common/referrer.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_request_headers.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_response_info.h"
-#include "net/http/http_util.h"
-#include "net/log/net_log.h"
-#include "net/log/net_log_event_type.h"
-#include "net/log/net_log_with_source.h"
-#include "services/network/public/cpp/resource_request_body.h"
-#include "storage/browser/blob/blob_data_builder.h"
-#include "storage/browser/blob/blob_data_handle.h"
-#include "storage/browser/blob/blob_impl.h"
-#include "storage/browser/blob/blob_storage_context.h"
-#include "ui/base/page_transition_types.h"
-
-namespace content {
-
-namespace {
-
-net::URLRequestStatus ServiceWorkerResponseErrorToNetStatus(
-    blink::mojom::ServiceWorkerResponseError error) {
-  if (error ==
-      blink::mojom::ServiceWorkerResponseError::kDataPipeCreationFailed) {
-    return net::URLRequestStatus::FromError(net::ERR_INSUFFICIENT_RESOURCES);
-  }
-
-  // TODO(falken): Add more mapping to net errors.
-  return net::URLRequestStatus::FromError(net::ERR_FAILED);
-}
-
-net::NetLogEventType RequestJobResultToNetEventType(
-    ServiceWorkerMetrics::URLRequestJobResult result) {
-  using n = net::NetLogEventType;
-  using m = ServiceWorkerMetrics;
-  switch (result) {
-    case m::REQUEST_JOB_FALLBACK_RESPONSE:
-      return n::SERVICE_WORKER_FALLBACK_RESPONSE;
-    case m::REQUEST_JOB_FALLBACK_FOR_CORS:
-      return n::SERVICE_WORKER_FALLBACK_FOR_CORS;
-    case m::REQUEST_JOB_HEADERS_ONLY_RESPONSE:
-      return n::SERVICE_WORKER_HEADERS_ONLY_RESPONSE;
-    case m::REQUEST_JOB_STREAM_RESPONSE:
-      return n::SERVICE_WORKER_STREAM_RESPONSE;
-    case m::REQUEST_JOB_BLOB_RESPONSE:
-      return n::SERVICE_WORKER_BLOB_RESPONSE;
-    case m::REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO:
-      return n::SERVICE_WORKER_ERROR_RESPONSE_STATUS_ZERO;
-    case m::REQUEST_JOB_ERROR_BAD_BLOB:
-      return n::SERVICE_WORKER_ERROR_BAD_BLOB;
-    case m::REQUEST_JOB_ERROR_NO_PROVIDER_HOST:
-      return n::SERVICE_WORKER_ERROR_NO_PROVIDER_HOST;
-    case m::REQUEST_JOB_ERROR_NO_ACTIVE_VERSION:
-      return n::SERVICE_WORKER_ERROR_NO_ACTIVE_VERSION;
-    case m::REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH:
-      return n::SERVICE_WORKER_ERROR_FETCH_EVENT_DISPATCH;
-    case m::REQUEST_JOB_ERROR_BLOB_READ:
-      return n::SERVICE_WORKER_ERROR_BLOB_READ;
-    case m::REQUEST_JOB_ERROR_STREAM_ABORTED:
-      return n::SERVICE_WORKER_ERROR_STREAM_ABORTED;
-    case m::REQUEST_JOB_ERROR_KILLED:
-      return n::SERVICE_WORKER_ERROR_KILLED;
-    case m::REQUEST_JOB_ERROR_KILLED_WITH_BLOB:
-      return n::SERVICE_WORKER_ERROR_KILLED_WITH_BLOB;
-    case m::REQUEST_JOB_ERROR_KILLED_WITH_STREAM:
-      return n::SERVICE_WORKER_ERROR_KILLED_WITH_STREAM;
-    case m::REQUEST_JOB_ERROR_BAD_DELEGATE:
-      return n::SERVICE_WORKER_ERROR_BAD_DELEGATE;
-    case m::REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED:
-      return n::SERVICE_WORKER_ERROR_REQUEST_BODY_BLOB_FAILED;
-    // Invalid type.
-    case m::NUM_REQUEST_JOB_RESULT_TYPES:
-      NOTREACHED() << result;
-  }
-  NOTREACHED() << result;
-  return n::FAILED;
-}
-
-}  // namespace
-
-// A helper for recording navigation preload UMA. The UMA is recorded
-// after both service worker preparation finished and the
-// navigation preload response arrived.
-class ServiceWorkerURLRequestJob::NavigationPreloadMetrics {
- public:
-  explicit NavigationPreloadMetrics(ServiceWorkerURLRequestJob* owner)
-      : owner_(owner) {}
-  ~NavigationPreloadMetrics() {}
-
-  // Called when service worker preparation finished.
-  void ReportWorkerPreparationFinished() {
-    DCHECK(!owner_->worker_start_time_.is_null());
-    DCHECK(!owner_->worker_ready_time_.is_null());
-    switch (phase_) {
-      case Phase::INITIAL:
-        phase_ = Phase::WORKER_PREPARATION_FINISHED;
-        break;
-      case Phase::NAV_PRELOAD_FINISHED:
-        phase_ = Phase::BOTH_FINISHED;
-        Complete();
-        break;
-      case Phase::DO_NOT_RECORD:
-        return;
-      case Phase::BOTH_FINISHED:
-      case Phase::WORKER_PREPARATION_FINISHED:
-      case Phase::RECORDED:
-        NOTREACHED();
-    }
-  }
-
-  // Called when the navigation preload response arrived.
-  void ReportNavigationPreloadFinished() {
-    navigation_preload_response_time_ = base::TimeTicks::Now();
-    switch (phase_) {
-      case Phase::INITIAL:
-        phase_ = Phase::NAV_PRELOAD_FINISHED;
-        break;
-      case Phase::WORKER_PREPARATION_FINISHED:
-        phase_ = Phase::BOTH_FINISHED;
-        Complete();
-        break;
-      case Phase::DO_NOT_RECORD:
-        return;
-      case Phase::BOTH_FINISHED:
-      case Phase::NAV_PRELOAD_FINISHED:
-      case Phase::RECORDED:
-        NOTREACHED();
-    }
-  }
-
-  // After Abort() is called, no navigation preload UMA will be recorded for
-  // this navigation.
-  void Abort() {
-    DCHECK_NE(phase_, Phase::RECORDED);
-    phase_ = Phase::DO_NOT_RECORD;
-  }
-
- private:
-  enum class Phase {
-    INITIAL,
-    WORKER_PREPARATION_FINISHED,
-    NAV_PRELOAD_FINISHED,
-    BOTH_FINISHED,
-    RECORDED,
-    DO_NOT_RECORD
-  };
-
-  void Complete() {
-    DCHECK_EQ(phase_, Phase::BOTH_FINISHED);
-    ServiceWorkerMetrics::RecordNavigationPreloadResponse(
-        owner_->worker_ready_time_ - owner_->worker_start_time_,
-        navigation_preload_response_time_ - owner_->worker_start_time_,
-        owner_->initial_worker_status_, owner_->worker_start_situation_,
-        owner_->resource_type_);
-    phase_ = Phase::RECORDED;
-  }
-
-  // Owns and must outlive |this|.
-  ServiceWorkerURLRequestJob* owner_;
-
-  base::TimeTicks navigation_preload_response_time_;
-  Phase phase_ = Phase::INITIAL;
-
-  DISALLOW_COPY_AND_ASSIGN(NavigationPreloadMetrics);
-};
-
-ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
-    net::URLRequest* request,
-    net::NetworkDelegate* network_delegate,
-    base::WeakPtr<ServiceWorkerProviderHost> provider_host,
-    base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
-    const ResourceContext* resource_context,
-    network::mojom::FetchRequestMode request_mode,
-    network::mojom::FetchCredentialsMode credentials_mode,
-    network::mojom::FetchRedirectMode redirect_mode,
-    const std::string& integrity,
-    bool keepalive,
-    ResourceType resource_type,
-    blink::mojom::RequestContextType request_context_type,
-    network::mojom::RequestContextFrameType frame_type,
-    scoped_refptr<network::ResourceRequestBody> body,
-    Delegate* delegate)
-    : net::URLRequestJob(request, network_delegate),
-      delegate_(delegate),
-      response_type_(ResponseType::NOT_DETERMINED),
-      is_started_(false),
-      fetch_response_type_(network::mojom::FetchResponseType::kDefault),
-      provider_host_(std::move(provider_host)),
-      blob_storage_context_(blob_storage_context),
-      resource_context_(resource_context),
-      request_mode_(request_mode),
-      credentials_mode_(credentials_mode),
-      redirect_mode_(redirect_mode),
-      integrity_(integrity),
-      keepalive_(keepalive),
-      resource_type_(resource_type),
-      request_context_type_(request_context_type),
-      frame_type_(frame_type),
-      fall_back_required_(false),
-      body_(body),
-      weak_factory_(this) {
-  DCHECK(delegate_) << "ServiceWorkerURLRequestJob requires a delegate";
-}
-
-ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() {
-  data_pipe_reader_.reset();
-
-  if (!ShouldRecordResult())
-    return;
-
-  ServiceWorkerMetrics::URLRequestJobResult result =
-      ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED;
-  if (response_body_type_ == STREAM)
-    result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_STREAM;
-  else if (response_body_type_ == BLOB)
-    result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_BLOB;
-  RecordResult(result);
-}
-
-void ServiceWorkerURLRequestJob::FallbackToNetwork() {
-  DCHECK_EQ(ResponseType::NOT_DETERMINED, response_type_);
-  DCHECK(!IsFallbackToRendererNeeded());
-  response_type_ = ResponseType::FALLBACK_TO_NETWORK;
-  MaybeStartRequest();
-}
-
-void ServiceWorkerURLRequestJob::FallbackToNetworkOrRenderer() {
-  DCHECK_EQ(ResponseType::NOT_DETERMINED, response_type_);
-  if (IsFallbackToRendererNeeded()) {
-    response_type_ = ResponseType::FALLBACK_TO_RENDERER;
-  } else {
-    response_type_ = ResponseType::FALLBACK_TO_NETWORK;
-  }
-  MaybeStartRequest();
-}
-
-void ServiceWorkerURLRequestJob::ForwardToServiceWorker() {
-  DCHECK_EQ(ResponseType::NOT_DETERMINED, response_type_);
-  response_type_ = ResponseType::FORWARD_TO_SERVICE_WORKER;
-  MaybeStartRequest();
-}
-
-void ServiceWorkerURLRequestJob::FailDueToLostController() {
-  DCHECK_EQ(ResponseType::NOT_DETERMINED, response_type_);
-  response_type_ = ResponseType::FAIL_DUE_TO_LOST_CONTROLLER;
-  MaybeStartRequest();
-}
-
-void ServiceWorkerURLRequestJob::Start() {
-  is_started_ = true;
-  MaybeStartRequest();
-}
-
-void ServiceWorkerURLRequestJob::Kill() {
-  net::URLRequestJob::Kill();
-  data_pipe_reader_.reset();
-  fetch_dispatcher_.reset();
-  blob_reader_.reset();
-  weak_factory_.InvalidateWeakPtrs();
-}
-
-net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const {
-  // TODO(kinuko): refine this for better debug.
-  return net::URLRequestJob::GetLoadState();
-}
-
-bool ServiceWorkerURLRequestJob::GetCharset(std::string* charset) {
-  if (!http_info())
-    return false;
-  return http_info()->headers->GetCharset(charset);
-}
-
-bool ServiceWorkerURLRequestJob::GetMimeType(std::string* mime_type) const {
-  if (!http_info())
-    return false;
-  return http_info()->headers->GetMimeType(mime_type);
-}
-
-void ServiceWorkerURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
-  if (!http_info())
-    return;
-  const base::Time request_time = info->request_time;
-  *info = *http_info();
-  info->request_time = request_time;
-  info->response_time = response_time_;
-}
-
-void ServiceWorkerURLRequestJob::GetLoadTimingInfo(
-    net::LoadTimingInfo* load_timing_info) const {
-  *load_timing_info = load_timing_info_;
-}
-
-void ServiceWorkerURLRequestJob::SetExtraRequestHeaders(
-    const net::HttpRequestHeaders& headers) {
-  std::string range_header;
-  std::vector<net::HttpByteRange> ranges;
-  if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header) ||
-      !net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
-    return;
-  }
-
-  // We don't support multiple range requests in one single URL request.
-  if (ranges.size() == 1U)
-    byte_range_ = ranges[0];
-}
-
-int ServiceWorkerURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
-  DCHECK(buf);
-  DCHECK_GE(buf_size, 0);
-
-  if (data_pipe_reader_)
-    return data_pipe_reader_->ReadRawData(buf, buf_size);
-  if (blob_reader_)
-    return blob_reader_->ReadRawData(buf, buf_size);
-
-  return 0;
-}
-
-void ServiceWorkerURLRequestJob::OnResponseStarted() {
-  if (response_time_.is_null())
-    response_time_ = base::Time::Now();
-  CommitResponseHeader();
-}
-
-void ServiceWorkerURLRequestJob::OnReadRawDataComplete(int bytes_read) {
-  ReadRawDataComplete(bytes_read);
-}
-
-void ServiceWorkerURLRequestJob::RecordResult(
-    ServiceWorkerMetrics::URLRequestJobResult result) {
-  // It violates style guidelines to handle a NOTREACHED() failure but if there
-  // is a bug don't let it corrupt UMA results by double-counting.
-  if (!ShouldRecordResult()) {
-    NOTREACHED();
-    return;
-  }
-  did_record_result_ = true;
-  ServiceWorkerMetrics::RecordURLRequestJobResult(IsMainResourceLoad(), result);
-  request()->net_log().AddEvent(RequestJobResultToNetEventType(result));
-}
-
-base::WeakPtr<ServiceWorkerURLRequestJob>
-ServiceWorkerURLRequestJob::GetWeakPtr() {
-  return weak_factory_.GetWeakPtr();
-}
-
-const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
-  if (!http_response_info_)
-    return nullptr;
-  if (range_response_info_)
-    return range_response_info_.get();
-  return http_response_info_.get();
-}
-
-void ServiceWorkerURLRequestJob::MaybeStartRequest() {
-  if (is_started_ && response_type_ != ResponseType::NOT_DETERMINED) {
-    // Start asynchronously.
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(&ServiceWorkerURLRequestJob::StartRequest,
-                                  weak_factory_.GetWeakPtr()));
-  }
-}
-
-void ServiceWorkerURLRequestJob::StartRequest() {
-  request()->net_log().AddEvent(
-      net::NetLogEventType::SERVICE_WORKER_START_REQUEST);
-
-  switch (response_type_) {
-    case ResponseType::NOT_DETERMINED:
-      NOTREACHED();
-      return;
-
-    case ResponseType::FAIL_DUE_TO_LOST_CONTROLLER:
-      request()->net_log().AddEvent(
-          net::NetLogEventType::SERVICE_WORKER_ERROR_NO_ACTIVE_VERSION);
-      NotifyStartError(net::URLRequestStatus::FromError(net::ERR_FAILED));
-      return;
-
-    case ResponseType::FALLBACK_TO_NETWORK:
-      FinalizeFallbackToNetwork();
-      return;
-
-    case ResponseType::FALLBACK_TO_RENDERER:
-      FinalizeFallbackToRenderer();
-      return;
-
-    case ResponseType::FORWARD_TO_SERVICE_WORKER:
-      ForwardRequestToServiceWorker();
-      return;
-  }
-
-  NOTREACHED();
-}
-
-// The network::ResourceRequest will be converted to
-// blink::mojom::FetchAPIRequestPtr to be passed to the renderer and be
-// converted to blink::WebServiceWorkerRequest in
-// ServiceWorkerContextClient::ToWebServiceWorkerRequestForFetchEvent. So make
-// sure the fields set here are consistent with the fields read there.
-// TODO(crbug.com/911930): Create blink::mojom::FetchAPIRequestPtr directly here
-// instead of network::ResourceRequest.
-std::unique_ptr<network::ResourceRequest>
-ServiceWorkerURLRequestJob::CreateResourceRequest() {
-  auto request = std::make_unique<network::ResourceRequest>();
-  request->url = request_->url();
-  request->method = request_->method();
-
-  for (net::HttpRequestHeaders::Iterator it(request_->extra_request_headers());
-       it.GetNext();) {
-    request->headers.SetHeader(it.name(), it.value());
-  }
-
-  request->referrer = GURL(request_->referrer());
-  request->referrer_policy = request_->referrer_policy();
-  request->fetch_request_mode = request_mode_;
-  request->resource_type = resource_type_;
-  request->fetch_credentials_mode = credentials_mode_;
-  request->load_flags = request_->load_flags();
-  request->fetch_redirect_mode = redirect_mode_;
-  request->fetch_request_context_type = static_cast<int>(request_context_type_);
-  request->fetch_frame_type = frame_type_;
-  ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
-  if (info)
-    request->transition_type = info->GetPageTransition();
-  request->fetch_integrity = integrity_;
-  request->keepalive = keepalive_;
-  // Set the request window id if we have one. If we don't, or the provider
-  // host is gone, it just means client certification authentication may fail
-  // so continue on without it anyway.
-  if (provider_host_ && provider_host_->fetch_request_window_id()) {
-    request->fetch_window_id =
-        base::make_optional(provider_host_->fetch_request_window_id());
-  }
-  return request;
-}
-
-bool ServiceWorkerURLRequestJob::ShouldRecordNavigationMetrics(
-    const ServiceWorkerVersion* version) const {
-  // Don't record navigation metrics in the following situations.
-  // 1) The worker was in state INSTALLED or ACTIVATING, and the browser had to
-  //    wait for it to become ACTIVATED. This is to avoid including the time to
-  //    execute the activate event handlers in the worker's script.
-  if (!worker_already_activated_) {
-    return false;
-  }
-  // 2) The worker was started for the fetch AND DevTools was attached during
-  //    startup. This is intended to avoid including the time for debugging.
-  if (version->skip_recording_startup_time() &&
-      initial_worker_status_ != EmbeddedWorkerStatus::RUNNING) {
-    return false;
-  }
-  // 3) The request is for New Tab Page. This is because it tends to dominate
-  //    the stats and makes the results largely skewed.
-  if (ServiceWorkerMetrics::ShouldExcludeSiteFromHistogram(
-          version->site_for_uma())) {
-    return false;
-  }
-
-  return true;
-}
-
-void ServiceWorkerURLRequestJob::DidPrepareFetchEvent(
-    scoped_refptr<ServiceWorkerVersion> version) {
-  worker_ready_time_ = base::TimeTicks::Now();
-  load_timing_info_.send_start = worker_ready_time_;
-  worker_start_situation_ = version->embedded_worker()->start_situation();
-
-  if (!ShouldRecordNavigationMetrics(version.get())) {
-    nav_preload_metrics_->Abort();
-    return;
-  }
-  if (resource_type_ == RESOURCE_TYPE_MAIN_FRAME) {
-    // Record the time taken for the browser to find and possibly start an
-    // active worker to which to dispatch a FetchEvent for a main frame resource
-    // request. For context, a FetchEvent can only be dispatched to an ACTIVATED
-    // worker that is running (it has been successfully started). The
-    // measurements starts when the browser process receives the request. The
-    // browser then finds the worker appropriate for this request (if there is
-    // none, this metric is not recorded). If that worker is already started,
-    // the browser process can send the request to it, so the measurement ends
-    // quickly. Otherwise the browser process has to start the worker and the
-    // measurement ends when the worker is successfully started.
-    ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame(
-        worker_ready_time_ - request()->creation_time(), initial_worker_status_,
-        worker_start_situation_, did_navigation_preload_, request_->url());
-  }
-  nav_preload_metrics_->ReportWorkerPreparationFinished();
-}
-
-void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
-    blink::ServiceWorkerStatusCode status,
-    ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
-    blink::mojom::FetchAPIResponsePtr response,
-    blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
-    blink::mojom::ServiceWorkerFetchEventTimingPtr timing,
-    scoped_refptr<ServiceWorkerVersion> version) {
-  // Do not clear |fetch_dispatcher_| if it has dispatched a navigation preload
-  // request to keep the network::mojom::URLLoader related objects in it,
-  // because the preload response might still need to be streamed even after
-  // calling respondWith().
-  if (!did_navigation_preload_) {
-    fetch_dispatcher_.reset();
-  }
-  ServiceWorkerMetrics::RecordFetchEventStatus(IsMainResourceLoad(), status);
-
-  ServiceWorkerMetrics::URLRequestJobResult result =
-      ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
-  if (!delegate_->RequestStillValid(&result)) {
-    RecordResult(result);
-    DeliverErrorResponse();
-    return;
-  }
-
-  if (status != blink::ServiceWorkerStatusCode::kOk) {
-    RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH);
-    if (IsMainResourceLoad()) {
-      // Using the service worker failed, so fallback to network.
-      delegate_->MainResourceLoadFailed();
-      FinalizeFallbackToNetwork();
-    } else {
-      DeliverErrorResponse();
-    }
-    return;
-  }
-
-  if (fetch_result ==
-      ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback) {
-    ServiceWorkerMetrics::RecordFallbackedRequestMode(request_mode_);
-    if (IsFallbackToRendererNeeded()) {
-      FinalizeFallbackToRenderer();
-    } else {
-      FinalizeFallbackToNetwork();
-    }
-    return;
-  }
-
-  // We should have a response now.
-  DCHECK_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
-            fetch_result);
-
-  // A response with status code 0 is Blink telling us to respond with network
-  // error.
-  if (response->status_code == 0) {
-    RecordStatusZeroResponseError(response->error);
-    NotifyStartError(ServiceWorkerResponseErrorToNetStatus(response->error));
-    return;
-  }
-
-  load_timing_info_.send_end = base::TimeTicks::Now();
-
-  // Creates a new HttpResponseInfo using the the ServiceWorker script's
-  // HttpResponseInfo to show HTTPS padlock.
-  // TODO(horo): When we support mixed-content (HTTP) no-cors requests from a
-  // ServiceWorker, we have to check the security level of the responses.
-  DCHECK(!http_response_info_);
-  DCHECK(version);
-  const net::HttpResponseInfo* main_script_http_info =
-      version->GetMainScriptHttpResponseInfo();
-  DCHECK(main_script_http_info);
-  http_response_info_.reset(new net::HttpResponseInfo(*main_script_http_info));
-
-  // Process stream using Mojo's data pipe.
-  if (!body_as_stream.is_null()) {
-    SetResponseBodyType(STREAM);
-    SetResponse(std::move(response));
-    data_pipe_reader_.reset(
-        new ServiceWorkerDataPipeReader(this, std::move(body_as_stream)));
-    data_pipe_reader_->Start();
-    return;
-  }
-
-  // Set up a request for reading the blob.
-  // TODO(falken): Can we just read |response->blob->blob| directly like in
-  // ServiceWorkerNavigationLoader?
-  if (response->blob && blob_storage_context_) {
-    DCHECK(!response->blob->uuid.empty());
-    DCHECK(response->blob->blob.is_valid());
-    SetResponseBodyType(BLOB);
-    std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
-        blob_storage_context_->GetBlobDataFromUUID(response->blob->uuid);
-    if (!blob_data_handle) {
-      // The renderer gave us a bad blob UUID.
-      RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_BLOB);
-      DeliverErrorResponse();
-      return;
-    }
-    blob_reader_.reset(new ServiceWorkerBlobReader(this));
-    blob_reader_->Start(std::move(blob_data_handle), request()->context());
-  }
-
-  SetResponse(std::move(response));
-  if (!blob_reader_) {
-    RecordResult(ServiceWorkerMetrics::REQUEST_JOB_HEADERS_ONLY_RESPONSE);
-    CommitResponseHeader();
-  }
-}
-
-void ServiceWorkerURLRequestJob::SetResponse(
-    blink::mojom::FetchAPIResponsePtr response) {
-  response_url_list_ = std::move(response->url_list);
-  fetch_response_type_ = response->response_type;
-  cors_exposed_header_names_ = std::move(response->cors_exposed_header_names);
-  response_time_ = response->response_time;
-  CreateResponseHeader(response->status_code, response->status_text,
-                       std::move(response->headers));
-  load_timing_info_.receive_headers_start = base::TimeTicks::Now();
-  load_timing_info_.receive_headers_end =
-      load_timing_info_.receive_headers_start;
-
-  response_is_in_cache_storage_ =
-      response->response_source ==
-      network::mojom::FetchResponseSource::kCacheStorage;
-  if (response->cache_storage_cache_name) {
-    response_cache_storage_cache_name_ =
-        std::move(*(response->cache_storage_cache_name));
-  } else {
-    response_cache_storage_cache_name_.clear();
-  }
-}
-
-void ServiceWorkerURLRequestJob::CreateResponseHeader(
-    int status_code,
-    const std::string& status_text,
-    ResponseHeaderMap headers) {
-  // Build a string instead of using HttpResponseHeaders::AddHeader on
-  // each header, since AddHeader has O(n^2) performance.
-  std::string buf(base::StringPrintf("HTTP/1.1 %d %s\r\n", status_code,
-                                     status_text.c_str()));
-  for (auto& item : headers) {
-    buf.append(std::move(item.first));
-    buf.append(": ");
-    buf.append(std::move(item.second));
-    buf.append("\r\n");
-  }
-  buf.append("\r\n");
-  http_response_headers_ = new net::HttpResponseHeaders(
-      net::HttpUtil::AssembleRawHeaders(buf.c_str(), buf.size()));
-}
-
-void ServiceWorkerURLRequestJob::CommitResponseHeader() {
-  if (!http_response_info_)
-    http_response_info_.reset(new net::HttpResponseInfo());
-  http_response_info_->headers.swap(http_response_headers_);
-  http_response_info_->vary_data = net::HttpVaryData();
-  http_response_info_->metadata =
-      blob_reader_ ? blob_reader_->response_metadata() : nullptr;
-  NotifyHeadersComplete();
-}
-
-void ServiceWorkerURLRequestJob::DeliverErrorResponse() {
-  // TODO(falken): Print an error to the console of the ServiceWorker and of
-  // the requesting page.
-  CreateResponseHeader(500, "Service Worker Response Error",
-                       ResponseHeaderMap());
-  CommitResponseHeader();
-}
-
-void ServiceWorkerURLRequestJob::FinalizeFallbackToNetwork() {
-  // Restart this request to create a new job. The default job (which will hit
-  // network) will be created in the next time because our request handler will
-  // return nullptr after restarting and this means our interceptor does not
-  // intercept.
-  if (ShouldRecordResult())
-    RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_RESPONSE);
-  response_type_ = ResponseType::FALLBACK_TO_NETWORK;
-  NotifyRestartRequired();
-  return;
-}
-
-void ServiceWorkerURLRequestJob::FinalizeFallbackToRenderer() {
-  fall_back_required_ = true;
-  if (ShouldRecordResult())
-    RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_FOR_CORS);
-  CreateResponseHeader(400, "Service Worker Fallback Required",
-                       ResponseHeaderMap());
-  response_type_ = ResponseType::FALLBACK_TO_RENDERER;
-  CommitResponseHeader();
-}
-
-bool ServiceWorkerURLRequestJob::IsFallbackToRendererNeeded() const {
-  // When the request_mode is |CORS| or |CORS-with-forced-preflight| and the
-  // origin of the request URL is different from the security origin of the
-  // document, we can't simply fallback to the network in the browser process.
-  // It is because the CORS preflight logic is implemented in the renderer. So
-  // we return a fall_back_required response to the renderer.
-  return !IsMainResourceLoad() &&
-         (request_mode_ == network::mojom::FetchRequestMode::kCors ||
-          request_mode_ ==
-              network::mojom::FetchRequestMode::kCorsWithForcedPreflight) &&
-         (!request()->initiator().has_value() ||
-          !request()->initiator()->IsSameOriginWith(
-              url::Origin::Create(request()->url())));
-}
-
-void ServiceWorkerURLRequestJob::SetResponseBodyType(ResponseBodyType type) {
-  DCHECK_EQ(response_body_type_, UNKNOWN);
-  DCHECK_NE(type, UNKNOWN);
-  response_body_type_ = type;
-}
-
-bool ServiceWorkerURLRequestJob::ShouldRecordResult() {
-  return !did_record_result_ && is_started_ &&
-         response_type_ == ResponseType::FORWARD_TO_SERVICE_WORKER;
-}
-
-void ServiceWorkerURLRequestJob::RecordStatusZeroResponseError(
-    blink::mojom::ServiceWorkerResponseError error) {
-  // It violates style guidelines to handle a NOTREACHED() failure but if there
-  // is a bug don't let it corrupt UMA results by double-counting.
-  if (!ShouldRecordResult()) {
-    NOTREACHED();
-    return;
-  }
-  RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO);
-  ServiceWorkerMetrics::RecordStatusZeroResponseError(IsMainResourceLoad(),
-                                                      error);
-}
-
-void ServiceWorkerURLRequestJob::NotifyHeadersComplete() {
-  OnStartCompleted();
-  URLRequestJob::NotifyHeadersComplete();
-}
-
-void ServiceWorkerURLRequestJob::NotifyStartError(
-    net::URLRequestStatus status) {
-  OnStartCompleted();
-  URLRequestJob::NotifyStartError(status);
-}
-
-void ServiceWorkerURLRequestJob::NotifyRestartRequired() {
-  ServiceWorkerResponseInfo::ForRequest(request_, true)
-      ->OnPrepareToRestart(worker_start_time_, worker_ready_time_,
-                           did_navigation_preload_);
-  delegate_->OnPrepareToRestart();
-  URLRequestJob::NotifyRestartRequired();
-}
-
-void ServiceWorkerURLRequestJob::OnStartCompleted() const {
-  switch (response_type_) {
-    case ResponseType::NOT_DETERMINED:
-      NOTREACHED();
-      return;
-    case ResponseType::FAIL_DUE_TO_LOST_CONTROLLER:
-    case ResponseType::FALLBACK_TO_NETWORK:
-      // Indicate that the service worker did not respond to the request.
-      ServiceWorkerResponseInfo::ForRequest(request_, true)
-          ->OnStartCompleted(
-              false /* was_fetched_via_service_worker */,
-              false /* was_fallback_required */,
-              std::vector<GURL>() /* url_list_via_service_worker */,
-              network::mojom::FetchResponseType::kDefault,
-              base::TimeTicks() /* service_worker_start_time */,
-              base::TimeTicks() /* service_worker_ready_time */,
-              false /* response_is_in_cache_storage */,
-              std::string() /* response_cache_storage_cache_name */,
-              ServiceWorkerHeaderList() /* cors_exposed_header_names */,
-              did_navigation_preload_);
-      break;
-    case ResponseType::FALLBACK_TO_RENDERER:
-    case ResponseType::FORWARD_TO_SERVICE_WORKER:
-      // Indicate that the service worker responded to the request, which is
-      // considered true if "fallback to renderer" was required since the
-      // renderer expects that.
-      ServiceWorkerResponseInfo::ForRequest(request_, true)
-          ->OnStartCompleted(
-              true /* was_fetched_via_service_worker */,
-              fall_back_required_, response_url_list_, fetch_response_type_,
-              worker_start_time_, worker_ready_time_,
-              response_is_in_cache_storage_, response_cache_storage_cache_name_,
-              cors_exposed_header_names_, did_navigation_preload_);
-      break;
-  }
-}
-
-bool ServiceWorkerURLRequestJob::IsMainResourceLoad() const {
-  return ServiceWorkerUtils::IsMainResourceType(resource_type_);
-}
-
-bool ServiceWorkerURLRequestJob::HasRequestBody() {
-  // URLRequest::has_upload() must be checked since its upload data may have
-  // been cleared while handling a redirect.
-  return request_->has_upload() && body_.get();
-}
-
-void ServiceWorkerURLRequestJob::ForwardRequestToServiceWorker() {
-  ServiceWorkerMetrics::URLRequestJobResult result =
-      ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
-  ServiceWorkerVersion* active_worker =
-      delegate_->GetServiceWorkerVersion(&result);
-  if (!active_worker) {
-    RecordResult(result);
-    DeliverErrorResponse();
-    return;
-  }
-
-  if (!provider_host_) {
-    RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST);
-    DeliverErrorResponse();
-    return;
-  }
-
-  worker_already_activated_ =
-      active_worker->status() == ServiceWorkerVersion::ACTIVATED;
-  initial_worker_status_ = active_worker->running_status();
-
-  std::unique_ptr<network::ResourceRequest> resource_request =
-      CreateResourceRequest();
-  auto fetch_api_request =
-      blink::mojom::FetchAPIRequest::From(*resource_request);
-  if (HasRequestBody()) {
-    fetch_api_request->body = std::move(body_);
-  }
-  DCHECK(!fetch_dispatcher_);
-  fetch_dispatcher_ = std::make_unique<ServiceWorkerFetchDispatcher>(
-      std::move(fetch_api_request), resource_type_,
-      provider_host_->client_uuid(), base::WrapRefCounted(active_worker),
-      base::BindOnce(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
-                     weak_factory_.GetWeakPtr(),
-                     base::WrapRefCounted(active_worker)),
-      base::BindOnce(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
-                     weak_factory_.GetWeakPtr()));
-  worker_start_time_ = base::TimeTicks::Now();
-  nav_preload_metrics_ = std::make_unique<NavigationPreloadMetrics>(this);
-  if (simulate_navigation_preload_for_test_) {
-    did_navigation_preload_ = true;
-  } else {
-    did_navigation_preload_ = fetch_dispatcher_->MaybeStartNavigationPreload(
-        request(),
-        base::BindOnce(&ServiceWorkerURLRequestJob::OnNavigationPreloadResponse,
-                       weak_factory_.GetWeakPtr()));
-  }
-  fetch_dispatcher_->Run();
-}
-
-void ServiceWorkerURLRequestJob::OnNavigationPreloadResponse() {
-  nav_preload_metrics_->ReportNavigationPreloadFinished();
-}
-
-}  // namespace content
diff --git a/content/browser/service_worker/service_worker_url_request_job.h b/content/browser/service_worker/service_worker_url_request_job.h
deleted file mode 100644
index 5f0ba12c..0000000
--- a/content/browser/service_worker/service_worker_url_request_job.h
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_REQUEST_JOB_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_REQUEST_JOB_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
-#include "base/time/time.h"
-#include "content/browser/service_worker/embedded_worker_status.h"
-#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
-#include "content/browser/service_worker/service_worker_metrics.h"
-#include "content/browser/service_worker/service_worker_response_type.h"
-#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
-#include "content/common/content_export.h"
-#include "content/public/common/resource_type.h"
-#include "mojo/public/cpp/system/data_pipe.h"
-#include "net/http/http_byte_range.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_job.h"
-#include "net/url_request/url_request_status.h"
-#include "services/network/public/cpp/resource_request.h"
-#include "services/network/public/mojom/fetch_api.mojom.h"
-#include "services/network/public/mojom/request_context_frame_type.mojom.h"
-#include "storage/common/blob_storage/blob_storage_constants.h"
-#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
-#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
-#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom.h"
-#include "url/gurl.h"
-
-namespace net {
-class IOBuffer;
-}  // namespace net
-
-namespace network {
-class ResourceRequestBody;
-}
-
-namespace storage {
-class BlobStorageContext;
-}  // namespace storage
-
-namespace content {
-
-class ResourceContext;
-class ServiceWorkerBlobReader;
-class ServiceWorkerDataPipeReader;
-class ServiceWorkerProviderHost;
-class ServiceWorkerVersion;
-
-namespace service_worker_controllee_request_handler_unittest {
-class ServiceWorkerControlleeRequestHandlerTest;
-FORWARD_DECLARE_TEST(ServiceWorkerControlleeRequestHandlerTest,
-                     LostActiveVersion);
-}  // namespace service_worker_controllee_request_handler_unittest
-
-namespace service_worker_url_request_job_unittest {
-class ServiceWorkerURLRequestJobTest;
-class DelayHelper;
-}  // namespace service_worker_url_request_job_unittest
-
-class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
- public:
-  using Delegate = ServiceWorkerURLJobWrapper::Delegate;
-  using ResponseType = ServiceWorkerResponseType;
-
-  ServiceWorkerURLRequestJob(
-      net::URLRequest* request,
-      net::NetworkDelegate* network_delegate,
-      base::WeakPtr<ServiceWorkerProviderHost> provider_host,
-      base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
-      const ResourceContext* resource_context,
-      network::mojom::FetchRequestMode request_mode,
-      network::mojom::FetchCredentialsMode credentials_mode,
-      network::mojom::FetchRedirectMode redirect_mode,
-      const std::string& integrity,
-      bool keepalive,
-      ResourceType resource_type,
-      blink::mojom::RequestContextType request_context_type,
-      network::mojom::RequestContextFrameType frame_type,
-      scoped_refptr<network::ResourceRequestBody> body,
-      Delegate* delegate);
-
-  ~ServiceWorkerURLRequestJob() override;
-
-  const ResourceContext* resource_context() const { return resource_context_; }
-  bool did_navigation_preload() const { return did_navigation_preload_; }
-
-  // When set, this job will pretend that navigation preload was triggered, but
-  // not actually do navigation preload. This is to aid unit tests that check
-  // UMA logging. It's difficult to get navigation preload to work in a unit
-  // test: there is a much setup of ResourceRequestInfoImpl,
-  // ResourceRequesterInfo, etc. required.
-  void set_simulate_navigation_preload_for_test() {
-    simulate_navigation_preload_for_test_ = true;
-  }
-
-  // Sets the response type.
-  // When an in-flight request possibly needs CORS check, use
-  // FallbackToNetworkOrRenderer. This method will decide whether the request
-  // can directly go to the network or should fallback to a renderer to send
-  // CORS preflight. You can use FallbackToNetwork only when it's apparent that
-  // the request can go to the network directly (e.g., main resource requests or
-  // same-origin requests).
-  void FallbackToNetwork();
-  void FallbackToNetworkOrRenderer();
-  void ForwardToServiceWorker();
-  // Tells the job to abort with a start error. Currently this is only called
-  // because the controller was lost. This function could be made more generic
-  // if needed later.
-  void FailDueToLostController();
-
-  bool ShouldFallbackToNetwork() const {
-    return response_type_ == ResponseType::FALLBACK_TO_NETWORK;
-  }
-  bool ShouldForwardToServiceWorker() const {
-    return response_type_ == ResponseType::FORWARD_TO_SERVICE_WORKER;
-  }
-
-  // net::URLRequestJob overrides:
-  void Start() override;
-  void Kill() override;
-  net::LoadState GetLoadState() const override;
-  bool GetCharset(std::string* charset) override;
-  bool GetMimeType(std::string* mime_type) const override;
-  void GetResponseInfo(net::HttpResponseInfo* info) override;
-  void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override;
-  void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
-  int ReadRawData(net::IOBuffer* buf, int buf_size) override;
-
-  //----------------------------------------------------------------------------
-  // The following are intended for use by ServiceWorker(Blob|DataPipe)Reader.
-  virtual void OnResponseStarted();
-  virtual void OnReadRawDataComplete(int bytes_read);
-  virtual void RecordResult(ServiceWorkerMetrics::URLRequestJobResult result);
-  //----------------------------------------------------------------------------
-
-  base::WeakPtr<ServiceWorkerURLRequestJob> GetWeakPtr();
-
- private:
-  using ResponseHeaderMap = base::flat_map<std::string, std::string>;
-
-  class NavigationPreloadMetrics;
-  friend class service_worker_url_request_job_unittest::DelayHelper;
-  friend class service_worker_url_request_job_unittest::
-      ServiceWorkerURLRequestJobTest;
-  FRIEND_TEST_ALL_PREFIXES(service_worker_controllee_request_handler_unittest::
-                               ServiceWorkerControlleeRequestHandlerTest,
-                           LostActiveVersion);
-
-  enum ResponseBodyType {
-    UNKNOWN,
-    BLOB,
-    STREAM,
-  };
-
-  // We start processing the request if Start() is called AND response_type_
-  // is determined.
-  void MaybeStartRequest();
-  void StartRequest();
-
-  // Creates a ResourceRequest from |request_|. Does not populate the request
-  // body.
-  std::unique_ptr<network::ResourceRequest> CreateResourceRequest();
-
-  // Returns true if this job performed a navigation that should be logged to
-  // performance-related UMA. It returns false in certain cases that are not
-  // relevant to performance analysis, such as if the worker was not already
-  // activated or DevTools was attached to the worker.
-  bool ShouldRecordNavigationMetrics(const ServiceWorkerVersion* version) const;
-
-  // For FORWARD_TO_SERVICE_WORKER case.
-  void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version);
-  void DidDispatchFetchEvent(
-      blink::ServiceWorkerStatusCode status,
-      ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
-      blink::mojom::FetchAPIResponsePtr response,
-      blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
-      blink::mojom::ServiceWorkerFetchEventTimingPtr timing,
-      scoped_refptr<ServiceWorkerVersion> version);
-  void SetResponse(blink::mojom::FetchAPIResponsePtr response);
-
-  // Populates |http_response_headers_|.
-  void CreateResponseHeader(int status_code,
-                            const std::string& status_text,
-                            ResponseHeaderMap headers);
-
-  // Creates |http_response_info_| using |http_response_headers_| and calls
-  // NotifyHeadersComplete.
-  void CommitResponseHeader();
-
-  // Creates and commits a response header indicating error.
-  void DeliverErrorResponse();
-
-  // Restarts this job to fallback to network.
-  // This can be called after StartRequest.
-  void FinalizeFallbackToNetwork();
-
-  // Sends back a response with fall_back_required set as true to trigger
-  // subsequent network requests with CORS checking.
-  // This can be called after StartRequest.
-  void FinalizeFallbackToRenderer();
-
-  // True if need to send back a response with fall_back_required set as true to
-  // trigger subsequent network requests with CORS checking.
-  bool IsFallbackToRendererNeeded() const;
-
-  // For UMA.
-  void SetResponseBodyType(ResponseBodyType type);
-  bool ShouldRecordResult();
-  void RecordStatusZeroResponseError(
-      blink::mojom::ServiceWorkerResponseError error);
-
-  const net::HttpResponseInfo* http_info() const;
-
-  // Invoke callbacks before invoking corresponding URLRequestJob methods.
-  void NotifyHeadersComplete();
-  void NotifyStartError(net::URLRequestStatus status);
-  void NotifyRestartRequired();
-
-  // Wrapper that gathers parameters to |on_start_completed_callback_| and then
-  // calls it.
-  void OnStartCompleted() const;
-
-  bool IsMainResourceLoad() const;
-
-  bool HasRequestBody();
-  void ForwardRequestToServiceWorker();
-
-  // Called back from
-  // ServiceWorkerFetchEventDispatcher::MaybeStartNavigationPreload when the
-  // navigation preload response starts.
-  void OnNavigationPreloadResponse();
-
-  void MaybeReportNavigationPreloadMetrics();
-
-  // Not owned.
-  Delegate* delegate_;
-
-  // Timing info to show on the popup in Devtools' Network tab.
-  net::LoadTimingInfo load_timing_info_;
-
-  // When the worker was asked to prepare for the fetch event. Preparation may
-  // include activation and startup.
-  base::TimeTicks worker_start_time_;
-
-  // When the worker confirmed it's ready for the fetch event. If it was already
-  // activated and running when asked to prepare, this should be nearly the same
-  // as |worker_start_time_|).
-  base::TimeTicks worker_ready_time_;
-
-  // When the response started.
-  base::Time response_time_;
-
-  // When the navigation preload response started.
-  base::TimeTicks navigation_preload_response_time_;
-
-  // True if the worker was already in ACTIVATED status when asked to prepare
-  // for the fetch event.
-  bool worker_already_activated_ = false;
-
-  // The status the worker was in when asked to prepare for the fetch event.
-  EmbeddedWorkerStatus initial_worker_status_ = EmbeddedWorkerStatus::STOPPED;
-
-  // If worker startup occurred during preparation, the situation that startup
-  // occurred in.
-  ServiceWorkerMetrics::StartSituation worker_start_situation_ =
-      ServiceWorkerMetrics::StartSituation::UNKNOWN;
-
-  // True if navigation preload was enabled.
-  bool did_navigation_preload_ = false;
-  bool simulate_navigation_preload_for_test_ = false;
-
-  std::unique_ptr<NavigationPreloadMetrics> nav_preload_metrics_;
-
-  ResponseType response_type_;
-
-  // True if URLRequestJob::Start() has been called.
-  bool is_started_;
-
-  net::HttpByteRange byte_range_;
-  std::unique_ptr<net::HttpResponseInfo> range_response_info_;
-  std::unique_ptr<net::HttpResponseInfo> http_response_info_;
-  // Headers that have not yet been committed to |http_response_info_|.
-  scoped_refptr<net::HttpResponseHeaders> http_response_headers_;
-  std::vector<GURL> response_url_list_;
-  network::mojom::FetchResponseType fetch_response_type_;
-
-  // Used when response type is FORWARD_TO_SERVICE_WORKER.
-  std::unique_ptr<ServiceWorkerFetchDispatcher> fetch_dispatcher_;
-  base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
-  base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
-  const ResourceContext* resource_context_;
-  // Only one of |blob_reader_| and |data_pipe_reader_| can be non-null.
-  std::unique_ptr<ServiceWorkerBlobReader> blob_reader_;
-  std::unique_ptr<ServiceWorkerDataPipeReader> data_pipe_reader_;
-
-  network::mojom::FetchRequestMode request_mode_;
-  network::mojom::FetchCredentialsMode credentials_mode_;
-  network::mojom::FetchRedirectMode redirect_mode_;
-  std::string integrity_;
-  const bool keepalive_;
-  const ResourceType resource_type_;
-  blink::mojom::RequestContextType request_context_type_;
-  network::mojom::RequestContextFrameType frame_type_;
-  bool fall_back_required_;
-  scoped_refptr<network::ResourceRequestBody> body_;
-
-  ResponseBodyType response_body_type_ = UNKNOWN;
-  bool did_record_result_ = false;
-
-  bool response_is_in_cache_storage_ = false;
-  std::string response_cache_storage_cache_name_;
-
-  ServiceWorkerHeaderList cors_exposed_header_names_;
-
-  base::WeakPtrFactory<ServiceWorkerURLRequestJob> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerURLRequestJob);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_REQUEST_JOB_H_
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 03108d60..e3f28b1 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -600,8 +600,6 @@
   FRIEND_TEST_ALL_PREFIXES(
       service_worker_storage_unittest::ServiceWorkerStorageDiskTest,
       ScriptResponseTime);
-  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, EarlyResponse);
-  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, CancelRequest);
 
   // Contains timeout info for InflightRequest.
   struct InflightRequestTimeoutInfo {
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc
index 85743ac..eed1e64 100644
--- a/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -1141,7 +1141,7 @@
   EXPECT_FALSE(google_rfh->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
 
   // Navigate to third page on same site.
-  const GURL url3("http://news.google.com");
+  const GURL url3("http://google.com/foo");
   NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url3);
   NavigationEntry* entry3 = controller().GetLastCommittedEntry();
   SiteInstance* instance3 = contents()->GetSiteInstance();
@@ -1155,20 +1155,24 @@
             NavigationEntryImpl::FromNavigationEntry(entry3)->site_instance());
 
   // Go back within the site.
-  controller().GoBack();
+  auto back_navigation1 =
+      NavigationSimulator::CreateHistoryNavigation(-1, contents());
+  back_navigation1->ReadyToCommit();
   EXPECT_FALSE(contents()->CrossProcessNavigationPending());
   EXPECT_EQ(entry2, controller().GetPendingEntry());
 
   // Before that commits, go back again.
-  controller().GoBack();
+  auto back_navigation2 =
+      NavigationSimulatorImpl::CreateHistoryNavigation(-1, contents());
+  back_navigation2->set_drop_swap_out_ack(true);
+  back_navigation2->ReadyToCommit();
   EXPECT_TRUE(contents()->CrossProcessNavigationPending());
   EXPECT_TRUE(contents()->GetPendingMainFrame());
   EXPECT_EQ(entry1, controller().GetPendingEntry());
   webui_rfh = contents()->GetPendingMainFrame();
 
   // DidNavigate from the second back.
-  contents()->TestDidNavigate(webui_rfh, entry1->GetUniqueID(), false, url1,
-                              ui::PAGE_TRANSITION_TYPED);
+  back_navigation2->Commit();
 
   // That should have landed us on the first entry.
   EXPECT_EQ(entry1, controller().GetLastCommittedEntry());
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index be46fe5..0693ea2 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -373,9 +373,6 @@
   WebRuntimeFeatures::EnableModernMediaControls(
       base::FeatureList::IsEnabled(media::kUseModernMediaControls));
 
-  WebRuntimeFeatures::EnableScheduledScriptStreaming(
-      base::FeatureList::IsEnabled(features::kScheduledScriptStreaming));
-
   WebRuntimeFeatures::EnableScriptStreamingOnPreload(
       base::FeatureList::IsEnabled(features::kScriptStreamingOnPreload));
 
@@ -495,6 +492,10 @@
 
   if (base::FeatureList::IsEnabled(features::kUserAgentClientHint))
     WebRuntimeFeatures::EnableFeatureFromString("UserAgentClientHint", true);
+
+  WebRuntimeFeatures::EnableSignedExchangeSubresourcePrefetch(
+      base::FeatureList::IsEnabled(
+          features::kSignedExchangeSubresourcePrefetch));
 }
 
 }  // namespace
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 32e7f67..a09878d 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -463,6 +463,11 @@
 const base::Feature kSignedExchangeReportingForDistributors{
     "SignedExchangeReportingForDistributors", base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Subresource prefetching+loading via Signed HTTP Exchange
+// https://www.chromestatus.com/features/5126805474246656
+const base::Feature kSignedExchangeSubresourcePrefetch{
+    "SignedExchangeSubresourcePrefetch", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Origin-Signed HTTP Exchanges (for WebPackage Loading)
 // https://www.chromestatus.com/features/5745285984681984
 const base::Feature kSignedHTTPExchange{"SignedHTTPExchange",
@@ -683,10 +688,6 @@
 const base::Feature kWipeCorruptV2IDBDatabases{
     "WipeCorruptV2IDBDatabases", base::FEATURE_ENABLED_BY_DEFAULT};
 
-// Enabled scheduler use for script streaming.
-const base::Feature kScheduledScriptStreaming{"ScheduledScriptStreaming",
-                                              base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Start streaming scripts on script preload.
 const base::Feature kScriptStreamingOnPreload{
     "ScriptStreamingOnPreload", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 9fd281d..12c931b 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -108,6 +108,7 @@
 CONTENT_EXPORT extern const base::Feature kSharedArrayBuffer;
 CONTENT_EXPORT extern const base::Feature
     kSignedExchangeReportingForDistributors;
+CONTENT_EXPORT extern const base::Feature kSignedExchangeSubresourcePrefetch;
 CONTENT_EXPORT extern const base::Feature kSignedHTTPExchange;
 CONTENT_EXPORT extern const base::Feature kSkipBrowserTouchFilter;
 CONTENT_EXPORT extern const char kSkipBrowserTouchFilterTypeParamName[];
@@ -149,7 +150,6 @@
 CONTENT_EXPORT extern const base::Feature kWebXrGamepadSupport;
 CONTENT_EXPORT extern const base::Feature kWebXrHitTest;
 CONTENT_EXPORT extern const base::Feature kWipeCorruptV2IDBDatabases;
-CONTENT_EXPORT extern const base::Feature kScheduledScriptStreaming;
 CONTENT_EXPORT extern const base::Feature kScriptStreamingOnPreload;
 
 #if defined(OS_ANDROID)
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3a133a9..1fac3bcf 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3514,8 +3514,7 @@
   navigation_params->history_item = item_for_history_navigation;
   navigation_params->service_worker_network_provider =
       BuildServiceWorkerNetworkProviderForNavigation(
-          &commit_params, std::move(controller_service_worker_info),
-          std::move(provider_info));
+          std::move(controller_service_worker_info), std::move(provider_info));
 
   frame_->CommitNavigation(std::move(navigation_params),
                            std::move(document_state));
@@ -7515,7 +7514,6 @@
 
 std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
 RenderFrameImpl::BuildServiceWorkerNetworkProviderForNavigation(
-    const CommitNavigationParams* commit_params,
     blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
     blink::mojom::ServiceWorkerProviderInfoForWindowPtr provider_info) {
   // An empty provider will always be created since it is expected in a certain
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 08550bf..435b6e6 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -1397,7 +1397,6 @@
   // to be supplied to the loader.
   std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
   BuildServiceWorkerNetworkProviderForNavigation(
-      const CommitNavigationParams* commit_params,
       blink::mojom::ControllerServiceWorkerInfoPtr
           controller_service_worker_info,
       blink::mojom::ServiceWorkerProviderInfoForWindowPtr provider_info);
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 4881660..f3309d2 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -28,7 +28,7 @@
 #include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h"
 #include "third_party/blink/public/mojom/loader/code_cache.mojom.h"
-#include "third_party/blink/public/platform/modules/webdatabase/web_database.mojom.h"
+#include "third_party/blink/public/mojom/webdatabase/web_database.mojom.h"
 
 #if defined(OS_LINUX)
 #include "components/services/font/public/cpp/font_loader.h"  // nogncheck
diff --git a/content/renderer/service_worker/service_worker_provider_context.cc b/content/renderer/service_worker/service_worker_provider_context.cc
index 8f4209cd..2e019077 100644
--- a/content/renderer/service_worker/service_worker_provider_context.cc
+++ b/content/renderer/service_worker/service_worker_provider_context.cc
@@ -76,7 +76,6 @@
   // the controller.
   if (controller_info) {
     SetController(std::move(controller_info),
-                  std::vector<blink::mojom::WebFeature>(),
                   false /* should_notify_controllerchange */);
   }
 }
@@ -283,7 +282,6 @@
 
 void ServiceWorkerProviderContext::SetController(
     blink::mojom::ControllerServiceWorkerInfoPtr controller_info,
-    const std::vector<blink::mojom::WebFeature>& used_features,
     bool should_notify_controllerchange) {
   DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
   ServiceWorkerProviderStateForClient* state = state_for_client_.get();
@@ -320,7 +318,7 @@
       worker->OnControllerChanged(state->controller_mode);
     }
   }
-  for (blink::mojom::WebFeature feature : used_features)
+  for (blink::mojom::WebFeature feature : controller_info->used_features)
     state->used_features.insert(feature);
 
   // S13nServiceWorker:
diff --git a/content/renderer/service_worker/service_worker_provider_context.h b/content/renderer/service_worker/service_worker_provider_context.h
index 73f68c1..5da7e72d 100644
--- a/content/renderer/service_worker/service_worker_provider_context.h
+++ b/content/renderer/service_worker/service_worker_provider_context.h
@@ -194,7 +194,6 @@
   // Implementation of blink::mojom::ServiceWorkerContainer.
   void SetController(
       blink::mojom::ControllerServiceWorkerInfoPtr controller_info,
-      const std::vector<blink::mojom::WebFeature>& used_features,
       bool should_notify_controllerchange) override;
   void PostMessageToClient(blink::mojom::ServiceWorkerObjectInfoPtr source,
                            blink::TransferableMessage message) override;
diff --git a/content/renderer/service_worker/service_worker_provider_context_unittest.cc b/content/renderer/service_worker/service_worker_provider_context_unittest.cc
index 20b30a3..7165822 100644
--- a/content/renderer/service_worker/service_worker_provider_context_unittest.cc
+++ b/content/renderer/service_worker/service_worker_provider_context_unittest.cc
@@ -333,8 +333,7 @@
     auto info = blink::mojom::ControllerServiceWorkerInfo::New();
     info->mode = blink::mojom::ControllerServiceWorkerMode::kControlled;
     info->object_info = std::move(object_info);
-    container_ptr->SetController(std::move(info),
-                                 std::vector<blink::mojom::WebFeature>(), true);
+    container_ptr->SetController(std::move(info), true);
     base::RunLoop().RunUntilIdle();
 
     // Destruction of the provider context should release references to the
@@ -378,8 +377,7 @@
     auto info = blink::mojom::ControllerServiceWorkerInfo::New();
     info->mode = blink::mojom::ControllerServiceWorkerMode::kControlled;
     info->object_info = std::move(object_info);
-    container_ptr->SetController(std::move(info),
-                                 std::vector<blink::mojom::WebFeature>(), true);
+    container_ptr->SetController(std::move(info), true);
     base::RunLoop().RunUntilIdle();
 
     EXPECT_TRUE(client->was_set_controller_called());
@@ -410,7 +408,7 @@
   provider_impl->SetClient(client.get());
 
   container_ptr->SetController(blink::mojom::ControllerServiceWorkerInfo::New(),
-                               std::vector<blink::mojom::WebFeature>(), true);
+                               true);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_FALSE(provider_context->TakeController());
@@ -496,8 +494,7 @@
   // object binding being broken.
   base::RunLoop drop_binding_loop;
   object_host1->RunOnConnectionError(drop_binding_loop.QuitClosure());
-  container_ptr->SetController(std::move(controller_info2),
-                               std::vector<blink::mojom::WebFeature>(), true);
+  container_ptr->SetController(std::move(controller_info2), true);
   container_ptr.FlushForTesting();
   drop_binding_loop.Run();
   EXPECT_EQ(0, object_host1->GetBindingCount());
@@ -529,7 +526,7 @@
   base::RunLoop drop_binding_loop2;
   object_host2->RunOnConnectionError(drop_binding_loop2.QuitClosure());
   container_ptr->SetController(blink::mojom::ControllerServiceWorkerInfo::New(),
-                               std::vector<blink::mojom::WebFeature>(), true);
+                               true);
 
   // The controller is reset. References to the old controller must be
   // released.
@@ -576,8 +573,7 @@
       blink::mojom::ControllerServiceWorkerMode::kControlled;
   controller_info4->object_info = std::move(object_info4);
   controller_info4->endpoint = controller_ptr4.PassInterface();
-  container_ptr->SetController(std::move(controller_info4),
-                               std::vector<blink::mojom::WebFeature>(), true);
+  container_ptr->SetController(std::move(controller_info4), true);
   container_ptr.FlushForTesting();
 
   // Subresource loader factory must be available.
diff --git a/content/renderer/web_database_observer_impl.h b/content/renderer/web_database_observer_impl.h
index 67515de..c3739b7d 100644
--- a/content/renderer/web_database_observer_impl.h
+++ b/content/renderer/web_database_observer_impl.h
@@ -7,7 +7,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "third_party/blink/public/platform/modules/webdatabase/web_database.mojom.h"
+#include "third_party/blink/public/mojom/webdatabase/web_database.mojom.h"
 #include "third_party/blink/public/platform/web_database_observer.h"
 
 namespace base {
diff --git a/content/shell/renderer/web_test/blink_test_helpers.cc b/content/shell/renderer/web_test/blink_test_helpers.cc
index 40b58ed1d..a3d41387 100644
--- a/content/shell/renderer/web_test/blink_test_helpers.cc
+++ b/content/shell/renderer/web_test/blink_test_helpers.cc
@@ -94,6 +94,7 @@
   to->strict_powerful_feature_restrictions =
       from.strict_powerful_feature_restrictions;
   to->spatial_navigation_enabled = from.spatial_navigation_enabled;
+  to->enable_scroll_animator = from.scroll_animator_enabled;
 }
 
 // Applies settings that differ between web tests and regular mode. Some
diff --git a/content/shell/test_runner/test_preferences.cc b/content/shell/test_runner/test_preferences.cc
index 5a999fc..076d79e 100644
--- a/content/shell/test_runner/test_preferences.cc
+++ b/content/shell/test_runner/test_preferences.cc
@@ -46,6 +46,7 @@
   strict_mixed_content_checking = false;
   strict_powerful_feature_restrictions = false;
   spatial_navigation_enabled = false;
+  scroll_animator_enabled = true;
 }
 
 }  // namespace test_runner
diff --git a/content/shell/test_runner/test_preferences.h b/content/shell/test_runner/test_preferences.h
index 886ee2d5..3decb88 100644
--- a/content/shell/test_runner/test_preferences.h
+++ b/content/shell/test_runner/test_preferences.h
@@ -37,6 +37,7 @@
   bool strict_mixed_content_checking;
   bool strict_powerful_feature_restrictions;
   bool spatial_navigation_enabled;
+  bool scroll_animator_enabled;
 
   TestPreferences();
   void Reset();
diff --git a/content/shell/test_runner/test_runner.cc b/content/shell/test_runner/test_runner.cc
index df5475e8..ca3db076 100644
--- a/content/shell/test_runner/test_runner.cc
+++ b/content/shell/test_runner/test_runner.cc
@@ -2229,6 +2229,8 @@
     ConvertAndSet(args, &prefs->web_security_enabled);
   } else if (key == "WebKitSpatialNavigationEnabled") {
     ConvertAndSet(args, &prefs->spatial_navigation_enabled);
+  } else if (key == "ScrollAnimatorEnabled") {
+    ConvertAndSet(args, &prefs->scroll_animator_enabled);
   } else {
     args->ThrowTypeError("Invalid name for preference: " + key);
   }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 578fe1dd..3fc87d0 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1140,6 +1140,8 @@
 
   if (is_win) {
     sources += [
+      "../browser/accessibility/accessibility_browsertest.cc",
+      "../browser/accessibility/accessibility_browsertest.h",
       "../browser/accessibility/accessibility_win_browsertest.cc",
       "../browser/accessibility/ax_platform_node_win_browsertest.cc",
       "../browser/renderer_host/accessibility_tree_linkage_win_browsertest.cc",
@@ -1167,8 +1169,11 @@
     ]
 
     if (use_atk) {
-      sources +=
-          [ "../browser/accessibility/accessibility_auralinux_browsertest.cc" ]
+      sources += [
+        "../browser/accessibility/accessibility_auralinux_browsertest.cc",
+        "../browser/accessibility/accessibility_browsertest.cc",
+        "../browser/accessibility/accessibility_browsertest.h",
+      ]
       configs += [ "//build/config/linux/atk" ]
     }
   }
@@ -1657,7 +1662,6 @@
     "../browser/service_worker/service_worker_context_unittest.cc",
     "../browser/service_worker/service_worker_context_watcher_unittest.cc",
     "../browser/service_worker/service_worker_controllee_request_handler_unittest.cc",
-    "../browser/service_worker/service_worker_data_pipe_reader_unittest.cc",
     "../browser/service_worker/service_worker_database_unittest.cc",
     "../browser/service_worker/service_worker_installed_scripts_sender_unittest.cc",
     "../browser/service_worker/service_worker_job_unittest.cc",
diff --git a/content/test/data/accessibility/language-detection/lang-detection-basic-expected-blink.txt b/content/test/data/accessibility/language-detection/basic-expected-blink.txt
similarity index 100%
rename from content/test/data/accessibility/language-detection/lang-detection-basic-expected-blink.txt
rename to content/test/data/accessibility/language-detection/basic-expected-blink.txt
diff --git a/content/test/data/accessibility/language-detection/lang-detection-basic-expected-mac.txt b/content/test/data/accessibility/language-detection/basic-expected-mac.txt
similarity index 100%
rename from content/test/data/accessibility/language-detection/lang-detection-basic-expected-mac.txt
rename to content/test/data/accessibility/language-detection/basic-expected-mac.txt
diff --git a/content/test/data/accessibility/language-detection/lang-detection-basic-expected-win.txt b/content/test/data/accessibility/language-detection/basic-expected-win.txt
similarity index 100%
rename from content/test/data/accessibility/language-detection/lang-detection-basic-expected-win.txt
rename to content/test/data/accessibility/language-detection/basic-expected-win.txt
diff --git a/content/test/data/accessibility/language-detection/lang-detection-basic.html b/content/test/data/accessibility/language-detection/basic.html
similarity index 100%
rename from content/test/data/accessibility/language-detection/lang-detection-basic.html
rename to content/test/data/accessibility/language-detection/basic.html
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc
index 6e713de..98aca2a5 100644
--- a/content/test/navigation_simulator_impl.cc
+++ b/content/test/navigation_simulator_impl.cc
@@ -601,7 +601,7 @@
 
   // Simulate the UnloadACK in the old RenderFrameHost if it was swapped out at
   // commit time.
-  if (previous_rfh != render_frame_host_) {
+  if (previous_rfh != render_frame_host_ && !drop_swap_out_ack_) {
     previous_rfh->OnMessageReceived(
         FrameHostMsg_SwapOut_ACK(previous_rfh->GetRoutingID()));
   }
@@ -724,7 +724,7 @@
 
   // Simulate the UnloadACK in the old RenderFrameHost if it was swapped out at
   // commit time.
-  if (previous_rfh != render_frame_host_) {
+  if (previous_rfh != render_frame_host_ && !drop_swap_out_ack_) {
     previous_rfh->OnMessageReceived(
         FrameHostMsg_SwapOut_ACK(previous_rfh->GetRoutingID()));
   }
diff --git a/content/test/navigation_simulator_impl.h b/content/test/navigation_simulator_impl.h
index d71d1c8..23dfd31c 100644
--- a/content/test/navigation_simulator_impl.h
+++ b/content/test/navigation_simulator_impl.h
@@ -120,6 +120,13 @@
 
   void set_ssl_info(net::SSLInfo ssl_info) { ssl_info_ = ssl_info; }
 
+  // Whether to complete the swap out of the previous RenderFrameHost during
+  // cross-process navigations. By default this is true, set to false if you
+  // want the old RenderFrameHost to be left in a pending swap out state.
+  void set_drop_swap_out_ack(bool drop_swap_out_ack) {
+    drop_swap_out_ack_ = drop_swap_out_ack;
+  }
+
  private:
   NavigationSimulatorImpl(const GURL& original_url,
                           bool browser_initiated,
@@ -244,6 +251,7 @@
   base::Optional<net::SSLInfo> ssl_info_;
 
   bool auto_advance_ = true;
+  bool drop_swap_out_ack_ = false;
 
   // Generic params structure used for fully customized browser initiated
   // navigation requests. Only valid if explicitely provided.
diff --git a/docs/updating_clang.md b/docs/updating_clang.md
index da5b757d..73d0016 100644
--- a/docs/updating_clang.md
+++ b/docs/updating_clang.md
@@ -24,8 +24,6 @@
             gs://chromium-browser-clang/$x/clang-$rev.tgz ; \
         gsutil.py cp -n -a public-read gs://chromium-browser-clang-staging/$x/llvmobjdump-$rev.tgz \
             gs://chromium-browser-clang/$x/llvmobjdump-$rev.tgz ; \
-        gsutil.py cp -n -a public-read gs://chromium-browser-clang-staging/$x/llvmcfiverify-$rev.tgz \
-            gs://chromium-browser-clang/$x/llvmcfiverify-$rev.tgz ; \
         gsutil.py cp -n -a public-read gs://chromium-browser-clang-staging/$x/translation_unit-$rev.tgz \
             gs://chromium-browser-clang/$x/translation_unit-$rev.tgz ; \
         gsutil.py cp -n -a public-read gs://chromium-browser-clang-staging/$x/llvm-code-coverage-$rev.tgz \
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
index 410b9fc2..2b0433c 100644
--- a/extensions/browser/api/web_request/web_request_api.cc
+++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -1584,10 +1584,11 @@
         listener->id.extension_id, crosses_incognito));
 
     EventRouter::DispatchEventToSender(
-        listener->ipc_sender.get(), browser_context, listener->id.extension_id,
+        listener->ipc_sender.get(), browser_context,
+        listener->id.render_process_id, listener->id.extension_id,
         listener->histogram_value, listener->id.sub_event_name,
-        std::move(args_filtered), EventRouter::USER_GESTURE_UNKNOWN,
-        EventFilteringInfo());
+        blink::mojom::kInvalidServiceWorkerVersionId, std::move(args_filtered),
+        EventRouter::USER_GESTURE_UNKNOWN, EventFilteringInfo());
   }
 }
 
@@ -1597,12 +1598,12 @@
     const std::string& event_name,
     const std::string& sub_event_name,
     uint64_t request_id,
-    int embedder_process_id,
+    int render_process_id,
     int web_view_instance_id,
     EventResponse* response) {
   Listeners& listeners = listeners_[browser_context][event_name];
   EventListener::ID id(browser_context, extension_id, sub_event_name,
-                       embedder_process_id, web_view_instance_id);
+                       render_process_id, web_view_instance_id);
   EventListener* listener = FindEventListenerInContainer(id, listeners);
 
   // This might happen, for example, if the extension has been unloaded.
@@ -1623,7 +1624,7 @@
     const std::string& sub_event_name,
     const RequestFilter& filter,
     int extra_info_spec,
-    int embedder_process_id,
+    int render_process_id,
     int web_view_instance_id,
     base::WeakPtr<IPC::Sender> ipc_sender) {
   if (!IsWebRequestEvent(event_name))
@@ -1633,7 +1634,7 @@
     return false;
 
   EventListener::ID id(browser_context, extension_id, sub_event_name,
-                       embedder_process_id, web_view_instance_id);
+                       render_process_id, web_view_instance_id);
   if (FindEventListener(id) != nullptr) {
     // This is likely an abuse of the API by a malicious extension.
     return false;
@@ -1698,7 +1699,7 @@
 
     // There are two places that call this method: RemoveWebViewEventListeners
     // and OnListenerRemoved. The latter can't use operator== because it doesn't
-    // have the embedder_process_id. This shouldn't be a problem, because
+    // have the render_process_id. This shouldn't be a problem, because
     // OnListenerRemoved is only called for web_view_instance_id == 0.
     bool matches =
         strict ? listener->id == id : listener->id.LooselyMatches(id);
@@ -1725,7 +1726,7 @@
 
 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners(
     void* browser_context,
-    int embedder_process_id,
+    int render_process_id,
     int web_view_instance_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -1739,7 +1740,7 @@
     std::vector<EventListener::ID> listeners_to_delete;
     const Listeners& listeners = event_iter.second;
     for (const auto& listener : listeners) {
-      if (listener->id.embedder_process_id == embedder_process_id &&
+      if (listener->id.render_process_id == render_process_id &&
           listener->id.web_view_instance_id == web_view_instance_id) {
         listeners_to_delete.push_back(listener->id);
       }
@@ -1860,7 +1861,7 @@
       // If this is a PlzNavigate request, then we can skip this check. IDs will
       // be -1 and the request is trusted.
       if (!request->is_browser_side_navigation &&
-          (listener->id.embedder_process_id !=
+          (listener->id.render_process_id !=
            request->web_view_embedder_process_id)) {
         continue;
       }
@@ -1872,7 +1873,7 @@
     // Filter requests from other extensions / apps. This does not work for
     // content scripts, or extension pages in non-extension processes.
     if (is_request_from_extension &&
-        listener->id.embedder_process_id != request->render_process_id) {
+        listener->id.render_process_id != request->render_process_id) {
       continue;
     }
 
@@ -2540,8 +2541,9 @@
   int web_view_instance_id = 0;
   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &web_view_instance_id));
 
+  // TODO(dbertoni): We should just use source_process_id() here.
   base::WeakPtr<IOThreadExtensionMessageFilter> ipc_sender = ipc_sender_weak();
-  int embedder_process_id = ipc_sender ? ipc_sender->render_process_id() : 0;
+  int render_process_id = ipc_sender ? ipc_sender->render_process_id() : 0;
 
   const Extension* extension =
       extension_info_map()->extensions().GetByID(extension_id_safe());
@@ -2585,7 +2587,7 @@
       ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
           profile_id(), extension_id_safe(), extension_name,
           GetEventHistogramValue(event_name), event_name, sub_event_name,
-          filter, extra_info_spec, embedder_process_id, web_view_instance_id,
+          filter, extra_info_spec, render_process_id, web_view_instance_id,
           ipc_sender_weak());
   EXTENSION_FUNCTION_VALIDATE(success);
 
@@ -2598,12 +2600,12 @@
     const std::string& event_name,
     const std::string& sub_event_name,
     uint64_t request_id,
-    int embedder_process_id,
+    int render_process_id,
     int web_view_instance_id,
     std::unique_ptr<ExtensionWebRequestEventRouter::EventResponse> response) {
   ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
       profile_id(), extension_id_safe(), event_name, sub_event_name, request_id,
-      embedder_process_id, web_view_instance_id, response.release());
+      render_process_id, web_view_instance_id, response.release());
 }
 
 ExtensionFunction::ResponseAction
@@ -2623,7 +2625,7 @@
   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &web_view_instance_id));
 
   base::WeakPtr<IOThreadExtensionMessageFilter> ipc_sender = ipc_sender_weak();
-  int embedder_process_id = ipc_sender ? ipc_sender->render_process_id() : 0;
+  int render_process_id = ipc_sender ? ipc_sender->render_process_id() : 0;
 
   std::unique_ptr<ExtensionWebRequestEventRouter::EventResponse> response;
   if (HasOptionalArgument(4)) {
@@ -2645,7 +2647,7 @@
          value->HasKey(keys::kAuthCredentialsKey) ||
          value->HasKey("requestHeaders") ||
          value->HasKey("responseHeaders"))) {
-      OnError(event_name, sub_event_name, request_id, embedder_process_id,
+      OnError(event_name, sub_event_name, request_id, render_process_id,
               web_view_instance_id, std::move(response));
       return RespondNow(Error(keys::kInvalidPublicSessionBlockingResponse));
     }
@@ -2653,7 +2655,7 @@
     if (value->HasKey("cancel")) {
       // Don't allow cancel mixed with other keys.
       if (value->size() != 1) {
-        OnError(event_name, sub_event_name, request_id, embedder_process_id,
+        OnError(event_name, sub_event_name, request_id, render_process_id,
                 web_view_instance_id, std::move(response));
         return RespondNow(Error(keys::kInvalidBlockingResponse));
       }
@@ -2669,7 +2671,7 @@
                                                    &new_url_str));
       response->new_url = GURL(new_url_str);
       if (!response->new_url.is_valid()) {
-        OnError(event_name, sub_event_name, request_id, embedder_process_id,
+        OnError(event_name, sub_event_name, request_id, render_process_id,
                 web_view_instance_id, std::move(response));
         return RespondNow(Error(keys::kInvalidRedirectUrl, new_url_str));
       }
@@ -2680,7 +2682,7 @@
     if (has_request_headers || has_response_headers) {
       if (has_request_headers && has_response_headers) {
         // Allow only one of the keys, not both.
-        OnError(event_name, sub_event_name, request_id, embedder_process_id,
+        OnError(event_name, sub_event_name, request_id, render_process_id,
                 web_view_instance_id, std::move(response));
         return RespondNow(Error(keys::kInvalidHeaderKeyCombination));
       }
@@ -2707,17 +2709,17 @@
         if (!FromHeaderDictionary(header_value, &name, &value)) {
           std::string serialized_header;
           base::JSONWriter::Write(*header_value, &serialized_header);
-          OnError(event_name, sub_event_name, request_id, embedder_process_id,
+          OnError(event_name, sub_event_name, request_id, render_process_id,
                   web_view_instance_id, std::move(response));
           return RespondNow(Error(keys::kInvalidHeader, serialized_header));
         }
         if (!net::HttpUtil::IsValidHeaderName(name)) {
-          OnError(event_name, sub_event_name, request_id, embedder_process_id,
+          OnError(event_name, sub_event_name, request_id, render_process_id,
                   web_view_instance_id, std::move(response));
           return RespondNow(Error(keys::kInvalidHeaderName));
         }
         if (!net::HttpUtil::IsValidHeaderValue(value)) {
-          OnError(event_name, sub_event_name, request_id, embedder_process_id,
+          OnError(event_name, sub_event_name, request_id, render_process_id,
                   web_view_instance_id, std::move(response));
           return RespondNow(Error(keys::kInvalidHeaderValue, name));
         }
@@ -2749,7 +2751,7 @@
 
   ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
       profile_id(), extension_id_safe(), event_name, sub_event_name, request_id,
-      embedder_process_id, web_view_instance_id, response.release());
+      render_process_id, web_view_instance_id, response.release());
 
   return RespondNow(NoArguments());
 }
@@ -2790,12 +2792,12 @@
     void* browser_context,
     const std::string& extension_id,
     const std::string& sub_event_name,
-    int embedder_process_id,
+    int render_process_id,
     int web_view_instance_id)
     : browser_context(browser_context),
       extension_id(extension_id),
       sub_event_name(sub_event_name),
-      embedder_process_id(embedder_process_id),
+      render_process_id(render_process_id),
       web_view_instance_id(web_view_instance_id) {}
 
 bool ExtensionWebRequestEventRouter::EventListener::ID::LooselyMatches(
@@ -2818,7 +2820,7 @@
   return extension_id == that.extension_id &&
          sub_event_name == that.sub_event_name &&
          web_view_instance_id == that.web_view_instance_id &&
-         embedder_process_id == that.embedder_process_id &&
+         render_process_id == that.render_process_id &&
          browser_context == that.browser_context;
 }
 
diff --git a/extensions/browser/api/web_request/web_request_api.h b/extensions/browser/api/web_request/web_request_api.h
index ff6bbea..57281dc8 100644
--- a/extensions/browser/api/web_request/web_request_api.h
+++ b/extensions/browser/api/web_request/web_request_api.h
@@ -447,7 +447,7 @@
                       const std::string& event_name,
                       const std::string& sub_event_name,
                       uint64_t request_id,
-                      int embedder_process_id,
+                      int render_process_id,
                       int web_view_instance_id,
                       EventResponse* response);
 
@@ -463,15 +463,14 @@
                         const std::string& sub_event_name,
                         const RequestFilter& filter,
                         int extra_info_spec,
-                        int embedder_process_id,
+                        int render_process_id,
                         int web_view_instance_id,
                         base::WeakPtr<IPC::Sender> ipc_sender);
 
   // Removes the listeners for a given <webview>.
-  void RemoveWebViewEventListeners(
-      void* browser_context,
-      int embedder_process_id,
-      int web_view_instance_id);
+  void RemoveWebViewEventListeners(void* browser_context,
+                                   int render_process_id,
+                                   int web_view_instance_id);
 
   // Called when an incognito browser_context is created or destroyed.
   void OnOTRBrowserContextCreated(void* original_browser_context,
@@ -520,17 +519,17 @@
     // associated with WebViews and those that are not. The ones associated with
     // WebViews are always identified by all five properties. The other ones
     // will always have web_view_instance_id = 0. Unfortunately, the
-    // callbacks/interfaces for these ones don't specify embedder_process_id.
+    // callbacks/interfaces for these ones don't specify render_process_id.
     // This is why we need the LooselyMatches method, and the need for a
     // |strict| argument on RemoveEventListener.
     struct ID {
       ID(void* browser_context,
          const std::string& extension_id,
          const std::string& sub_event_name,
-         int embedder_process_id,
+         int render_process_id,
          int web_view_instance_id);
 
-      // If web_view_instance_id is 0, then ignore embedder_process_id.
+      // If web_view_instance_id is 0, then ignore render_process_id.
       // TODO(rdevlin.cronin): In a more sane world, LooselyMatches wouldn't be
       // necessary.
       bool LooselyMatches(const ID& that) const;
@@ -539,7 +538,8 @@
       void* browser_context;
       std::string extension_id;
       std::string sub_event_name;
-      int embedder_process_id;
+      // In the case of a webview, this is the process ID of the embedder.
+      int render_process_id;
       int web_view_instance_id;
     };
 
@@ -800,7 +800,7 @@
       const std::string& event_name,
       const std::string& sub_event_name,
       uint64_t request_id,
-      int embedder_process_id,
+      int render_process_id,
       int web_view_instance_id,
       std::unique_ptr<ExtensionWebRequestEventRouter::EventResponse> response);
 
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc
index 57a5add..c554abd 100644
--- a/extensions/browser/event_router.cc
+++ b/extensions/browser/event_router.cc
@@ -131,26 +131,29 @@
 // static
 void EventRouter::DispatchEventToSender(IPC::Sender* ipc_sender,
                                         void* browser_context_id,
+                                        int render_process_id,
                                         const std::string& extension_id,
                                         events::HistogramValue histogram_value,
                                         const std::string& event_name,
+                                        int64_t service_worker_version_id,
                                         std::unique_ptr<ListValue> event_args,
                                         UserGestureState user_gesture,
                                         const EventFilteringInfo& info) {
   int event_id = g_extension_event_id.GetNext();
 
   if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    DoDispatchEventToSenderBookkeepingOnUI(browser_context_id, extension_id,
-                                           event_id, histogram_value,
-                                           event_name);
+    DoDispatchEventToSenderBookkeepingOnUI(
+        browser_context_id, render_process_id, extension_id, event_id,
+        service_worker_version_id, histogram_value, event_name);
   } else {
     // This is called from WebRequest API.
     // TODO(lazyboy): Skip this entirely: http://crbug.com/488747.
     base::PostTaskWithTraits(
         FROM_HERE, {BrowserThread::UI},
         base::BindOnce(&EventRouter::DoDispatchEventToSenderBookkeepingOnUI,
-                       browser_context_id, extension_id, event_id,
-                       histogram_value, event_name));
+                       browser_context_id, render_process_id, extension_id,
+                       event_id, service_worker_version_id, histogram_value,
+                       event_name));
   }
 
   DispatchExtensionMessage(ipc_sender,
@@ -702,29 +705,18 @@
   if (extension) {
     ReportEvent(event->histogram_value, extension, did_enqueue);
 
-    const bool is_for_service_worker = worker_thread_id != kMainThreadId;
-    // TODO(lazyboy): It would be nice to unify inflight-event increment code
-    // for worker and non-worker below. That would also require passing in
-    // dummy worker thread id and service worker context to the unified
-    // method...
-    if (is_for_service_worker) {
-      content::ServiceWorkerContext* service_worker_context =
-          process->GetStoragePartition()->GetServiceWorkerContext();
-      event_ack_data_.IncrementInflightEvent(
-          service_worker_context, process->GetID(), service_worker_version_id,
-          event_id);
-    } else {
-      IncrementInFlightEvents(listener_context, extension, event_id,
-                              event->event_name);
-    }
+    IncrementInFlightEvents(listener_context, process, extension, event_id,
+                            event->event_name, service_worker_version_id);
   }
 }
 
 // static
 void EventRouter::DoDispatchEventToSenderBookkeepingOnUI(
     void* browser_context_id,
+    int render_process_id,
     const std::string& extension_id,
     int event_id,
+    int64_t service_worker_version_id,
     events::HistogramValue histogram_value,
     const std::string& event_name) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -762,16 +754,19 @@
     NOTREACHED();
     return;
   }
-  event_router->IncrementInFlightEvents(browser_context, extension, event_id,
-                                        event_name);
+  event_router->IncrementInFlightEvents(
+      browser_context, content::RenderProcessHost::FromID(render_process_id),
+      extension, event_id, event_name, service_worker_version_id);
   event_router->ReportEvent(histogram_value, extension,
                             false /* did_enqueue */);
 }
 
 void EventRouter::IncrementInFlightEvents(BrowserContext* context,
+                                          content::RenderProcessHost* process,
                                           const Extension* extension,
                                           int event_id,
-                                          const std::string& event_name) {
+                                          const std::string& event_name,
+                                          int64_t service_worker_version_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Only increment in-flight events if the lazy background page is active,
@@ -783,6 +778,19 @@
       pm->IncrementLazyKeepaliveCount(extension, Activity::EVENT, event_name);
       host->OnBackgroundEventDispatched(event_name, event_id);
     }
+  } else if (service_worker_version_id !=
+             blink::mojom::kInvalidServiceWorkerVersionId) {
+    // Check to make sure the rendered process hasn't gone away by the time
+    // we've gotten here. (It's possible it has crashed, etc.) If that's
+    // happened, we don't want to track the expected ACK, since we'll never
+    // get it.
+    if (process) {
+      content::ServiceWorkerContext* service_worker_context =
+          process->GetStoragePartition()->GetServiceWorkerContext();
+      event_ack_data_.IncrementInflightEvent(
+          service_worker_context, process->GetID(), service_worker_version_id,
+          event_id);
+    }
   }
 }
 
diff --git a/extensions/browser/event_router.h b/extensions/browser/event_router.h
index 1de4c1a..140d848 100644
--- a/extensions/browser/event_router.h
+++ b/extensions/browser/event_router.h
@@ -105,9 +105,11 @@
   // methods BroadcastEvent or DispatchEventToExtension.
   static void DispatchEventToSender(IPC::Sender* ipc_sender,
                                     void* browser_context_id,
+                                    int render_process_id,
                                     const std::string& extension_id,
                                     events::HistogramValue histogram_value,
                                     const std::string& event_name,
+                                    int64_t service_worker_version_id,
                                     std::unique_ptr<base::ListValue> event_args,
                                     UserGestureState user_gesture,
                                     const EventFilteringInfo& info);
@@ -338,15 +340,19 @@
   // Track the dispatched events that have not yet sent an ACK from the
   // renderer.
   void IncrementInFlightEvents(content::BrowserContext* context,
+                               content::RenderProcessHost* process,
                                const Extension* extension,
                                int event_id,
-                               const std::string& event_name);
+                               const std::string& event_name,
+                               int64_t service_worker_version_id);
 
   // static
   static void DoDispatchEventToSenderBookkeepingOnUI(
       void* browser_context_id,
+      int render_process_id,
       const std::string& extension_id,
       int event_id,
+      int64_t service_worker_version_id,
       events::HistogramValue histogram_value,
       const std::string& event_name);
 
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 8913381..fb0ff05 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1018,7 +1018,7 @@
   PLATFORMKEYSINTERNAL_SELECTCLIENTCERTIFICATES = 957,
   CRYPTOTOKENPRIVATE_CANORIGINASSERTAPPID = 958,
   DELETED_EASYUNLOCKPRIVATE_SETAUTOPAIRINGRESULT = 959,
-  FILEMANAGERPRIVATE_ISUMAENABLED = 960,
+  DELETED_FILEMANAGERPRIVATE_ISUMAENABLED = 960,
   WEBVIEWINTERNAL_SETALLOWSCALING = 961,
   PLATFORMKEYSINTERNAL_GETPUBLICKEY = 962,
   RUNTIME_OPENOPTIONSPAGE = 963,
diff --git a/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc b/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc
index ffa79cf2..019c445 100644
--- a/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc
+++ b/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc
@@ -14,6 +14,7 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
+#include "content/public/common/child_process_host.h"
 #include "extensions/browser/api/extensions_api_client.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/guest_view/app_view/app_view_guest.h"
@@ -27,6 +28,7 @@
 #include "extensions/browser/view_type_utils.h"
 #include "extensions/common/features/feature.h"
 #include "extensions/common/features/feature_provider.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-forward.h"
 
 using guest_view::GuestViewBase;
 using guest_view::GuestViewManager;
@@ -71,9 +73,10 @@
     return;  // Could happen at tab shutdown.
 
   EventRouter::DispatchEventToSender(
-      owner->GetRenderViewHost(), guest->browser_context(), guest->owner_host(),
-      histogram_value, event_name, std::move(event_args),
-      EventRouter::USER_GESTURE_UNKNOWN, info);
+      owner->GetRenderViewHost(), guest->browser_context(),
+      content::ChildProcessHost::kInvalidUniqueID, guest->owner_host(),
+      histogram_value, event_name, blink::mojom::kInvalidServiceWorkerVersionId,
+      std::move(event_args), EventRouter::USER_GESTURE_UNKNOWN, info);
 }
 
 bool ExtensionsGuestViewManagerDelegate::IsGuestAvailableToContext(
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json
index 8aba3a0..65a5e108 100644
--- a/extensions/common/api/_api_features.json
+++ b/extensions/common/api/_api_features.json
@@ -571,13 +571,6 @@
     "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
     "contexts": ["blessed_extension"]
   },
-  "types.private": {
-    // preferencesPrivate is the only API that uses types.private.
-    // If any other APIs need it then they'll need to be added in
-    // separate rules.
-    "dependencies": ["permission:preferencesPrivate"],
-    "contexts": ["blessed_extension"]
-  },
   "usb": {
     "dependencies": ["permission:usb"],
     "contexts": ["blessed_extension"]
diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h
index 044e431..fd703e48 100644
--- a/extensions/common/permissions/api_permission.h
+++ b/extensions/common/permissions/api_permission.h
@@ -157,7 +157,7 @@
     kPlatformKeys = 113,
     kDeleted_Plugin = 114,
     kPower = 115,
-    kPreferencesPrivate = 116,
+    kDeleted_PreferencesPrivate = 116,
     kDeleted_PrincipalsPrivate = 117,
     kPrinterProvider = 118,
     kPrivacy = 119,
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn
index c7f428e5..f32360c 100644
--- a/extensions/renderer/BUILD.gn
+++ b/extensions/renderer/BUILD.gn
@@ -96,8 +96,6 @@
     "display_source_custom_bindings.h",
     "dom_activity_logger.cc",
     "dom_activity_logger.h",
-    "easy_unlock_proximity_required_stub.cc",
-    "easy_unlock_proximity_required_stub.h",
     "event_bindings.cc",
     "event_bindings.h",
     "event_bookkeeper.cc",
diff --git a/extensions/renderer/easy_unlock_proximity_required_stub.cc b/extensions/renderer/easy_unlock_proximity_required_stub.cc
deleted file mode 100644
index 8d9c8f70..0000000
--- a/extensions/renderer/easy_unlock_proximity_required_stub.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "extensions/renderer/easy_unlock_proximity_required_stub.h"
-
-#include "extensions/renderer/bindings/api_binding_util.h"
-#include "extensions/renderer/bindings/api_event_handler.h"
-#include "gin/arguments.h"
-#include "gin/handle.h"
-#include "gin/object_template_builder.h"
-
-namespace extensions {
-
-v8::Local<v8::Object> EasyUnlockProximityRequiredStub::Create(
-    v8::Isolate* isolate,
-    const std::string& property_name,
-    const base::ListValue* property_values,
-    APIRequestHandler* request_handler,
-    APIEventHandler* event_handler,
-    APITypeReferenceMap* type_refs,
-    const BindingAccessChecker* access_checker) {
-  gin::Handle<EasyUnlockProximityRequiredStub> handle = gin::CreateHandle(
-      isolate, new EasyUnlockProximityRequiredStub(event_handler));
-  return handle.ToV8().As<v8::Object>();
-}
-
-EasyUnlockProximityRequiredStub::EasyUnlockProximityRequiredStub(
-    APIEventHandler* event_handler)
-    : event_handler_(event_handler) {}
-EasyUnlockProximityRequiredStub::~EasyUnlockProximityRequiredStub() {}
-
-gin::WrapperInfo EasyUnlockProximityRequiredStub::kWrapperInfo = {
-    gin::kEmbedderNativeGin};
-
-gin::ObjectTemplateBuilder
-EasyUnlockProximityRequiredStub::GetObjectTemplateBuilder(
-    v8::Isolate* isolate) {
-  return Wrappable<EasyUnlockProximityRequiredStub>::GetObjectTemplateBuilder(
-             isolate)
-      .SetProperty("onChange",
-                   &EasyUnlockProximityRequiredStub::GetOnChangeEvent);
-}
-
-v8::Local<v8::Value> EasyUnlockProximityRequiredStub::GetOnChangeEvent(
-    gin::Arguments* arguments) {
-  v8::Isolate* isolate = arguments->isolate();
-  v8::Local<v8::Context> context = arguments->GetHolderCreationContext();
-  v8::Local<v8::Object> wrapper = GetWrapper(isolate).ToLocalChecked();
-
-  if (!binding::IsContextValidOrThrowError(context))
-    return v8::Undefined(isolate);
-
-  v8::Local<v8::Private> key = v8::Private::ForApi(
-      isolate, gin::StringToSymbol(isolate, "onChangeEvent"));
-  v8::Local<v8::Value> event;
-  if (!wrapper->GetPrivate(context, key).ToLocal(&event)) {
-    NOTREACHED();
-    return v8::Local<v8::Value>();
-  }
-
-  DCHECK(!event.IsEmpty());
-  if (event->IsUndefined()) {
-    event = event_handler_->CreateAnonymousEventInstance(context);
-    v8::Maybe<bool> set_result = wrapper->SetPrivate(context, key, event);
-    if (!set_result.IsJust() || !set_result.FromJust()) {
-      NOTREACHED();
-      return v8::Local<v8::Value>();
-    }
-  }
-  return event;
-}
-
-}  // namespace extensions
diff --git a/extensions/renderer/easy_unlock_proximity_required_stub.h b/extensions/renderer/easy_unlock_proximity_required_stub.h
deleted file mode 100644
index 0d9c6cc..0000000
--- a/extensions/renderer/easy_unlock_proximity_required_stub.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef EXTENSIONS_RENDERER_EASY_UNLOCK_PROXIMITY_REQUIRED_STUB_H_
-#define EXTENSIONS_RENDERER_EASY_UNLOCK_PROXIMITY_REQUIRED_STUB_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "extensions/renderer/bindings/argument_spec.h"
-#include "gin/wrappable.h"
-#include "v8/include/v8.h"
-
-namespace base {
-class ListValue;
-}
-
-namespace gin {
-class Arguments;
-}
-
-namespace extensions {
-class APIEventHandler;
-class APIRequestHandler;
-class BindingAccessChecker;
-
-// A stub object for the EasyUnlockProxmityRequired object. This only needs to
-// support a single property, an event for 'onChange' (which will never be
-// triggered).
-// TODO(devlin): Remove this once the preferencesPrivate API is fully removed.
-// https://crbug.com/593166
-class EasyUnlockProximityRequiredStub final
-    : public gin::Wrappable<EasyUnlockProximityRequiredStub> {
- public:
-  ~EasyUnlockProximityRequiredStub() override;
-
-  static v8::Local<v8::Object> Create(
-      v8::Isolate* isolate,
-      const std::string& property_name,
-      const base::ListValue* property_values,
-      APIRequestHandler* request_handler,
-      APIEventHandler* event_handler,
-      APITypeReferenceMap* type_refs,
-      const BindingAccessChecker* access_checker);
-
-  static gin::WrapperInfo kWrapperInfo;
-
-  gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
-      v8::Isolate* isolate) override;
-
- private:
-  EasyUnlockProximityRequiredStub(APIEventHandler* event_handler);
-
-  // Returns the onChange event.
-  v8::Local<v8::Value> GetOnChangeEvent(gin::Arguments* arguments);
-
-  // The binding system's event handler; guaranteed to outlive this object.
-  APIEventHandler* const event_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(EasyUnlockProximityRequiredStub);
-};
-
-}  // namespace extensions
-
-#endif  // EXTENSIONS_RENDERER_EASY_UNLOCK_PROXIMITY_REQUIRED_STUB_H_
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc
index a3256bae..de84e52 100644
--- a/extensions/renderer/native_extension_bindings_system.cc
+++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -25,7 +25,6 @@
 #include "extensions/renderer/console.h"
 #include "extensions/renderer/content_setting.h"
 #include "extensions/renderer/declarative_content_hooks_delegate.h"
-#include "extensions/renderer/easy_unlock_proximity_required_stub.h"
 #include "extensions/renderer/extension_frame_helper.h"
 #include "extensions/renderer/extension_js_runner.h"
 #include "extensions/renderer/get_script_context.h"
@@ -363,9 +362,6 @@
       weak_factory_(this) {
   api_system_.RegisterCustomType("storage.StorageArea",
                                  base::Bind(&StorageArea::CreateStorageArea));
-  api_system_.RegisterCustomType(
-      "preferencesPrivate.EasyUnlockProximityRequired",
-      base::Bind(&EasyUnlockProximityRequiredStub::Create));
   api_system_.RegisterCustomType("types.ChromeSetting",
                                  base::Bind(&ChromeSetting::Create));
   api_system_.RegisterCustomType("contentSettings.ContentSetting",
diff --git a/ios/chrome/browser/autofill/form_suggestion_label.mm b/ios/chrome/browser/autofill/form_suggestion_label.mm
index a8f6cf9..603a65d 100644
--- a/ios/chrome/browser/autofill/form_suggestion_label.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_label.mm
@@ -32,9 +32,6 @@
 
 namespace {
 
-// The button corner radius.
-const CGFloat kCornerRadius = 2.0f;
-
 // Font size of button titles.
 const CGFloat kIpadFontSize = 15.0f;
 const CGFloat kIphoneFontSize = 14.0f;
@@ -44,7 +41,7 @@
 const CGFloat kDescriptionLabelAlpha = 0.55f;
 
 // The horizontal space between the edge of the background and the text.
-const CGFloat kBorderWidth = 8.0f;
+const CGFloat kBorderWidth = 14.0f;
 // The space between items in the label.
 const CGFloat kSpacing = 4.0f;
 
@@ -125,7 +122,6 @@
     if (userInteractionEnabled_) {
       [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
     }
-    [[self layer] setCornerRadius:kCornerRadius];
 
     [self setClipsToBounds:YES];
     [self setUserInteractionEnabled:YES];
@@ -144,6 +140,11 @@
   return self;
 }
 
+- (void)layoutSubviews {
+  [super layoutSubviews];
+  self.layer.cornerRadius = self.bounds.size.height / 2.0;
+}
+
 #pragma mark -
 #pragma mark UIResponder
 
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
index 29014be..d3176385 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
@@ -76,6 +76,8 @@
     "card_list_delegate.h",
     "card_view_controller.h",
     "card_view_controller.mm",
+    "chip_button.h",
+    "chip_button.mm",
     "credential.h",
     "credential.mm",
     "credit_card.h",
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/action_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/action_cell.mm
index 0add3bb75..0dd7806 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/action_cell.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/action_cell.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/autofill/manual_fill/action_cell.h"
 
+#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_button.h"
 #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h"
 #import "ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.h"
 #import "ios/chrome/browser/ui/list_model/list_model.h"
@@ -139,9 +140,11 @@
   UIView* guide = self.contentView;
   self.grayLine = CreateGraySeparatorForContainer(guide);
 
-  self.titleButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapTitleButton:), self);
-  self.titleButton.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
+  self.titleButton = [ManualFillCellButton buttonWithType:UIButtonTypeCustom];
+  [self.titleButton addTarget:self
+                       action:@selector(userDidTapTitleButton:)
+             forControlEvents:UIControlEventTouchUpInside];
+
   [self.contentView addSubview:self.titleButton];
 
   NSMutableArray<NSLayoutConstraint*>* staticConstraints =
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/chip_button.h b/ios/chrome/browser/ui/autofill/manual_fill/chip_button.h
new file mode 100644
index 0000000..b7dc629
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/manual_fill/chip_button.h
@@ -0,0 +1,14 @@
+// Copyright 2019 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 IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CHIP_BUTTON_H_
+#define IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CHIP_BUTTON_H_
+
+#import <UIKit/UIKit.h>
+
+// Buttons with a rounded border and gray background in highlighted state.
+@interface ChipButton : UIButton
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CHIP_BUTTON_H_
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/chip_button.mm b/ios/chrome/browser/ui/autofill/manual_fill/chip_button.mm
new file mode 100644
index 0000000..8d98634
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/manual_fill/chip_button.mm
@@ -0,0 +1,102 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/autofill/manual_fill/chip_button.h"
+
+#include "base/mac/foundation_util.h"
+#import "ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+// Top and bottom padding for the button.
+static const CGFloat kChipVerticalPadding = 14;
+// Left and right padding for the button.
+static const CGFloat kChipHorizontalPadding = 14;
+// Vertical margins for the button. How much bigger the tap target is.
+static const CGFloat kChipVerticalMargin = 4;
+}  // namespace
+
+@interface ChipButton ()
+
+// Gray rounded background view which gives the aspect of a chip.
+@property(strong, nonatomic) UIView* backgroundView;
+
+@end
+
+@implementation ChipButton
+
+- (id)initWithFrame:(CGRect)frame {
+  self = [super initWithFrame:frame];
+  if (self) {
+    [self initializeStyling];
+  }
+  return self;
+}
+
+- (id)initWithCoder:(NSCoder*)aDecoder {
+  self = [super initWithCoder:aDecoder];
+  if (self) {
+    [self initializeStyling];
+  }
+  return self;
+}
+
+- (void)awakeFromNib {
+  [super awakeFromNib];
+  [self initializeStyling];
+}
+
+- (void)layoutSubviews {
+  [super layoutSubviews];
+  self.backgroundView.layer.cornerRadius =
+      self.backgroundView.bounds.size.height / 2.0;
+}
+
+- (void)setHighlighted:(BOOL)highlighted {
+  [super setHighlighted:highlighted];
+  CGFloat alpha = highlighted ? 0.2 : 1.0;
+  self.backgroundView.alpha = alpha;
+}
+
+#pragma mark - Private
+
+- (void)initializeStyling {
+  _backgroundView = [[UIView alloc] init];
+  _backgroundView.userInteractionEnabled = NO;
+  _backgroundView.backgroundColor = UIColor.cr_manualFillChipColor;
+  _backgroundView.translatesAutoresizingMaskIntoConstraints = NO;
+
+  [self addSubview:_backgroundView];
+  [self sendSubviewToBack:_backgroundView];
+  [NSLayoutConstraint activateConstraints:@[
+    [_backgroundView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
+    [_backgroundView.trailingAnchor
+        constraintEqualToAnchor:self.trailingAnchor],
+    [_backgroundView.topAnchor constraintEqualToAnchor:self.topAnchor
+                                              constant:kChipVerticalMargin],
+    [_backgroundView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor
+                                                 constant:-kChipVerticalMargin]
+  ]];
+
+  self.translatesAutoresizingMaskIntoConstraints = NO;
+
+  [self setTitleColor:UIColor.cr_manualFillChipDarkTextColor
+             forState:UIControlStateNormal];
+  self.titleLabel.adjustsFontForContentSizeCategory = YES;
+
+  UIFont* font = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline];
+  UIFontDescriptor* boldFontDescriptor = [font.fontDescriptor
+      fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
+  DCHECK(boldFontDescriptor);
+  self.titleLabel.font = [UIFont fontWithDescriptor:boldFontDescriptor size:0];
+
+  self.contentEdgeInsets =
+      UIEdgeInsetsMake(kChipVerticalPadding, kChipHorizontalPadding,
+                       kChipVerticalPadding, kChipHorizontalPadding);
+}
+
+@end
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm
index 3d53ed8e..8230cfd 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm
@@ -48,6 +48,9 @@
 
 @interface ManualFillAddressCell ()
 
+// Separator line between cells, if needed.
+@property(nonatomic, strong) UIView* grayLine;
+
 // The label with the line1 -- line2.
 @property(nonatomic, strong) UILabel* addressLabel;
 
@@ -58,15 +61,9 @@
 // A button showing the address associated first name.
 @property(nonatomic, strong) UIButton* firstNameButton;
 
-// The separator label between first and middle name/initial.
-@property(nonatomic, strong) UILabel* middleNameSeparatorLabel;
-
 // A button showing the address associated middle name or initial.
 @property(nonatomic, strong) UIButton* middleNameButton;
 
-// The separator label between middle name/initial and last name.
-@property(nonatomic, strong) UILabel* lastNameSeparatorLabel;
-
 // A button showing the address associated last name.
 @property(nonatomic, strong) UIButton* lastNameButton;
 
@@ -82,18 +79,12 @@
 // A button showing zip code.
 @property(nonatomic, strong) UIButton* zipButton;
 
-// The separator label between zip and city.
-@property(nonatomic, strong) UILabel* citySeparatorLabel;
-
 // A button showing city.
 @property(nonatomic, strong) UIButton* cityButton;
 
 // A button showing state/province.
 @property(nonatomic, strong) UIButton* stateButton;
 
-// The separator label between state and country.
-@property(nonatomic, strong) UILabel* countrySeparatorLabel;
-
 // A button showing country.
 @property(nonatomic, strong) UIButton* countryButton;
 
@@ -141,7 +132,7 @@
   self.delegate = delegate;
 
   NSMutableArray<UIView*>* verticalLeadViews = [[NSMutableArray alloc] init];
-  UIView* guide = self.contentView;
+  UIView* guide = self.grayLine;
 
   NSString* blackText = nil;
   NSString* grayText = nil;
@@ -208,13 +199,6 @@
     self.firstNameButton.hidden = YES;
   }
 
-  if (showFirstName && showMiddleName && !largeTypes) {
-    [nameLineViews addObject:self.middleNameSeparatorLabel];
-    self.middleNameSeparatorLabel.hidden = NO;
-  } else {
-    self.middleNameSeparatorLabel.hidden = YES;
-  }
-
   if (showMiddleName) {
     [self.middleNameButton setTitle:address.middleNameOrInitial
                            forState:UIControlStateNormal];
@@ -224,13 +208,6 @@
     self.middleNameButton.hidden = YES;
   }
 
-  if ((showFirstName || showMiddleName) && showLastName && !largeTypes) {
-    [nameLineViews addObject:self.lastNameSeparatorLabel];
-    self.lastNameSeparatorLabel.hidden = NO;
-  } else {
-    self.lastNameSeparatorLabel.hidden = YES;
-  }
-
   if (showLastName) {
     [self.lastNameButton setTitle:address.lastName
                          forState:UIControlStateNormal];
@@ -283,13 +260,6 @@
     self.zipButton.hidden = YES;
   }
 
-  if (address.zip.length && address.city.length && !largeTypes) {
-    [zipCityLineViews addObject:self.citySeparatorLabel];
-    self.citySeparatorLabel.hidden = NO;
-  } else {
-    self.citySeparatorLabel.hidden = YES;
-  }
-
   if (address.city.length) {
     [self.cityButton setTitle:address.city forState:UIControlStateNormal];
     [zipCityLineViews addObject:self.cityButton];
@@ -315,13 +285,6 @@
     self.stateButton.hidden = YES;
   }
 
-  if (address.state.length && address.country.length && !largeTypes) {
-    [stateCountryLineViews addObject:self.countrySeparatorLabel];
-    self.countrySeparatorLabel.hidden = NO;
-  } else {
-    self.countrySeparatorLabel.hidden = YES;
-  }
-
   if (address.country.length) {
     [self.countryButton setTitle:address.country forState:UIControlStateNormal];
     [stateCountryLineViews addObject:self.countryButton];
@@ -353,8 +316,9 @@
     self.emailAddressButton.hidden = YES;
   }
 
-  AppendVerticalConstraintsSpacingForViews(self.dynamicConstraints,
-                                           verticalLeadViews, self.contentView);
+  AppendVerticalConstraintsSpacingForViews(
+      self.dynamicConstraints, verticalLeadViews, self.contentView,
+      TopSystemSpacingMultiplier, 1, BottomSystemSpacingMultiplier);
   [NSLayoutConstraint activateConstraints:self.dynamicConstraints];
 }
 
@@ -372,14 +336,16 @@
     return;
   if (largeTypes) {
     for (UIView* view in views) {
-      AppendHorizontalConstraintsForViews(self.dynamicConstraints, @[ view ],
-                                          guide);
+      AppendHorizontalConstraintsForViews(
+          self.dynamicConstraints, @[ view ], guide, kChipsHorizontalMargin,
+          AppendConstraintsHorizontalEqualOrSmallerThanGuide);
       [verticalLeadViews addObject:view];
     }
   } else {
     AppendHorizontalConstraintsForViews(
-        self.dynamicConstraints, views, guide, 0,
-        AppendConstraintsHorizontalSyncBaselines);
+        self.dynamicConstraints, views, guide, kChipsHorizontalMargin,
+        AppendConstraintsHorizontalSyncBaselines |
+            AppendConstraintsHorizontalEqualOrSmallerThanGuide);
     [verticalLeadViews addObject:views.firstObject];
   }
 }
@@ -388,8 +354,7 @@
 - (void)createViewHierarchy {
   self.selectionStyle = UITableViewCellSelectionStyleNone;
 
-  UIView* guide = self.contentView;
-  CreateGraySeparatorForContainer(guide);
+  self.grayLine = CreateGraySeparatorForContainer(self.contentView);
 
   NSMutableArray<NSLayoutConstraint*>* staticConstraints =
       [[NSMutableArray alloc] init];
@@ -397,81 +362,76 @@
   self.addressLabel = CreateLabel();
   [self.contentView addSubview:self.addressLabel];
   AppendHorizontalConstraintsForViews(staticConstraints, @[ self.addressLabel ],
-                                      guide, ButtonHorizontalMargin);
+                                      self.contentView,
+                                      kButtonHorizontalMargin);
 
-  self.firstNameButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.firstNameButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.firstNameButton];
 
-  self.middleNameSeparatorLabel = CreateLabel();
-  self.middleNameSeparatorLabel.text = @"·";
-  [self.contentView addSubview:self.middleNameSeparatorLabel];
-
-  self.middleNameButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.middleNameButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.middleNameButton];
 
-  self.lastNameSeparatorLabel = CreateLabel();
-  self.lastNameSeparatorLabel.text = @"·";
-  [self.contentView addSubview:self.lastNameSeparatorLabel];
-
-  self.lastNameButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.lastNameButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.lastNameButton];
 
-  self.companyButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.companyButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.companyButton];
-  AppendHorizontalConstraintsForViews(staticConstraints,
-                                      @[ self.companyButton ], guide);
+  AppendHorizontalConstraintsForViews(
+      staticConstraints, @[ self.companyButton ], self.grayLine,
+      kChipsHorizontalMargin,
+      AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
-  self.line1Button = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.line1Button =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.line1Button];
-  AppendHorizontalConstraintsForViews(staticConstraints, @[ self.line1Button ],
-                                      guide);
+  AppendHorizontalConstraintsForViews(
+      staticConstraints, @[ self.line1Button ], self.grayLine,
+      kChipsHorizontalMargin,
+      AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
-  self.line2Button = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.line2Button =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.line2Button];
-  AppendHorizontalConstraintsForViews(staticConstraints, @[ self.line2Button ],
-                                      guide);
+  AppendHorizontalConstraintsForViews(
+      staticConstraints, @[ self.line2Button ], self.grayLine,
+      kChipsHorizontalMargin,
+      AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
-  self.zipButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.zipButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.zipButton];
 
-  self.citySeparatorLabel = CreateLabel();
-  self.citySeparatorLabel.text = @"·";
-  [self.contentView addSubview:self.citySeparatorLabel];
-
-  self.cityButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.cityButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.cityButton];
 
-  self.stateButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.stateButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.stateButton];
 
-  self.countrySeparatorLabel = CreateLabel();
-  self.countrySeparatorLabel.text = @"·";
-  [self.contentView addSubview:self.countrySeparatorLabel];
-
-  self.countryButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.countryButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.countryButton];
 
-  self.phoneNumberButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.phoneNumberButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.phoneNumberButton];
-  AppendHorizontalConstraintsForViews(staticConstraints,
-                                      @[ self.phoneNumberButton ], guide);
+  AppendHorizontalConstraintsForViews(
+      staticConstraints, @[ self.phoneNumberButton ], self.grayLine,
+      kChipsHorizontalMargin,
+      AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
-  self.emailAddressButton = CreateButtonWithSelectorAndTarget(
-      @selector(userDidTapAddressInfo:), self);
+  self.emailAddressButton =
+      CreateChipWithSelectorAndTarget(@selector(userDidTapAddressInfo:), self);
   [self.contentView addSubview:self.emailAddressButton];
-  AppendHorizontalConstraintsForViews(staticConstraints,
-                                      @[ self.emailAddressButton ], guide);
+  AppendHorizontalConstraintsForViews(
+      staticConstraints, @[ self.emailAddressButton ], self.grayLine,
+      kChipsHorizontalMargin,
+      AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
   // Without this set, Voice Over will read the content vertically instead of
   // horizontally.
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm
index 9abf38d..9f8e003 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm
@@ -37,9 +37,6 @@
 @end
 
 @implementation ManualFillCardItem
-@synthesize contentDelegate = _contentDelegate;
-@synthesize navigationDelegate = _navigationDelegate;
-@synthesize card = _card;
 
 - (instancetype)initWithCreditCard:(ManualFillCreditCard*)card
                    contentDelegate:
@@ -186,8 +183,9 @@
     self.cardholderButton.hidden = YES;
   }
 
-  AppendVerticalConstraintsSpacingForViews(self.dynamicConstraints,
-                                           verticalViews, self.contentView);
+  AppendVerticalConstraintsSpacingForViews(
+      self.dynamicConstraints, verticalViews, self.contentView,
+      TopSystemSpacingMultiplier, 1, BottomSystemSpacingMultiplier);
   [NSLayoutConstraint activateConstraints:self.dynamicConstraints];
 }
 
@@ -197,8 +195,7 @@
 - (void)createViewHierarchy {
   self.selectionStyle = UITableViewCellSelectionStyleNone;
 
-  UIView* guide = self.contentView;
-  CreateGraySeparatorForContainer(guide);
+  UIView* grayLine = CreateGraySeparatorForContainer(self.contentView);
 
   NSMutableArray<NSLayoutConstraint*>* staticConstraints =
       [[NSMutableArray alloc] init];
@@ -210,35 +207,40 @@
   self.cardIcon.translatesAutoresizingMaskIntoConstraints = NO;
   [self.contentView addSubview:self.cardIcon];
   AppendHorizontalConstraintsForViews(
-      staticConstraints, @[ self.cardLabel, self.cardIcon ], guide,
-      ButtonHorizontalMargin, AppendConstraintsHorizontalExtraSpaceLeft);
+      staticConstraints, @[ self.cardIcon, self.cardLabel ], self.contentView,
+      kButtonHorizontalMargin);
   [NSLayoutConstraint activateConstraints:@[
-    [self.cardIcon.bottomAnchor
-        constraintEqualToAnchor:self.cardLabel.firstBaselineAnchor]
+    [self.cardIcon.centerYAnchor
+        constraintEqualToAnchor:self.cardLabel.centerYAnchor]
   ]];
 
   self.cardNumberButton =
-      CreateButtonWithSelectorAndTarget(@selector(userDidTapCardNumber:), self);
+      CreateChipWithSelectorAndTarget(@selector(userDidTapCardNumber:), self);
   [self.contentView addSubview:self.cardNumberButton];
-  AppendHorizontalConstraintsForViews(staticConstraints,
-                                      @[ self.cardNumberButton ], guide);
+  AppendHorizontalConstraintsForViews(
+      staticConstraints, @[ self.cardNumberButton ], grayLine,
+      kChipsHorizontalMargin,
+      AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
   self.cardholderButton =
-      CreateButtonWithSelectorAndTarget(@selector(userDidTapCardInfo:), self);
+      CreateChipWithSelectorAndTarget(@selector(userDidTapCardInfo:), self);
   [self.contentView addSubview:self.cardholderButton];
-  AppendHorizontalConstraintsForViews(staticConstraints,
-                                      @[ self.cardholderButton ], guide);
+  AppendHorizontalConstraintsForViews(
+      staticConstraints, @[ self.cardholderButton ], grayLine,
+      kChipsHorizontalMargin,
+      AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
   // Expiration line.
   self.expirationMonthButton =
-      CreateButtonWithSelectorAndTarget(@selector(userDidTapCardInfo:), self);
+      CreateChipWithSelectorAndTarget(@selector(userDidTapCardInfo:), self);
   [self.contentView addSubview:self.expirationMonthButton];
   self.expirationYearButton =
-      CreateButtonWithSelectorAndTarget(@selector(userDidTapCardInfo:), self);
+      CreateChipWithSelectorAndTarget(@selector(userDidTapCardInfo:), self);
   [self.contentView addSubview:self.expirationYearButton];
   UILabel* expirationSeparatorLabel = CreateLabel();
   expirationSeparatorLabel.font =
       [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
+  [expirationSeparatorLabel setTextColor:UIColor.cr_manualFillChipColor];
   expirationSeparatorLabel.text = @"/";
   [self.contentView addSubview:expirationSeparatorLabel];
   AppendHorizontalConstraintsForViews(
@@ -247,8 +249,9 @@
         self.expirationMonthButton, expirationSeparatorLabel,
         self.expirationYearButton
       ],
-      guide, 0, AppendConstraintsHorizontalSyncBaselines);
-
+      grayLine, kChipsHorizontalMargin,
+      AppendConstraintsHorizontalSyncBaselines |
+          AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
   // Without this set, Voice Over will read the content vertically instead of
   // horizontally.
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_button.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_button.mm
index 198d221..41262f88 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_button.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_button.mm
@@ -4,18 +4,62 @@
 
 #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_button.h"
 
+#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h"
 #import "ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
+namespace {
+
+// Top and bottom margins for buttons.
+static const CGFloat kButtonVerticalMargin = 12;
+
+}  // namespace
+
 @implementation ManualFillCellButton
 
+- (id)initWithFrame:(CGRect)frame {
+  self = [super initWithFrame:frame];
+  if (self) {
+    [self initializeStyling];
+  }
+  return self;
+}
+
+- (id)initWithCoder:(NSCoder*)aDecoder {
+  self = [super initWithCoder:aDecoder];
+  if (self) {
+    [self initializeStyling];
+  }
+  return self;
+}
+
+- (void)awakeFromNib {
+  [super awakeFromNib];
+  [self initializeStyling];
+}
+
 - (void)setHighlighted:(BOOL)highlighted {
   [super setHighlighted:highlighted];
   CGFloat alpha = highlighted ? 0.07 : 0;
   self.backgroundColor = [UIColor colorWithWhite:0 alpha:alpha];
 }
 
+#pragma mark - Private
+
+- (void)initializeStyling {
+  [self setTitleColor:UIColor.cr_manualFillTintColor
+             forState:UIControlStateNormal];
+  self.translatesAutoresizingMaskIntoConstraints = NO;
+  self.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
+  self.titleLabel.adjustsFontForContentSizeCategory = YES;
+  self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeading;
+  self.contentEdgeInsets =
+      UIEdgeInsetsMake(kButtonVerticalMargin, kButtonHorizontalMargin,
+                       kButtonVerticalMargin, kButtonHorizontalMargin);
+  self.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h
index 9052130..0900cf45 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h
@@ -9,6 +9,12 @@
 
 namespace {
 
+// Left and right margins of the cell content and buttons.
+static const CGFloat kButtonHorizontalMargin = 16;
+
+// Left and right margins for the chips.
+static const CGFloat kChipsHorizontalMargin = -1;
+
 // The multiplier for the base system spacing at the top margin.
 static const CGFloat TopSystemSpacingMultiplier = 1.58;
 
@@ -18,26 +24,19 @@
 // The multiplier for the base system spacing at the bottom margin.
 static const CGFloat BottomSystemSpacingMultiplier = 2.26;
 
-// Top and bottom margins for buttons.
-static const CGFloat ButtonVerticalMargin = 12;
-
-// Left and right margins of the cell content and buttons.
-static const CGFloat ButtonHorizontalMargin = 16;
-
 // Options for |AppendHorizontalConstraintsForViews|.
 typedef NS_OPTIONS(NSUInteger, AppendConstraints) {
   AppendConstraintsNone = 0,
-  // Add to options to give remaining space in the line to leftmost item.
-  AppendConstraintsHorizontalExtraSpaceLeft = 1 << 0,
-  // Add to options to give remaining space in the line to leftmost item.
-  AppendConstraintsHorizontalSyncBaselines = 1 << 1,
+  // Add an equal constraint to the baselines.
+  AppendConstraintsHorizontalSyncBaselines = 1 << 0,
+  // The views can be constraint smaller than the guide.
+  AppendConstraintsHorizontalEqualOrSmallerThanGuide = 1 << 1,
 };
 
 }  // namespace
 
-// Creates a blank button in fallback style, for the given |action| and
-// |target|.
-UIButton* CreateButtonWithSelectorAndTarget(SEL action, id target);
+// Creates a blank button in chip style, for the given |action| and |target|.
+UIButton* CreateChipWithSelectorAndTarget(SEL action, id target);
 
 // Adds vertical constraints to given list, laying |views| vertically (based on
 // firstBaselineAnchor for the buttons or labels) inside |container|, starting
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.mm
index 741e41e7..6f49651 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.mm
@@ -6,7 +6,7 @@
 
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_button.h"
+#import "ios/chrome/browser/ui/autofill/manual_fill/chip_button.h"
 #import "ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.h"
 #import "ios/chrome/common/ui_util/constraints_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -16,22 +16,18 @@
 #error "This file requires ARC support."
 #endif
 
-UIButton* CreateButtonWithSelectorAndTarget(SEL action, id target) {
-  UIButton* button = [ManualFillCellButton buttonWithType:UIButtonTypeCustom];
-  [button setTitleColor:UIColor.cr_manualFillTintColor
-               forState:UIControlStateNormal];
+namespace {
+// Horizontal spacing between views in |AppendHorizontalConstraintsForViews|.
+constexpr CGFloat kHorizontalSpacing = 16;
+}  // namespace
+
+UIButton* CreateChipWithSelectorAndTarget(SEL action, id target) {
+  UIButton* button = [ChipButton buttonWithType:UIButtonTypeCustom];
   button.translatesAutoresizingMaskIntoConstraints = NO;
-  button.titleLabel.font =
-      [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
   button.titleLabel.adjustsFontForContentSizeCategory = YES;
-  button.contentHorizontalAlignment =
-      UIControlContentHorizontalAlignmentLeading;
   [button addTarget:target
                 action:action
       forControlEvents:UIControlEventTouchUpInside];
-  button.contentEdgeInsets =
-      UIEdgeInsetsMake(ButtonVerticalMargin, ButtonHorizontalMargin,
-                       ButtonVerticalMargin, ButtonHorizontalMargin);
   return button;
 }
 
@@ -57,11 +53,11 @@
   CGFloat multiplier = topSystemSpacingMultiplier;
   for (UIView* view in views) {
     [constraints
-        addObject:[view.firstBaselineAnchor
+        addObject:[view.topAnchor
                       constraintEqualToSystemSpacingBelowAnchor:previousAnchor
                                                      multiplier:multiplier]];
     multiplier = middleSystemSpacingMultiplier;
-    previousAnchor = view.lastBaselineAnchor;
+    previousAnchor = view.bottomAnchor;
   }
   multiplier = bottomSystemSpacingMultiplier;
   [constraints
@@ -95,39 +91,41 @@
     return;
 
   NSLayoutXAxisAnchor* previousAnchor = guide.leadingAnchor;
-  UILayoutPriority firstPriority =
-      options & AppendConstraintsHorizontalExtraSpaceLeft
-          ? UILayoutPriorityDefaultHigh
-          : UILayoutPriorityDefaultLow;
-  UILayoutPriority lastPriority =
-      options & AppendConstraintsHorizontalExtraSpaceLeft
-          ? UILayoutPriorityDefaultLow
-          : UILayoutPriorityDefaultHigh;
 
-  CGFloat shift = margin;
+  BOOL isFirstView = YES;
   for (UIView* view in views) {
+    CGFloat constant = isFirstView ? margin : kHorizontalSpacing;
     [constraints
         addObject:[view.leadingAnchor constraintEqualToAnchor:previousAnchor
-                                                     constant:shift]];
-    [view setContentCompressionResistancePriority:firstPriority
+                                                     constant:constant]];
+    [view setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
                                           forAxis:
                                               UILayoutConstraintAxisHorizontal];
-    [view setContentHuggingPriority:lastPriority
+    [view setContentHuggingPriority:UILayoutPriorityDefaultHigh
                             forAxis:UILayoutConstraintAxisHorizontal];
     previousAnchor = view.trailingAnchor;
-    shift = 0;
+    isFirstView = NO;
   }
 
-  [constraints addObject:[views.lastObject.trailingAnchor
-                             constraintEqualToAnchor:guide.trailingAnchor
-                                            constant:-margin]];
-  // Give all remaining space to the last button, minus margin, as per UX.
-  [views.lastObject
-      setContentCompressionResistancePriority:lastPriority
-                                      forAxis:UILayoutConstraintAxisHorizontal];
-  [views.lastObject setContentHuggingPriority:firstPriority
-                                      forAxis:UILayoutConstraintAxisHorizontal];
+  if (options & AppendConstraintsHorizontalEqualOrSmallerThanGuide) {
+    [constraints
+        addObject:[views.lastObject.trailingAnchor
+                      constraintLessThanOrEqualToAnchor:guide.trailingAnchor
+                                               constant:-margin]];
 
+  } else {
+    [constraints addObject:[views.lastObject.trailingAnchor
+                               constraintEqualToAnchor:guide.trailingAnchor
+                                              constant:-margin]];
+    // Give all remaining space to the last button, minus margin, as per UX.
+    [views.lastObject
+        setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh
+                                        forAxis:
+                                            UILayoutConstraintAxisHorizontal];
+    [views.lastObject
+        setContentHuggingPriority:UILayoutPriorityDefaultLow
+                          forAxis:UILayoutConstraintAxisHorizontal];
+  }
   if (options & AppendConstraintsHorizontalSyncBaselines) {
     AppendEqualBaselinesConstraints(constraints, views);
   }
@@ -169,9 +167,9 @@
     [grayLine.heightAnchor constraintEqualToConstant:1],
     // Horizontal constraints.
     [grayLine.leadingAnchor constraintEqualToAnchor:safeArea.leadingAnchor
-                                           constant:ButtonHorizontalMargin],
+                                           constant:kButtonHorizontalMargin],
     [safeArea.trailingAnchor constraintEqualToAnchor:grayLine.trailingAnchor
-                                            constant:ButtonHorizontalMargin],
+                                            constant:kButtonHorizontalMargin],
   ]];
 
   return grayLine;
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.mm
index 457be8a..d1ab656 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.mm
@@ -115,7 +115,7 @@
 
   [self.usernameButton setTitle:@"" forState:UIControlStateNormal];
   self.usernameButton.enabled = YES;
-  [self.usernameButton setTitleColor:UIColor.cr_manualFillTintColor
+  [self.usernameButton setTitleColor:UIColor.cr_manualFillChipDarkTextColor
                             forState:UIControlStateNormal];
 
   [self.passwordButton setTitle:@"" forState:UIControlStateNormal];
@@ -205,8 +205,7 @@
   self.dynamicConstraints = [[NSMutableArray alloc] init];
   AppendVerticalConstraintsSpacingForViews(
       self.dynamicConstraints, verticalLeadViews, self.contentView,
-      topSystemSpacingMultiplier, MiddleSystemSpacingMultiplier,
-      bottomSystemSpacingMultiplier);
+      topSystemSpacingMultiplier, 1, bottomSystemSpacingMultiplier);
   [NSLayoutConstraint activateConstraints:self.dynamicConstraints];
 }
 
@@ -216,8 +215,7 @@
 - (void)createViewHierarchy {
   self.selectionStyle = UITableViewCellSelectionStyleNone;
 
-  UIView* guide = self.contentView;
-  self.grayLine = CreateGraySeparatorForContainer(guide);
+  self.grayLine = CreateGraySeparatorForContainer(self.contentView);
   NSMutableArray<NSLayoutConstraint*>* staticConstraints =
       [[NSMutableArray alloc] init];
 
@@ -226,20 +224,24 @@
   self.siteNameLabel.adjustsFontForContentSizeCategory = YES;
   [self.contentView addSubview:self.siteNameLabel];
   AppendHorizontalConstraintsForViews(staticConstraints,
-                                      @[ self.siteNameLabel ], guide,
-                                      ButtonHorizontalMargin);
+                                      @[ self.siteNameLabel ], self.contentView,
+                                      kButtonHorizontalMargin);
 
-  self.usernameButton = CreateButtonWithSelectorAndTarget(
+  self.usernameButton = CreateChipWithSelectorAndTarget(
       @selector(userDidTapUsernameButton:), self);
   [self.contentView addSubview:self.usernameButton];
-  AppendHorizontalConstraintsForViews(staticConstraints,
-                                      @[ self.usernameButton ], guide);
+  AppendHorizontalConstraintsForViews(
+      staticConstraints, @[ self.usernameButton ], self.grayLine,
+      kChipsHorizontalMargin,
+      AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
-  self.passwordButton = CreateButtonWithSelectorAndTarget(
+  self.passwordButton = CreateChipWithSelectorAndTarget(
       @selector(userDidTapPasswordButton:), self);
   [self.contentView addSubview:self.passwordButton];
-  AppendHorizontalConstraintsForViews(staticConstraints,
-                                      @[ self.passwordButton ], guide);
+  AppendHorizontalConstraintsForViews(
+      staticConstraints, @[ self.passwordButton ], self.grayLine,
+      kChipsHorizontalMargin,
+      AppendConstraintsHorizontalEqualOrSmallerThanGuide);
 
   [NSLayoutConstraint activateConstraints:staticConstraints];
 }
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.h b/ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.h
index b85d53e67..b30f7eb 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.h
+++ b/ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.h
@@ -12,6 +12,12 @@
 // Color to set in interactable elements for manual fill (0.1, 0.45, 0.91 RGB).
 @property(class, nonatomic, readonly) UIColor* cr_manualFillTintColor;
 
+// Color for the text in manual fill chips.
+@property(class, nonatomic, readonly) UIColor* cr_manualFillChipDarkTextColor;
+
+// Color for the manual fill chips.
+@property(class, nonatomic, readonly) UIColor* cr_manualFillChipColor;
+
 // Color for the line separators in manual fill (0.66, 0.66, 0.66 RGB).
 @property(class, nonatomic, readonly) UIColor* cr_manualFillSeparatorColor;
 
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.mm b/ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.mm
index f21412eb..edfa1ac 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.mm
@@ -16,16 +16,32 @@
   return color;
 }
 
++ (UIColor*)cr_manualFillChipColor {
+  static UIColor* color = [UIColor colorWithRed:236.0 / 255.0
+                                          green:239.0 / 255.0
+                                           blue:241.0 / 255.0
+                                          alpha:1.0];
+  return color;
+}
+
++ (UIColor*)cr_manualFillChipDarkTextColor {
+  static UIColor* color = [UIColor colorWithRed:55.0 / 255.0
+                                          green:55.0 / 255.0
+                                           blue:55.0 / 255.0
+                                          alpha:1.0];
+  return color;
+}
+
 + (UIColor*)cr_manualFillSeparatorColor {
-  static UIColor* color = [UIColor colorWithRed:188 / 255.0
-                                          green:187 / 255.0
-                                           blue:193 / 255.0
-                                          alpha:1 / 1.0];
+  static UIColor* color = [UIColor colorWithRed:188.0 / 255.0
+                                          green:187.0 / 255.0
+                                           blue:193.0 / 255.0
+                                          alpha:1.0];
   return color;
 }
 
 + (UIColor*)cr_manualFillGrayLineColor {
-  static UIColor* color = [UIColor colorWithWhite:0.88 alpha:1];
+  static UIColor* color = [UIColor colorWithWhite:0.88 alpha:1.0];
   return color;
 }
 
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
index 0ebb504..5b01223 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
@@ -226,10 +226,10 @@
 
   self.navigationItem.hidesBackButton = YES;
 
-  UIBarButtonItem* cancelItem =
-      [ChromeIcon templateBarButtonItemWithImage:[ChromeIcon closeIcon]
-                                          target:self
-                                          action:@selector(cancel)];
+  UIBarButtonItem* cancelItem = [[UIBarButtonItem alloc]
+      initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+                           target:self
+                           action:@selector(cancel)];
   cancelItem.accessibilityIdentifier = @"Cancel";
   self.navigationItem.leftBarButtonItem = cancelItem;
   self.cancelItem = cancelItem;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
index 1ba60bd..d8ebe725 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
@@ -177,12 +177,10 @@
 
   if (self.editingExistingFolder) {
     // Add Cancel Button.
-    UIBarButtonItem* cancelItem =
-        [ChromeIcon templateBarButtonItemWithImage:[ChromeIcon closeIcon]
-                                            target:self
-                                            action:@selector(cancel)];
-    cancelItem.accessibilityLabel =
-        l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_CANCEL_BUTTON_LABEL);
+    UIBarButtonItem* cancelItem = [[UIBarButtonItem alloc]
+        initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+                             target:self
+                             action:@selector(cancel)];
     cancelItem.accessibilityIdentifier = @"Cancel";
     self.navigationItem.leftBarButtonItem = cancelItem;
 
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm
index 1f8dd1d..3aca5deb 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm
@@ -152,12 +152,10 @@
   self.title = l10n_util::GetNSString(IDS_IOS_BOOKMARK_CHOOSE_GROUP_BUTTON);
 
   if (self.allowsCancel) {
-    UIBarButtonItem* cancelItem =
-        [ChromeIcon templateBarButtonItemWithImage:[ChromeIcon closeIcon]
-                                            target:self
-                                            action:@selector(cancel:)];
-    cancelItem.accessibilityLabel =
-        l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_CANCEL_BUTTON_LABEL);
+    UIBarButtonItem* cancelItem = [[UIBarButtonItem alloc]
+        initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+                             target:self
+                             action:@selector(cancel:)];
     cancelItem.accessibilityIdentifier = @"Cancel";
     self.navigationItem.leftBarButtonItem = cancelItem;
   } else {
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
index c0ca22d..094b3b4 100644
--- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -313,12 +313,12 @@
 
 #pragma mark - Private
 
-// Creates an autoreleased "X" button that closes the settings when tapped.
+// Creates an autoreleased "Cancel" button that closes the settings when tapped.
 - (UIBarButtonItem*)closeButton {
-  UIBarButtonItem* closeButton =
-      [ChromeIcon templateBarButtonItemWithImage:[ChromeIcon closeIcon]
-                                          target:self
-                                          action:@selector(closeSettings)];
+  UIBarButtonItem* closeButton = [[UIBarButtonItem alloc]
+      initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+                           target:self
+                           action:@selector(closeSettings)];
   closeButton.accessibilityLabel = l10n_util::GetNSString(IDS_ACCNAME_CLOSE);
   return closeButton;
 }
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
index 4f87445b..65b3ae4 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -4,6 +4,7 @@
 
 #include "media/gpu/v4l2/v4l2_device.h"
 
+#include <algorithm>
 #include <set>
 
 #include <libdrm/drm_fourcc.h>
@@ -37,21 +38,23 @@
   static std::unique_ptr<V4L2Buffer> Create(scoped_refptr<V4L2Device> device,
                                             enum v4l2_buf_type type,
                                             enum v4l2_memory memory,
-                                            size_t planes_count,
+                                            const struct v4l2_format& format,
                                             size_t buffer_id);
   ~V4L2Buffer();
 
   void* GetPlaneMapping(const size_t plane);
   size_t GetMemoryUsage() const;
   const struct v4l2_buffer* v4l2_buffer() const { return &v4l2_buffer_; }
+  const scoped_refptr<VideoFrame>& GetVideoFrame();
 
  private:
   V4L2Buffer(scoped_refptr<V4L2Device> device,
              enum v4l2_buf_type type,
              enum v4l2_memory memory,
-             size_t planes_count,
+             const struct v4l2_format& format,
              size_t buffer_id);
   bool Query();
+  scoped_refptr<VideoFrame> CreateVideoFrame();
 
   scoped_refptr<V4L2Device> device_;
   std::vector<void*> plane_mappings_;
@@ -63,17 +66,20 @@
   // the number of allocated planes, resulting in memory corruption.
   struct v4l2_plane v4l2_planes_[VIDEO_MAX_PLANES] = {{}};
 
+  struct v4l2_format format_;
+  scoped_refptr<VideoFrame> video_frame_;
+
   DISALLOW_COPY_AND_ASSIGN(V4L2Buffer);
 };
 
 std::unique_ptr<V4L2Buffer> V4L2Buffer::Create(scoped_refptr<V4L2Device> device,
                                                enum v4l2_buf_type type,
                                                enum v4l2_memory memory,
-                                               size_t planes_count,
+                                               const struct v4l2_format& format,
                                                size_t buffer_id) {
   // Not using std::make_unique because constructor is private.
   std::unique_ptr<V4L2Buffer> buffer(
-      new V4L2Buffer(device, type, memory, planes_count, buffer_id));
+      new V4L2Buffer(device, type, memory, format, buffer_id));
 
   if (!buffer->Query())
     return nullptr;
@@ -84,14 +90,16 @@
 V4L2Buffer::V4L2Buffer(scoped_refptr<V4L2Device> device,
                        enum v4l2_buf_type type,
                        enum v4l2_memory memory,
-                       size_t planes_count,
+                       const struct v4l2_format& format,
                        size_t buffer_id)
-    : device_(device) {
+    : device_(device), format_(format) {
   DCHECK(V4L2_TYPE_IS_MULTIPLANAR(type));
-  DCHECK_LE(planes_count, base::size(v4l2_planes_));
+  DCHECK_LE(format.fmt.pix_mp.num_planes, base::size(v4l2_planes_));
   v4l2_buffer_.m.planes = v4l2_planes_;
   // Just in case we got more planes than we want.
-  v4l2_buffer_.length = std::min(planes_count, base::size(v4l2_planes_));
+  v4l2_buffer_.length =
+      std::min(static_cast<size_t>(format.fmt.pix_mp.num_planes),
+               base::size(v4l2_planes_));
   v4l2_buffer_.index = buffer_id;
   v4l2_buffer_.type = type;
   v4l2_buffer_.memory = memory;
@@ -156,6 +164,43 @@
   return usage;
 }
 
+scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
+  auto layout = V4L2Device::V4L2FormatToVideoFrameLayout(format_);
+  if (!layout) {
+    DVLOG(1) << "Cannot create frame layout for V4L2 buffers";
+    return nullptr;
+  }
+
+  std::vector<base::ScopedFD> dmabuf_fds = device_->GetDmabufsForV4L2Buffer(
+      v4l2_buffer_.index, v4l2_buffer_.length,
+      static_cast<enum v4l2_buf_type>(v4l2_buffer_.type));
+  if (dmabuf_fds.empty()) {
+    VLOGF(1) << "Failed to get DMABUFs of V4L2 buffer";
+    return nullptr;
+  }
+
+  gfx::Size size(format_.fmt.pix_mp.width, format_.fmt.pix_mp.height);
+
+  return VideoFrame::WrapExternalDmabufs(
+      *layout, gfx::Rect(size), size, std::move(dmabuf_fds), base::TimeDelta());
+}
+
+const scoped_refptr<VideoFrame>& V4L2Buffer::GetVideoFrame() {
+  // We can create the VideoFrame only when using MMAP buffers.
+  if (v4l2_buffer_.memory != V4L2_MEMORY_MMAP) {
+    DVLOGF(1) << "Cannot create video frame from non-MMAP buffer";
+    // video_frame_ should be null since that's its default value.
+    DCHECK_EQ(video_frame_, nullptr);
+    return video_frame_;
+  }
+
+  // Create the video frame instance if requiring it for the first time.
+  if (!video_frame_)
+    video_frame_ = CreateVideoFrame();
+
+  return video_frame_;
+}
+
 // A thread-safe pool of buffer indexes, allowing buffers to be obtained and
 // returned from different threads. All the methods of this class are
 // thread-safe. Users should keep a scoped_refptr to instances of this class
@@ -217,6 +262,8 @@
   bool QueueBuffer();
   void* GetPlaneMapping(const size_t plane);
 
+  const scoped_refptr<VideoFrame>& GetVideoFrame();
+
   // Data from the buffer, that users can query and/or write.
   struct v4l2_buffer v4l2_buffer_;
   // WARNING: do not change this to a vector or something smaller than
@@ -283,6 +330,20 @@
   return queue_->buffers_[BufferId()]->GetPlaneMapping(plane);
 }
 
+const scoped_refptr<VideoFrame>& V4L2BufferRefBase::GetVideoFrame() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  // Used so we can return a const scoped_refptr& in all cases.
+  static const scoped_refptr<VideoFrame> null_videoframe;
+
+  if (!queue_)
+    return null_videoframe;
+
+  DCHECK_LE(BufferId(), queue_->buffers_.size());
+
+  return queue_->buffers_[BufferId()]->GetVideoFrame();
+}
+
 V4L2WritableBufferRef::V4L2WritableBufferRef() {
   // Invalid buffers can be created from any thread.
   DETACH_FROM_SEQUENCE(sequence_checker_);
@@ -322,6 +383,12 @@
   return *this;
 }
 
+const scoped_refptr<VideoFrame>& V4L2WritableBufferRef::GetVideoFrame() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  return buffer_data_->GetVideoFrame();
+}
+
 bool V4L2WritableBufferRef::IsValid() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
@@ -497,6 +564,12 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
+const scoped_refptr<VideoFrame>& V4L2ReadableBuffer::GetVideoFrame() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  return buffer_data_->GetVideoFrame();
+}
+
 V4L2ReadableBuffer::~V4L2ReadableBuffer() {
   // This method is thread-safe. Since we are the destructor, we are guaranteed
   // to be called from the only remaining reference to us. Also, we are just
@@ -642,7 +715,7 @@
 
   // Now query all buffer information.
   for (size_t i = 0; i < reqbufs.count; i++) {
-    auto buffer = V4L2Buffer::Create(device_, type_, memory_, planes_count_, i);
+    auto buffer = V4L2Buffer::Create(device_, type_, memory_, format, i);
 
     if (!buffer) {
       DeallocateBuffers();
diff --git a/media/gpu/v4l2/v4l2_device.h b/media/gpu/v4l2/v4l2_device.h
index 5f75c2a..2e9fd58 100644
--- a/media/gpu/v4l2/v4l2_device.h
+++ b/media/gpu/v4l2/v4l2_device.h
@@ -105,6 +105,15 @@
   // Returns the previously-set number of bytes used for |plane|.
   size_t GetPlaneBytesUsed(const size_t plane) const;
 
+  // Return the VideoFrame underlying this buffer. The VideoFrame's layout
+  // will match that of the V4L2 format. This method will *always* return the
+  // same VideoFrame instance for a given V4L2 buffer. Moreover, the VideoFrame
+  // instance will also be the same across V4L2WritableBufferRef and
+  // V4L2ReadableBufferRef if both references point to the same V4L2 buffer.
+  // Note: at the moment, this method is valid for MMAP buffers only. It will
+  // return nullptr for any other buffer type.
+  const scoped_refptr<VideoFrame>& GetVideoFrame() WARN_UNUSED_RESULT;
+
   // Return the V4L2 buffer ID of the underlying buffer.
   // TODO(acourbot) This is used for legacy clients but should be ultimately
   // removed. See crbug/879971
@@ -155,6 +164,15 @@
   // removed. See crbug/879971
   size_t BufferId() const;
 
+  // Return the VideoFrame underlying this buffer. The VideoFrame's layout
+  // will match that of the V4L2 format. This method will *always* return the
+  // same VideoFrame instance for a given V4L2 buffer. Moreover, the VideoFrame
+  // instance will also be the same across V4L2WritableBufferRef and
+  // V4L2ReadableBufferRef if both references point to the same V4L2 buffer.
+  // Note: at the moment, this method is valid for MMAP buffers only. It will
+  // return nullptr for any other buffer type.
+  const scoped_refptr<VideoFrame>& GetVideoFrame() WARN_UNUSED_RESULT;
+
  private:
   friend class V4L2BufferRefFactory;
   friend class base::RefCountedThreadSafe<V4L2ReadableBuffer>;
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
index 7a998b0..98cd9cb3 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -434,24 +434,12 @@
     DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR);
     DCHECK_EQ(output_record.picture_id, -1);
     DCHECK(!output_record.cleared);
-    DCHECK(output_record.processor_input_fds.empty());
 
     output_record.picture_id = buffers[i].id();
     output_record.texture_id = buffers[i].service_texture_ids().empty()
                                    ? 0
                                    : buffers[i].service_texture_ids()[0];
 
-    if (image_processor_device_) {
-      std::vector<base::ScopedFD> dmabuf_fds = device_->GetDmabufsForV4L2Buffer(
-          i, output_planes_count_, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
-      if (dmabuf_fds.empty()) {
-        VLOGF(1) << "Failed to get DMABUFs of decoder.";
-        NOTIFY_ERROR(PLATFORM_FAILURE);
-        return;
-      }
-      output_record.processor_input_fds = std::move(dmabuf_fds);
-    }
-
     if (output_mode_ == Config::OutputMode::ALLOCATE) {
       std::vector<base::ScopedFD> dmabuf_fds;
       dmabuf_fds = egl_image_device_->GetDmabufsForV4L2Buffer(
@@ -2497,17 +2485,9 @@
   DVLOGF(4);
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
 
-  auto layout = VideoFrameLayout::Create(
-      V4L2Device::V4L2PixFmtToVideoPixelFormat(output_format_fourcc_),
-      coded_size_);
-  if (!layout) {
-    return false;
-  }
   OutputRecord& output_record = output_buffer_map_[buf->BufferId()];
-  scoped_refptr<VideoFrame> input_frame = VideoFrame::WrapExternalDmabufs(
-      *layout, gfx::Rect(visible_size_), visible_size_,
-      DuplicateFDs(output_record.processor_input_fds), base::TimeDelta());
 
+  scoped_refptr<VideoFrame> input_frame = buf->GetVideoFrame();
   if (!input_frame) {
     VLOGF(1) << "Failed wrapping input frame!";
     return false;
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
index c95e8a2e..a7ad43e3 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.h
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
@@ -193,8 +193,6 @@
     GLuint texture_id;
     bool cleared;           // Whether the texture is cleared and safe to render
                             // from. See TextureManager for details.
-    // Input fds of the processor. Exported from the decoder.
-    std::vector<base::ScopedFD> processor_input_fds;
     // Output fds. Used only when OutputMode is IMPORT.
     std::vector<base::ScopedFD> output_fds;
   };
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index 771dbf6..4a953ac 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -41,26 +41,13 @@
 
 namespace {
 
-std::unique_ptr<ClientSocketPoolManager> CreateSocketPoolManager(
-    HttpNetworkSession::SocketPoolType pool_type,
+SSLClientSocketContext CreateClientSocketContext(
     const HttpNetworkSession::Context& context,
-    SSLClientSessionCache* ssl_client_session_cache,
-    SSLClientSessionCache* ssl_client_session_cache_privacy_mode,
-    WebSocketEndpointLockManager* websocket_endpoint_lock_manager) {
-  // TODO(yutak): Differentiate WebSocket pool manager and allow more
-  // simultaneous connections for WebSockets.
-  return std::make_unique<ClientSocketPoolManagerImpl>(
-      context.net_log,
-      context.client_socket_factory ? context.client_socket_factory
-                                    : ClientSocketFactory::GetDefaultFactory(),
-      context.socket_performance_watcher_factory,
-      context.network_quality_estimator, context.host_resolver,
+    SSLClientSessionCache* ssl_client_session_cache) {
+  return SSLClientSocketContext(
       context.cert_verifier, context.channel_id_service,
       context.transport_security_state, context.cert_transparency_verifier,
-      context.ct_policy_enforcer, ssl_client_session_cache,
-      ssl_client_session_cache_privacy_mode, context.ssl_config_service,
-      websocket_endpoint_lock_manager, context.proxy_delegate,
-      context.http_user_agent_settings, pool_type);
+      context.ct_policy_enforcer, ssl_client_session_cache);
 }
 
 }  // unnamed namespace
@@ -267,18 +254,18 @@
   DCHECK(ssl_config_service_);
   CHECK(http_server_properties_);
 
-  normal_socket_pool_manager_ = CreateSocketPoolManager(
-      NORMAL_SOCKET_POOL, context, &ssl_client_session_cache_,
-      &ssl_client_session_cache_privacy_mode_,
-      &websocket_endpoint_lock_manager_);
-  websocket_socket_pool_manager_ = CreateSocketPoolManager(
-      WEBSOCKET_SOCKET_POOL, context, &ssl_client_session_cache_,
-      &ssl_client_session_cache_privacy_mode_,
-      &websocket_endpoint_lock_manager_);
+  normal_socket_pool_manager_ = std::make_unique<ClientSocketPoolManagerImpl>(
+      CreateCommonConnectJobParams(false /* for_websockets */),
+      CreateCommonConnectJobParams(true /* for_websockets */),
+      context_.ssl_config_service, NORMAL_SOCKET_POOL);
+  websocket_socket_pool_manager_ =
+      std::make_unique<ClientSocketPoolManagerImpl>(
+          CreateCommonConnectJobParams(false /* for_websockets */),
+          CreateCommonConnectJobParams(true /* for_websockets */),
+          context_.ssl_config_service, WEBSOCKET_SOCKET_POOL);
 
-  if (params_.enable_http2) {
+  if (params_.enable_http2)
     next_protos_.push_back(kProtoHTTP2);
-  }
 
   next_protos_.push_back(kProtoHTTP11);
 
@@ -498,6 +485,25 @@
   ssl_client_session_cache_privacy_mode_.Flush();
 }
 
+CommonConnectJobParams HttpNetworkSession::CreateCommonConnectJobParams(
+    bool for_websockets) {
+  // Use null websocket_endpoint_lock_manager, which is only set for WebSockets,
+  // and only when not using a proxy.
+  return CommonConnectJobParams(
+      context_.client_socket_factory ? context_.client_socket_factory
+                                     : ClientSocketFactory::GetDefaultFactory(),
+      context_.host_resolver, &http_auth_cache_,
+      context_.http_auth_handler_factory, &spdy_session_pool_,
+      &quic_stream_factory_, context_.proxy_delegate,
+      context_.http_user_agent_settings,
+      CreateClientSocketContext(context_, &ssl_client_session_cache_),
+      CreateClientSocketContext(context_,
+                                &ssl_client_session_cache_privacy_mode_),
+      context_.socket_performance_watcher_factory,
+      context_.network_quality_estimator, context_.net_log,
+      for_websockets ? &websocket_endpoint_lock_manager_ : nullptr);
+}
+
 ClientSocketPoolManager* HttpNetworkSession::GetSocketPoolManager(
     SocketPoolType pool_type) {
   switch (pool_type) {
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index f677756..0c5ccdd 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -30,6 +30,7 @@
 #include "net/http/http_stream_factory.h"
 #include "net/net_buildflags.h"
 #include "net/quic/quic_stream_factory.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/next_proto.h"
 #include "net/socket/websocket_endpoint_lock_manager.h"
 #include "net/spdy/spdy_session_pool.h"
@@ -374,7 +375,13 @@
 
   // Clear the SSL session cache.
   void ClearSSLSessionCache();
-  void ClearSSLSessionCachePrivacyMode();
+
+  // Returns a CommonConnectJobParams that references the NetworkSession's
+  // components. If |for_websockets| is true, the Params'
+  // |websocket_endpoint_lock_manager| field will be populated. Otherwise, it
+  // will be nullptr.
+  CommonConnectJobParams CreateCommonConnectJobParams(
+      bool for_websockets = false);
 
  private:
   friend class HttpNetworkSessionPeer;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index d2dd0f6c..2e43947c 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -84,6 +84,7 @@
 #include "net/socket/client_socket_factory.h"
 #include "net/socket/client_socket_pool.h"
 #include "net/socket/client_socket_pool_manager.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/connection_attempts.h"
 #include "net/socket/mock_client_socket_pool_manager.h"
 #include "net/socket/next_proto.h"
@@ -377,6 +378,21 @@
             base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME,
             base::test::ScopedTaskEnvironment::NowSource::
                 MAIN_THREAD_MOCK_TIME),
+        dummy_connect_job_params_(
+            nullptr /* client_socket_factory */,
+            nullptr /* host_resolver */,
+            nullptr /* http_auth_cache */,
+            nullptr /* http_auth_handler_factory */,
+            nullptr /* spdy_session_pool */,
+            nullptr /* quic_stream_factory */,
+            nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
+            SSLClientSocketContext(),
+            SSLClientSocketContext(),
+            nullptr /* socket_performance_watcher_factory */,
+            nullptr /* network_quality_estimator */,
+            nullptr /* net_log */,
+            nullptr /* websocket_endpoint_lock_manager */),
         ssl_(ASYNC, OK),
         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
             HttpNetworkSession::NORMAL_SOCKET_POOL)),
@@ -552,6 +568,8 @@
 
   void CheckErrorIsPassedBack(int error, IoMode mode);
 
+  const CommonConnectJobParams dummy_connect_job_params_;
+
   // These clocks are defined here, even though they're only used in the
   // Reporting tests below, since they need to be destroyed after
   // |session_deps_|.
@@ -641,11 +659,15 @@
 }
 #endif  // defined(NTLM_PORTABLE)
 
-template <typename ParentPool>
-class CaptureGroupIdSocketPool : public ParentPool {
+class CaptureGroupIdTransportSocketPool : public TransportClientSocketPool {
  public:
-  CaptureGroupIdSocketPool(HostResolver* host_resolver,
-                           CertVerifier* cert_verifier);
+  explicit CaptureGroupIdTransportSocketPool(
+      const CommonConnectJobParams* common_connect_job_params)
+      : TransportClientSocketPool(0,
+                                  0,
+                                  base::TimeDelta(),
+                                  common_connect_job_params,
+                                  nullptr /* ssl_config_service */) {}
 
   const ClientSocketPool::GroupId& last_group_id_received() const {
     return last_group_id_;
@@ -690,32 +712,6 @@
   bool socket_requested_ = false;
 };
 
-typedef CaptureGroupIdSocketPool<TransportClientSocketPool>
-    CaptureGroupIdTransportSocketPool;
-
-template <typename ParentPool>
-CaptureGroupIdSocketPool<ParentPool>::CaptureGroupIdSocketPool(
-    HostResolver* host_resolver,
-    CertVerifier* /* cert_verifier */)
-    : ParentPool(0,
-                 0,
-                 base::TimeDelta(),
-                 nullptr,
-                 host_resolver,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr,
-                 nullptr) {}
-
 //-----------------------------------------------------------------------------
 
 // Helper functions for validating that AuthChallengeInfo's are correctly
@@ -11303,7 +11299,7 @@
 
     HttpNetworkSessionPeer peer(session.get());
     CaptureGroupIdTransportSocketPool* transport_conn_pool =
-        new CaptureGroupIdTransportSocketPool(nullptr, nullptr);
+        new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
     mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
                                      base::WrapUnique(transport_conn_pool));
@@ -11369,7 +11365,7 @@
     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
                              HostPortPair("http_proxy", 80));
     CaptureGroupIdTransportSocketPool* http_proxy_pool =
-        new CaptureGroupIdTransportSocketPool(nullptr, nullptr);
+        new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
     mock_pool_manager->SetSocketPool(proxy_server,
                                      base::WrapUnique(http_proxy_pool));
@@ -11442,7 +11438,7 @@
         ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
     ASSERT_TRUE(proxy_server.is_valid());
     CaptureGroupIdTransportSocketPool* socks_conn_pool =
-        new CaptureGroupIdTransportSocketPool(nullptr, nullptr);
+        new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
     mock_pool_manager->SetSocketPool(proxy_server,
                                      base::WrapUnique(socks_conn_pool));
@@ -14461,21 +14457,13 @@
   // to validate that the TCP socket is not released to the pool between
   // each round of multi-round authentication.
   HttpNetworkSessionPeer session_peer(session.get());
+  CommonConnectJobParams common_connect_job_params(
+      session->CreateCommonConnectJobParams());
   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
       50,                                // Max sockets for pool
       1,                                 // Max sockets per group
       base::TimeDelta::FromSeconds(10),  // unused_idle_socket_timeout
-      session_deps_.socket_factory.get(), session_deps_.host_resolver.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      session_deps_.cert_verifier.get(), session_deps_.channel_id_service.get(),
-      session_deps_.transport_security_state.get(),
-      session_deps_.cert_transparency_verifier.get(),
-      session_deps_.ct_policy_enforcer.get(),
-      nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      session_deps_.ssl_config_service.get(),
-      nullptr /* socket_performance_watcher_factory */,
-      nullptr /* network_quality_estimator */, session_deps_.net_log);
+      &common_connect_job_params, session_deps_.ssl_config_service.get());
   auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
   mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
                                    base::WrapUnique(transport_pool));
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc
index 0c19f533..54a7cb8 100644
--- a/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -71,28 +71,31 @@
     : public ::testing::TestWithParam<HttpProxyType>,
       public WithScopedTaskEnvironment {
  protected:
-  HttpProxyClientSocketPoolTest()
-      : pool_(std::make_unique<TransportClientSocketPool>(
-            kMaxSockets,
-            kMaxSocketsPerGroup,
-            kUnusedIdleSocketTimeout,
-            &socket_factory_,
-            session_deps_.host_resolver.get(),
-            nullptr /* proxy_delegate */,
-            nullptr /* http_user_agent_settings */,
+  HttpProxyClientSocketPoolTest() {
+    session_deps_.host_resolver->set_synchronous_mode(true);
+    session_ = CreateNetworkSession();
+    common_connect_job_params_ = std::make_unique<CommonConnectJobParams>(
+        &socket_factory_, session_deps_.host_resolver.get(),
+        session_->http_auth_cache(),
+        session_deps_.http_auth_handler_factory.get(),
+        session_->spdy_session_pool(), session_->quic_stream_factory(),
+        nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+        SSLClientSocketContext(session_deps_.cert_verifier.get(),
+                               session_deps_.channel_id_service.get(),
+                               session_deps_.transport_security_state.get(),
+                               session_deps_.cert_transparency_verifier.get(),
+                               session_deps_.ct_policy_enforcer.get(),
+                               nullptr /* ssl_client_session_cache */),
+        SSLClientSocketContext(
             session_deps_.cert_verifier.get(),
             session_deps_.channel_id_service.get(),
             session_deps_.transport_security_state.get(),
             session_deps_.cert_transparency_verifier.get(),
             session_deps_.ct_policy_enforcer.get(),
-            nullptr /* ssl_client_session_cache */,
-            nullptr /* ssl_client_session_cache_privacy_mode */,
-            session_deps_.ssl_config_service.get(),
-            nullptr /* socket_performance_watcher_factory */,
-            &estimator_,
-            nullptr /* net_log */)) {
-    session_deps_.host_resolver->set_synchronous_mode(true);
-    session_ = CreateNetworkSession();
+            nullptr /* ssl_client_session_cache_privacy_mode */),
+        nullptr /* socket_performance_watcher_factory */, &estimator_,
+        nullptr /* net_log */, nullptr /* websocket_lock_endpoint_manager */);
+    InitPoolWithProxyDelegate(nullptr);
   }
 
   ~HttpProxyClientSocketPoolTest() override = default;
@@ -100,18 +103,8 @@
   void InitPoolWithProxyDelegate(ProxyDelegate* proxy_delegate) {
     pool_ = std::make_unique<TransportClientSocketPool>(
         kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-        &socket_factory_, session_deps_.host_resolver.get(), proxy_delegate,
-        nullptr /* http_user_agent_settings */,
-        session_deps_.cert_verifier.get(),
-        session_deps_.channel_id_service.get(),
-        session_deps_.transport_security_state.get(),
-        session_deps_.cert_transparency_verifier.get(),
-        session_deps_.ct_policy_enforcer.get(),
-        nullptr /* ssl_client_session_cache */,
-        nullptr /* ssl_client_session_cache_privacy_mode */,
-        session_deps_.ssl_config_service.get(),
-        nullptr /* socket_performance_watcher_factory */, &estimator_,
-        nullptr /* net_log */);
+        common_connect_job_params_.get(),
+        session_deps_.ssl_config_service.get());
   }
 
   void AddAuthToCache() {
@@ -154,9 +147,6 @@
                 CreateHttpProxyParams(), CreateHttpsProxyParams(),
                 quic::QUIC_VERSION_UNSUPPORTED,
                 HostPortPair("www.google.com", 443),
-                session_->http_auth_cache(),
-                session_->http_auth_handler_factory(),
-                session_->spdy_session_pool(), session_->quic_stream_factory(),
                 /*is_trusted_proxy=*/false, /*tunnel=*/true,
                 TRAFFIC_ANNOTATION_FOR_TESTS));
   }
@@ -208,6 +198,8 @@
 
   std::unique_ptr<HttpNetworkSession> session_;
 
+  std::unique_ptr<CommonConnectJobParams> common_connect_job_params_;
+
   base::HistogramTester histogram_tester_;
 
   SpdyTestUtil spdy_util_;
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc
index 1e19975..996f4dda 100644
--- a/net/http/http_proxy_connect_job.cc
+++ b/net/http/http_proxy_connect_job.cc
@@ -134,21 +134,13 @@
     const scoped_refptr<SSLSocketParams>& ssl_params,
     quic::QuicTransportVersion quic_version,
     const HostPortPair& endpoint,
-    HttpAuthCache* http_auth_cache,
-    HttpAuthHandlerFactory* http_auth_handler_factory,
-    SpdySessionPool* spdy_session_pool,
-    QuicStreamFactory* quic_stream_factory,
     bool is_trusted_proxy,
     bool tunnel,
     const NetworkTrafficAnnotationTag traffic_annotation)
     : transport_params_(transport_params),
       ssl_params_(ssl_params),
       quic_version_(quic_version),
-      spdy_session_pool_(spdy_session_pool),
-      quic_stream_factory_(quic_stream_factory),
       endpoint_(endpoint),
-      http_auth_cache_(tunnel ? http_auth_cache : nullptr),
-      http_auth_handler_factory_(tunnel ? http_auth_handler_factory : nullptr),
       is_trusted_proxy_(is_trusted_proxy),
       tunnel_(tunnel),
       traffic_annotation_(traffic_annotation) {
@@ -194,8 +186,8 @@
                     HttpAuth::AUTH_PROXY,
                     GURL((params_->ssl_params() ? "https://" : "http://") +
                          GetDestination().ToString()),
-                    params_->http_auth_cache(),
-                    params_->http_auth_handler_factory(),
+                    common_connect_job_params->http_auth_cache,
+                    common_connect_job_params->http_auth_handler_factory,
                     host_resolver())
               : nullptr),
       weak_ptr_factory_(this) {}
@@ -489,7 +481,7 @@
         params_->ssl_params()->GetDirectConnectionParams()->destination(),
         ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
         SpdySessionKey::IsProxySession::kTrue, socket_tag());
-    if (params_->spdy_session_pool()->FindAvailableSession(
+    if (common_connect_job_params()->spdy_session_pool->FindAvailableSession(
             key, /* enable_ip_based_pooling = */ true,
             /* is_websocket = */ false, net_log())) {
       using_spdy_ = true;
@@ -611,7 +603,7 @@
       ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
       SpdySessionKey::IsProxySession::kTrue, socket_tag());
   base::WeakPtr<SpdySession> spdy_session =
-      params_->spdy_session_pool()->FindAvailableSession(
+      common_connect_job_params()->spdy_session_pool->FindAvailableSession(
           key, /* enable_ip_based_pooling = */ true,
           /* is_websocket = */ false, net_log());
   // It's possible that a session to the proxy has recently been created
@@ -619,10 +611,11 @@
     nested_connect_job_.reset();
   } else {
     // Create a session direct to the proxy itself
-    spdy_session =
-        params_->spdy_session_pool()->CreateAvailableSessionFromSocket(
-            key, params_->is_trusted_proxy(), nested_connect_job_->PassSocket(),
-            nested_connect_job_->connect_timing(), net_log());
+    spdy_session = common_connect_job_params()
+                       ->spdy_session_pool->CreateAvailableSessionFromSocket(
+                           key, params_->is_trusted_proxy(),
+                           nested_connect_job_->PassSocket(),
+                           nested_connect_job_->connect_timing(), net_log());
     DCHECK(spdy_session);
     nested_connect_job_.reset();
   }
@@ -664,8 +657,8 @@
   next_state_ = STATE_QUIC_PROXY_CREATE_STREAM;
   const HostPortPair& proxy_server =
       ssl_params->GetDirectConnectionParams()->destination();
-  quic_stream_request_ =
-      std::make_unique<QuicStreamRequest>(params_->quic_stream_factory());
+  quic_stream_request_ = std::make_unique<QuicStreamRequest>(
+      common_connect_job_params()->quic_stream_factory);
   return quic_stream_request_->Request(
       proxy_server, params_->quic_version(), ssl_params->privacy_mode(),
       kH2QuicTunnelPriority, socket_tag(),
diff --git a/net/http/http_proxy_connect_job.h b/net/http/http_proxy_connect_job.h
index 2a278bf..27cf379 100644
--- a/net/http/http_proxy_connect_job.h
+++ b/net/http/http_proxy_connect_job.h
@@ -24,14 +24,11 @@
 
 namespace net {
 
-class HttpAuthCache;
 class HttpAuthController;
-class HttpAuthHandlerFactory;
 class HttpResponseInfo;
 class NetworkQualityEstimator;
 class SocketTag;
 class ProxyClientSocket;
-class SpdySessionPool;
 class SpdyStreamRequest;
 class SSLSocketParams;
 class TransportSocketParams;
@@ -50,10 +47,6 @@
       const scoped_refptr<SSLSocketParams>& ssl_params,
       quic::QuicTransportVersion quic_version,
       const HostPortPair& endpoint,
-      HttpAuthCache* http_auth_cache,
-      HttpAuthHandlerFactory* http_auth_handler_factory,
-      SpdySessionPool* spdy_session_pool,
-      QuicStreamFactory* quic_stream_factory,
       bool is_trusted_proxy,
       bool tunnel,
       const NetworkTrafficAnnotationTag traffic_annotation);
@@ -66,14 +59,6 @@
   }
   quic::QuicTransportVersion quic_version() const { return quic_version_; }
   const HostPortPair& endpoint() const { return endpoint_; }
-  HttpAuthCache* http_auth_cache() const { return http_auth_cache_; }
-  HttpAuthHandlerFactory* http_auth_handler_factory() const {
-    return http_auth_handler_factory_;
-  }
-  SpdySessionPool* spdy_session_pool() { return spdy_session_pool_; }
-  QuicStreamFactory* quic_stream_factory() const {
-    return quic_stream_factory_;
-  }
   bool is_trusted_proxy() const { return is_trusted_proxy_; }
   bool tunnel() const { return tunnel_; }
   const NetworkTrafficAnnotationTag traffic_annotation() const {
@@ -87,11 +72,7 @@
   const scoped_refptr<TransportSocketParams> transport_params_;
   const scoped_refptr<SSLSocketParams> ssl_params_;
   quic::QuicTransportVersion quic_version_;
-  SpdySessionPool* spdy_session_pool_;
-  QuicStreamFactory* quic_stream_factory_;
   const HostPortPair endpoint_;
-  HttpAuthCache* const http_auth_cache_;
-  HttpAuthHandlerFactory* const http_auth_handler_factory_;
   const bool is_trusted_proxy_;
   const bool tunnel_;
   const NetworkTrafficAnnotationTag traffic_annotation_;
diff --git a/net/http/http_proxy_connect_job_unittest.cc b/net/http/http_proxy_connect_job_unittest.cc
index 75d61ab..f9a9adc 100644
--- a/net/http/http_proxy_connect_job_unittest.cc
+++ b/net/http/http_proxy_connect_job_unittest.cc
@@ -135,8 +135,6 @@
         CreateHttpProxyParams(), CreateHttpsProxyParams(),
         quic::QUIC_VERSION_UNSUPPORTED,
         HostPortPair(kEndpointHost, tunnel ? 443 : 80),
-        session_->http_auth_cache(), session_->http_auth_handler_factory(),
-        session_->spdy_session_pool(), session_->quic_stream_factory(),
         /*is_trusted_proxy=*/false, tunnel, TRAFFIC_ANNOTATION_FOR_TESTS);
   }
 
@@ -174,23 +172,12 @@
   // have been created.
   void InitCommonConnectJobParams() {
     common_connect_job_params_ = std::make_unique<CommonConnectJobParams>(
-        &socket_factory_, session_deps_.host_resolver.get(),
-        proxy_delegate_.get(), nullptr /* http_user_agent_settings */,
-        SSLClientSocketContext(session_deps_.cert_verifier.get(),
-                               session_deps_.channel_id_service.get(),
-                               session_deps_.transport_security_state.get(),
-                               session_deps_.cert_transparency_verifier.get(),
-                               session_deps_.ct_policy_enforcer.get(),
-                               nullptr /* ssl_session_cache_arg */),
-        SSLClientSocketContext(session_deps_.cert_verifier.get(),
-                               session_deps_.channel_id_service.get(),
-                               session_deps_.transport_security_state.get(),
-                               session_deps_.cert_transparency_verifier.get(),
-                               session_deps_.ct_policy_enforcer.get(),
-                               nullptr /* ssl_session_cache_arg */),
-        nullptr /* socket_performance_watcher_factory */,
-        network_quality_estimator_.get(), nullptr /* net_log */,
-        nullptr /* websocket_endpoint_lock_manager */);
+        session_->CreateCommonConnectJobParams());
+    // TODO(mmenke): Consider reworking this so it can be done through
+    // |session_deps_|.
+    common_connect_job_params_->proxy_delegate = proxy_delegate_.get();
+    common_connect_job_params_->network_quality_estimator =
+        network_quality_estimator_.get();
   }
 
   void Initialize(base::span<const MockRead> reads,
@@ -206,7 +193,7 @@
 
     data_->set_connect_data(MockConnect(connect_and_ssl_io_mode, OK));
 
-    socket_factory_.AddSocketDataProvider(data_.get());
+    session_deps_.socket_factory->AddSocketDataProvider(data_.get());
 
     if (GetParam() != HTTP) {
       ssl_data_ =
@@ -214,7 +201,7 @@
       if (GetParam() == SPDY) {
         InitializeSpdySsl(ssl_data_.get());
       }
-      socket_factory_.AddSSLSocketDataProvider(ssl_data_.get());
+      session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data_.get());
     }
   }
 
@@ -235,7 +222,6 @@
 
   std::unique_ptr<SSLSocketDataProvider> ssl_data_;
   std::unique_ptr<SequencedSocketData> data_;
-  MockClientSocketFactory socket_factory_;
   SpdySessionDependencies session_deps_;
 
   std::unique_ptr<TestNetworkQualityEstimator> network_quality_estimator_;
@@ -294,7 +280,7 @@
 
   SequencedSocketData data;
   data.set_connect_data(MockConnect(ASYNC, OK));
-  socket_factory_.AddSocketDataProvider(&data);
+  session_deps_.socket_factory->AddSocketDataProvider(&data);
 
   // Set up SSL, if needed.
   SSLSocketDataProvider ssl_data(ASYNC, OK);
@@ -306,11 +292,11 @@
       // SSL negotiation is the last step in non-tunnel connections over HTTPS
       // proxies, so pause there, to check the final state before completion.
       ssl_data = SSLSocketDataProvider(SYNCHRONOUS, ERR_IO_PENDING);
-      socket_factory_.AddSSLSocketDataProvider(&ssl_data);
+      session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
       break;
     case SPDY:
       InitializeSpdySsl(&ssl_data);
-      socket_factory_.AddSSLSocketDataProvider(&ssl_data);
+      session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
       break;
   }
 
@@ -398,16 +384,16 @@
       break;
     case HTTPS:
       sequenced_data = &http1_data;
-      socket_factory_.AddSSLSocketDataProvider(&ssl_data);
+      session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
       break;
     case SPDY:
       sequenced_data = &spdy_data;
       InitializeSpdySsl(&ssl_data);
-      socket_factory_.AddSSLSocketDataProvider(&ssl_data);
+      session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
       break;
   }
 
-  socket_factory_.AddSocketDataProvider(sequenced_data);
+  session_deps_.socket_factory->AddSocketDataProvider(sequenced_data);
 
   TestConnectJobDelegate test_delegate;
   std::unique_ptr<ConnectJob> connect_job =
@@ -882,7 +868,7 @@
 
     SequencedSocketData data;
     data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_CLOSED));
-    socket_factory_.AddSocketDataProvider(&data);
+    session_deps_.socket_factory->AddSocketDataProvider(&data);
 
     TestConnectJobDelegate test_delegate;
     std::unique_ptr<ConnectJob> connect_job =
@@ -912,13 +898,13 @@
 
     SequencedSocketData data;
     data.set_connect_data(MockConnect(io_mode, OK));
-    socket_factory_.AddSocketDataProvider(&data);
+    session_deps_.socket_factory->AddSocketDataProvider(&data);
 
     SSLSocketDataProvider ssl_data(io_mode, ERR_CERT_AUTHORITY_INVALID);
     if (GetParam() == SPDY) {
       InitializeSpdySsl(&ssl_data);
     }
-    socket_factory_.AddSSLSocketDataProvider(&ssl_data);
+    session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
     TestConnectJobDelegate test_delegate;
     std::unique_ptr<ConnectJob> connect_job =
diff --git a/net/http/http_stream_factory_unittest.cc b/net/http/http_stream_factory_unittest.cc
index 3c6cb2e..2e345f4 100644
--- a/net/http/http_stream_factory_unittest.cc
+++ b/net/http/http_stream_factory_unittest.cc
@@ -48,6 +48,7 @@
 #include "net/quic/quic_stream_factory_peer.h"
 #include "net/quic/quic_test_packet_maker.h"
 #include "net/socket/client_socket_handle.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/mock_client_socket_pool_manager.h"
 #include "net/socket/next_proto.h"
 #include "net/socket/socket_tag.h"
@@ -396,14 +397,16 @@
                                    false /* privacy_mode */);
 }
 
-template <typename ParentPool>
-class CapturePreconnectsSocketPool : public ParentPool {
+class CapturePreconnectsTransportSocketPool : public TransportClientSocketPool {
  public:
-  CapturePreconnectsSocketPool(HostResolver* host_resolver,
-                               CertVerifier* cert_verifier,
-                               TransportSecurityState* transport_security_state,
-                               CTVerifier* cert_transparency_verifier,
-                               CTPolicyEnforcer* ct_policy_enforcer);
+  explicit CapturePreconnectsTransportSocketPool(
+      const CommonConnectJobParams* common_connect_job_params)
+      : TransportClientSocketPool(0,
+                                  0,
+                                  base::TimeDelta(),
+                                  common_connect_job_params,
+                                  nullptr /* ssl_config_service */),
+        last_num_streams_(-1) {}
 
   int last_num_streams() const { return last_num_streams_; }
   const ClientSocketPool::GroupId& last_group_id() const {
@@ -472,36 +475,6 @@
   ClientSocketPool::GroupId last_group_id_;
 };
 
-typedef CapturePreconnectsSocketPool<TransportClientSocketPool>
-    CapturePreconnectsTransportSocketPool;
-
-template <typename ParentPool>
-CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool(
-    HostResolver* host_resolver,
-    CertVerifier*,
-    TransportSecurityState*,
-    CTVerifier*,
-    CTPolicyEnforcer*)
-    : ParentPool(0,
-                 0,
-                 base::TimeDelta(),
-                 nullptr /* socket_factory */,
-                 host_resolver,
-                 nullptr /* proxy_delegate */,
-                 nullptr /* http_user_agent_settings */,
-                 nullptr /* cert_verifier */,
-                 nullptr /* channel_id_server */,
-                 nullptr /* transport_security_state */,
-                 nullptr /* cert_transparency_verifier */,
-                 nullptr /* ct_policy_enforcer */,
-                 nullptr /* ssl_client_session_cache */,
-                 nullptr /* ssl_client_session_cache_privacy_mode */,
-                 nullptr /* ssl_config_service */,
-                 nullptr /* socket_performance_watcher_factory */,
-                 nullptr /* network_quality_estimator */,
-                 nullptr /* netlog */),
-      last_num_streams_(-1) {}
-
 using HttpStreamFactoryTest = TestWithScopedTaskEnvironment;
 
 TEST_F(HttpStreamFactoryTest, PreconnectDirect) {
@@ -511,14 +484,12 @@
     std::unique_ptr<HttpNetworkSession> session(
         SpdySessionDependencies::SpdyCreateSession(&session_deps));
     HttpNetworkSessionPeer peer(session.get());
+    CommonConnectJobParams common_connect_job_params =
+        session->CreateCommonConnectJobParams();
     std::unique_ptr<CapturePreconnectsTransportSocketPool>
         owned_transport_conn_pool =
             std::make_unique<CapturePreconnectsTransportSocketPool>(
-                session_deps.host_resolver.get(),
-                session_deps.cert_verifier.get(),
-                session_deps.transport_security_state.get(),
-                session_deps.cert_transparency_verifier.get(),
-                session_deps.ct_policy_enforcer.get());
+                &common_connect_job_params);
     CapturePreconnectsTransportSocketPool* transport_conn_pool =
         owned_transport_conn_pool.get();
     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
@@ -540,12 +511,10 @@
     HttpNetworkSessionPeer peer(session.get());
     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
                              HostPortPair("http_proxy", 80));
+    CommonConnectJobParams common_connect_job_params =
+        session->CreateCommonConnectJobParams();
     CapturePreconnectsTransportSocketPool* http_proxy_pool =
-        new CapturePreconnectsTransportSocketPool(
-            session_deps.host_resolver.get(), session_deps.cert_verifier.get(),
-            session_deps.transport_security_state.get(),
-            session_deps.cert_transparency_verifier.get(),
-            session_deps.ct_policy_enforcer.get());
+        new CapturePreconnectsTransportSocketPool(&common_connect_job_params);
     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
     mock_pool_manager->SetSocketPool(proxy_server,
                                      base::WrapUnique(http_proxy_pool));
@@ -565,12 +534,10 @@
     HttpNetworkSessionPeer peer(session.get());
     ProxyServer proxy_server(ProxyServer::SCHEME_SOCKS4,
                              HostPortPair("socks_proxy", 1080));
+    CommonConnectJobParams common_connect_job_params =
+        session->CreateCommonConnectJobParams();
     CapturePreconnectsTransportSocketPool* socks_proxy_pool =
-        new CapturePreconnectsTransportSocketPool(
-            session_deps.host_resolver.get(), session_deps.cert_verifier.get(),
-            session_deps.transport_security_state.get(),
-            session_deps.cert_transparency_verifier.get(),
-            session_deps.ct_policy_enforcer.get());
+        new CapturePreconnectsTransportSocketPool(&common_connect_job_params);
     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
     mock_pool_manager->SetSocketPool(proxy_server,
                                      base::WrapUnique(socks_proxy_pool));
@@ -596,14 +563,12 @@
                        SpdySessionKey::IsProxySession::kFalse, SocketTag());
     ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key));
 
+    CommonConnectJobParams common_connect_job_params =
+        session->CreateCommonConnectJobParams();
     std::unique_ptr<CapturePreconnectsTransportSocketPool>
         owned_transport_conn_pool =
             std::make_unique<CapturePreconnectsTransportSocketPool>(
-                session_deps.host_resolver.get(),
-                session_deps.cert_verifier.get(),
-                session_deps.transport_security_state.get(),
-                session_deps.cert_transparency_verifier.get(),
-                session_deps.ct_policy_enforcer.get());
+                &common_connect_job_params);
     CapturePreconnectsTransportSocketPool* transport_conn_pool =
         owned_transport_conn_pool.get();
     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
@@ -629,14 +594,12 @@
   std::unique_ptr<HttpNetworkSession> session(
       SpdySessionDependencies::SpdyCreateSession(&session_deps));
   HttpNetworkSessionPeer peer(session.get());
+  CommonConnectJobParams common_connect_job_params =
+      session->CreateCommonConnectJobParams();
   std::unique_ptr<CapturePreconnectsTransportSocketPool>
       owned_transport_conn_pool =
           std::make_unique<CapturePreconnectsTransportSocketPool>(
-              session_deps.host_resolver.get(),
-              session_deps.cert_verifier.get(),
-              session_deps.transport_security_state.get(),
-              session_deps.cert_transparency_verifier.get(),
-              session_deps.ct_policy_enforcer.get());
+              &common_connect_job_params);
   CapturePreconnectsTransportSocketPool* transport_conn_pool =
       owned_transport_conn_pool.get();
   auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
@@ -1187,12 +1150,10 @@
     HttpNetworkSessionPeer peer(session.get());
     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
                              HostPortPair("http_proxy", 80));
+    CommonConnectJobParams common_connect_job_params =
+        session->CreateCommonConnectJobParams();
     CapturePreconnectsTransportSocketPool* http_proxy_pool =
-        new CapturePreconnectsTransportSocketPool(
-            session_deps.host_resolver.get(), session_deps.cert_verifier.get(),
-            session_deps.transport_security_state.get(),
-            session_deps.cert_transparency_verifier.get(),
-            session_deps.ct_policy_enforcer.get());
+        new CapturePreconnectsTransportSocketPool(&common_connect_job_params);
     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
     mock_pool_manager->SetSocketPool(proxy_server,
                                      base::WrapUnique(http_proxy_pool));
@@ -1239,13 +1200,11 @@
 
       for (int preconnect_request = 0; preconnect_request < 2;
            ++preconnect_request) {
+        CommonConnectJobParams common_connect_job_params =
+            session->CreateCommonConnectJobParams();
         CapturePreconnectsTransportSocketPool* http_proxy_pool =
             new CapturePreconnectsTransportSocketPool(
-                session_deps.host_resolver.get(),
-                session_deps.cert_verifier.get(),
-                session_deps.transport_security_state.get(),
-                session_deps.cert_transparency_verifier.get(),
-                session_deps.ct_policy_enforcer.get());
+                &common_connect_job_params);
 
         auto mock_pool_manager =
             std::make_unique<MockClientSocketPoolManager>();
@@ -1322,12 +1281,10 @@
   ProxyServer proxy_server(ProxyServer::SCHEME_HTTPS,
                            HostPortPair("myproxy.org", 443));
 
+  CommonConnectJobParams common_connect_job_params =
+      session->CreateCommonConnectJobParams();
   CapturePreconnectsTransportSocketPool* http_proxy_pool =
-      new CapturePreconnectsTransportSocketPool(
-          session_deps.host_resolver.get(), session_deps.cert_verifier.get(),
-          session_deps.transport_security_state.get(),
-          session_deps.cert_transparency_verifier.get(),
-          session_deps.ct_policy_enforcer.get());
+      new CapturePreconnectsTransportSocketPool(&common_connect_job_params);
 
   auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
   mock_pool_manager->SetSocketPool(proxy_server,
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index 6cb8fbdf..a1b679a0 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -537,6 +537,10 @@
       : common_connect_job_params_(
             nullptr /* client_socket_factory */,
             nullptr /* host_resolver */,
+            nullptr /* http_auth_cache */,
+            nullptr /* http_auth_handler_factory */,
+            nullptr /* spdy_session_pool */,
+            nullptr /* quic_stream_factory */,
             nullptr /* proxy_delegate */,
             nullptr /* http_user_agent_settings */,
             SSLClientSocketContext(),
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc
index e9e73f78..6445e68 100644
--- a/net/socket/client_socket_pool_manager.cc
+++ b/net/socket/client_socket_pool_manager.cc
@@ -67,31 +67,36 @@
 
 // The meat of the implementation for the InitSocketHandleForHttpRequest,
 // InitSocketHandleForRawConnect and PreconnectSocketsForHttpRequest methods.
+//
+// DO NOT ADD ANY ARGUMENTS TO THIS METHOD.
+//
+// TODO(https://crbug.com/921369) In order to resolve longstanding issues
+// related to pooling distinguishable sockets together, reduce the arguments to
+// just those that are used to populate |connection_group|, and those used to
+// locate the socket pool to use.
 scoped_refptr<TransportClientSocketPool::SocketParams>
 CreateSocketParamsAndGetGroupId(
     ClientSocketPoolManager::SocketGroupType group_type,
     const HostPortPair& endpoint,
+    // This argument should be removed.
     int request_load_flags,
-    HttpNetworkSession* session,
     const ProxyInfo& proxy_info,
+    // This argument should be removed.
     quic::QuicTransportVersion quic_version,
+    // This argument should be removed.
     const SSLConfig& ssl_config_for_origin,
+    // This argument should be removed.
     const SSLConfig& ssl_config_for_proxy,
+    // This argument should be removed.
     bool force_tunnel,
     PrivacyMode privacy_mode,
+    // TODO(https://crbug.com/912727):  This argument should be removed.
     const OnHostResolutionCallback& resolution_callback,
     ClientSocketPool::GroupId* connection_group) {
   scoped_refptr<HttpProxySocketParams> http_proxy_params;
   scoped_refptr<SOCKSSocketParams> socks_params;
 
   const bool using_ssl = group_type == ClientSocketPoolManager::SSL_GROUP;
-  HostPortPair origin_host_port = endpoint;
-
-  if (!using_ssl && session->params().testing_fixed_http_port != 0) {
-    origin_host_port.set_port(session->params().testing_fixed_http_port);
-  } else if (using_ssl && session->params().testing_fixed_https_port != 0) {
-    origin_host_port.set_port(session->params().testing_fixed_https_port);
-  }
 
   // LOAD_BYPASS_CACHE should bypass the host cache as well as the HTTP cache.
   // Other cache-related load flags should not have this effect.
@@ -99,7 +104,7 @@
 
   // Build the string used to uniquely identify connections of this type.
   // Determine the host and port to connect to.
-  DCHECK(!origin_host_port.IsEmpty());
+  DCHECK(!endpoint.IsEmpty());
   ClientSocketPool::SocketType socket_type =
       ClientSocketPool::SocketType::kHttp;
 
@@ -118,7 +123,7 @@
   }
 
   *connection_group = ClientSocketPool::GroupId(
-      origin_host_port, socket_type, privacy_mode == PRIVACY_MODE_ENABLED);
+      endpoint, socket_type, privacy_mode == PRIVACY_MODE_ENABLED);
 
   if (!proxy_info.is_direct()) {
     ProxyServer proxy_server = proxy_info.proxy_server();
@@ -144,16 +149,14 @@
       }
 
       http_proxy_params = new HttpProxySocketParams(
-          proxy_tcp_params, ssl_params, quic_version, origin_host_port,
-          session->http_auth_cache(), session->http_auth_handler_factory(),
-          session->spdy_session_pool(), session->quic_stream_factory(),
+          proxy_tcp_params, ssl_params, quic_version, endpoint,
           proxy_server.is_trusted_proxy(), force_tunnel || using_ssl,
           NetworkTrafficAnnotationTag(proxy_info.traffic_annotation()));
     } else {
       DCHECK(proxy_info.is_socks());
       socks_params = new SOCKSSocketParams(
           proxy_tcp_params, proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5,
-          origin_host_port,
+          endpoint,
           NetworkTrafficAnnotationTag(proxy_info.traffic_annotation()));
     }
   }
@@ -163,11 +166,11 @@
     scoped_refptr<TransportSocketParams> ssl_tcp_params;
     if (proxy_info.is_direct()) {
       ssl_tcp_params = base::MakeRefCounted<TransportSocketParams>(
-          origin_host_port, disable_resolver_cache, resolution_callback);
+          endpoint, disable_resolver_cache, resolution_callback);
     }
     scoped_refptr<SSLSocketParams> ssl_params =
         base::MakeRefCounted<SSLSocketParams>(
-            ssl_tcp_params, socks_params, http_proxy_params, origin_host_port,
+            ssl_tcp_params, socks_params, http_proxy_params, endpoint,
             ssl_config_for_origin, privacy_mode);
     return TransportClientSocketPool::SocketParams::CreateFromSSLSocketParams(
         std::move(ssl_params));
@@ -185,7 +188,7 @@
 
   DCHECK(proxy_info.is_direct());
   scoped_refptr<TransportSocketParams> tcp_params = new TransportSocketParams(
-      origin_host_port, disable_resolver_cache, resolution_callback);
+      endpoint, disable_resolver_cache, resolution_callback);
   return TransportClientSocketPool::SocketParams::
       CreateFromTransportSocketParams(std::move(tcp_params));
 }
@@ -210,10 +213,19 @@
     const OnHostResolutionCallback& resolution_callback,
     CompletionOnceCallback callback,
     const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback) {
+  bool using_ssl = group_type == ClientSocketPoolManager::SSL_GROUP;
+  HostPortPair origin_host_port = endpoint;
+
+  if (!using_ssl && session->params().testing_fixed_http_port != 0) {
+    origin_host_port.set_port(session->params().testing_fixed_http_port);
+  } else if (using_ssl && session->params().testing_fixed_https_port != 0) {
+    origin_host_port.set_port(session->params().testing_fixed_https_port);
+  }
+
   ClientSocketPool::GroupId connection_group;
   scoped_refptr<TransportClientSocketPool::SocketParams> socket_params =
       CreateSocketParamsAndGetGroupId(
-          group_type, endpoint, request_load_flags, session, proxy_info,
+          group_type, origin_host_port, request_load_flags, proxy_info,
           quic_version, ssl_config_for_origin, ssl_config_for_proxy,
           force_tunnel, privacy_mode, resolution_callback, &connection_group);
 
diff --git a/net/socket/client_socket_pool_manager_impl.cc b/net/socket/client_socket_pool_manager_impl.cc
index 19d97f4..85637a7 100644
--- a/net/socket/client_socket_pool_manager_impl.cc
+++ b/net/socket/client_socket_pool_manager_impl.cc
@@ -23,41 +23,19 @@
 class SocketPerformanceWatcherFactory;
 
 ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
-    NetLog* net_log,
-    ClientSocketFactory* socket_factory,
-    SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
-    NetworkQualityEstimator* network_quality_estimator,
-    HostResolver* host_resolver,
-    CertVerifier* cert_verifier,
-    ChannelIDService* channel_id_service,
-    TransportSecurityState* transport_security_state,
-    CTVerifier* cert_transparency_verifier,
-    CTPolicyEnforcer* ct_policy_enforcer,
-    SSLClientSessionCache* ssl_client_session_cache,
-    SSLClientSessionCache* ssl_client_session_cache_privacy_mode,
+    const CommonConnectJobParams& common_connect_job_params,
+    const CommonConnectJobParams& websocket_common_connect_job_params,
     SSLConfigService* ssl_config_service,
-    WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
-    ProxyDelegate* proxy_delegate,
-    const HttpUserAgentSettings* http_user_agent_settings,
     HttpNetworkSession::SocketPoolType pool_type)
-    : net_log_(net_log),
-      socket_factory_(socket_factory),
-      socket_performance_watcher_factory_(socket_performance_watcher_factory),
-      network_quality_estimator_(network_quality_estimator),
-      host_resolver_(host_resolver),
-      cert_verifier_(cert_verifier),
-      channel_id_service_(channel_id_service),
-      transport_security_state_(transport_security_state),
-      cert_transparency_verifier_(cert_transparency_verifier),
-      ct_policy_enforcer_(ct_policy_enforcer),
-      ssl_client_session_cache_(ssl_client_session_cache),
-      ssl_client_session_cache_privacy_mode_(
-          ssl_client_session_cache_privacy_mode),
+    : common_connect_job_params_(common_connect_job_params),
+      websocket_common_connect_job_params_(websocket_common_connect_job_params),
       ssl_config_service_(ssl_config_service),
-      websocket_endpoint_lock_manager_(websocket_endpoint_lock_manager),
-      proxy_delegate_(proxy_delegate),
-      http_user_agent_settings_(http_user_agent_settings),
       pool_type_(pool_type) {
+  // |websocket_endpoint_lock_manager| must only be set for websocket
+  // connections.
+  DCHECK(!common_connect_job_params_.websocket_endpoint_lock_manager);
+  DCHECK(websocket_common_connect_job_params.websocket_endpoint_lock_manager);
+
   CertDatabase::GetInstance()->AddObserver(this);
 }
 
@@ -102,23 +80,13 @@
       proxy_server.is_direct()) {
     new_pool = std::make_unique<WebSocketTransportClientSocketPool>(
         sockets_per_proxy_server, sockets_per_group,
-        unused_idle_socket_timeout(pool_type_), socket_factory_, host_resolver_,
-        proxy_delegate_, http_user_agent_settings_, cert_verifier_,
-        channel_id_service_, transport_security_state_,
-        cert_transparency_verifier_, ct_policy_enforcer_,
-        ssl_client_session_cache_, ssl_client_session_cache_privacy_mode_,
-        ssl_config_service_, network_quality_estimator_,
-        websocket_endpoint_lock_manager_, net_log_);
+        unused_idle_socket_timeout(pool_type_),
+        &websocket_common_connect_job_params_, ssl_config_service_);
   } else {
     new_pool = std::make_unique<TransportClientSocketPool>(
         sockets_per_proxy_server, sockets_per_group,
-        unused_idle_socket_timeout(pool_type_), socket_factory_, host_resolver_,
-        proxy_delegate_, http_user_agent_settings_, cert_verifier_,
-        channel_id_service_, transport_security_state_,
-        cert_transparency_verifier_, ct_policy_enforcer_,
-        ssl_client_session_cache_, ssl_client_session_cache_privacy_mode_,
-        ssl_config_service_, socket_performance_watcher_factory_,
-        network_quality_estimator_, net_log_);
+        unused_idle_socket_timeout(pool_type_), &common_connect_job_params_,
+        ssl_config_service_);
   }
 
   std::pair<TransportSocketPoolMap::iterator, bool> ret =
diff --git a/net/socket/client_socket_pool_manager_impl.h b/net/socket/client_socket_pool_manager_impl.h
index 446ce2a..ff51515 100644
--- a/net/socket/client_socket_pool_manager_impl.h
+++ b/net/socket/client_socket_pool_manager_impl.h
@@ -18,6 +18,7 @@
 #include "net/cert/cert_database.h"
 #include "net/http/http_network_session.h"
 #include "net/socket/client_socket_pool_manager.h"
+#include "net/socket/connect_job.h"
 
 namespace base {
 namespace trace_event {
@@ -27,44 +28,21 @@
 
 namespace net {
 
-class CertVerifier;
-class ChannelIDService;
-class ClientSocketFactory;
-class CTVerifier;
-class HostResolver;
-class HttpUserAgentSettings;
-class NetLog;
-class NetworkQualityEstimator;
-class ProxyDelegate;
 class ProxyServer;
-class SocketPerformanceWatcherFactory;
-class SSLClientSessionCache;
 class SSLConfigService;
 class TransportClientSocketPool;
-class TransportSecurityState;
-class WebSocketEndpointLockManager;
 
 class NET_EXPORT_PRIVATE ClientSocketPoolManagerImpl
     : public ClientSocketPoolManager,
       public CertDatabase::Observer {
  public:
+  // |websocket_common_connect_job_params| is only used for direct WebSocket
+  // connections (No proxy in use). It's never used if |pool_type| is not
+  // HttpNetworkSession::SocketPoolType::WEBSOCKET_SOCKET_POOL.
   ClientSocketPoolManagerImpl(
-      NetLog* net_log,
-      ClientSocketFactory* socket_factory,
-      SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
-      NetworkQualityEstimator* network_quality_estimator,
-      HostResolver* host_resolver,
-      CertVerifier* cert_verifier,
-      ChannelIDService* channel_id_service,
-      TransportSecurityState* transport_security_state,
-      CTVerifier* cert_transparency_verifier,
-      CTPolicyEnforcer* ct_policy_enforcer,
-      SSLClientSessionCache* ssl_client_session_cache,
-      SSLClientSessionCache* ssl_client_session_cache_privacy_mode,
+      const CommonConnectJobParams& common_connect_job_params,
+      const CommonConnectJobParams& websocket_common_connect_job_params,
       SSLConfigService* ssl_config_service,
-      WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
-      ProxyDelegate* proxy_delegate,
-      const HttpUserAgentSettings* http_user_agent_settings,
       HttpNetworkSession::SocketPoolType pool_type);
   ~ClientSocketPoolManagerImpl() override;
 
@@ -88,23 +66,12 @@
   using TransportSocketPoolMap =
       std::map<ProxyServer, std::unique_ptr<TransportClientSocketPool>>;
 
-  NetLog* const net_log_;
-  ClientSocketFactory* const socket_factory_;
-  SocketPerformanceWatcherFactory* socket_performance_watcher_factory_;
-  NetworkQualityEstimator* network_quality_estimator_;
-  HostResolver* const host_resolver_;
-  CertVerifier* const cert_verifier_;
-  ChannelIDService* const channel_id_service_;
-  TransportSecurityState* const transport_security_state_;
-  CTVerifier* const cert_transparency_verifier_;
-  CTPolicyEnforcer* const ct_policy_enforcer_;
-  SSLClientSessionCache* const ssl_client_session_cache_;
-  SSLClientSessionCache* const ssl_client_session_cache_privacy_mode_;
-  const std::string ssl_session_cache_shard_;
+  const CommonConnectJobParams common_connect_job_params_;
+  // Used only for direct WebSocket connections (i.e., no proxy in use).
+  const CommonConnectJobParams websocket_common_connect_job_params_;
+
   SSLConfigService* const ssl_config_service_;
-  WebSocketEndpointLockManager* const websocket_endpoint_lock_manager_;
-  ProxyDelegate* const proxy_delegate_;
-  const HttpUserAgentSettings* const http_user_agent_settings_;
+
   const HttpNetworkSession::SocketPoolType pool_type_;
 
   TransportSocketPoolMap socket_pools_;
diff --git a/net/socket/connect_job.cc b/net/socket/connect_job.cc
index 35afc8c..291ee7a 100644
--- a/net/socket/connect_job.cc
+++ b/net/socket/connect_job.cc
@@ -20,6 +20,10 @@
 CommonConnectJobParams::CommonConnectJobParams(
     ClientSocketFactory* client_socket_factory,
     HostResolver* host_resolver,
+    HttpAuthCache* http_auth_cache,
+    HttpAuthHandlerFactory* http_auth_handler_factory,
+    SpdySessionPool* spdy_session_pool,
+    QuicStreamFactory* quic_stream_factory,
     ProxyDelegate* proxy_delegate,
     const HttpUserAgentSettings* http_user_agent_settings,
     const SSLClientSocketContext& ssl_client_socket_context,
@@ -30,6 +34,10 @@
     WebSocketEndpointLockManager* websocket_endpoint_lock_manager)
     : client_socket_factory(client_socket_factory),
       host_resolver(host_resolver),
+      http_auth_cache(http_auth_cache),
+      http_auth_handler_factory(http_auth_handler_factory),
+      spdy_session_pool(spdy_session_pool),
+      quic_stream_factory(quic_stream_factory),
       proxy_delegate(proxy_delegate),
       http_user_agent_settings(http_user_agent_settings),
       ssl_client_socket_context(ssl_client_socket_context),
diff --git a/net/socket/connect_job.h b/net/socket/connect_job.h
index ae4159a..7d49d70 100644
--- a/net/socket/connect_job.h
+++ b/net/socket/connect_job.h
@@ -27,7 +27,9 @@
 class ClientSocketFactory;
 class ClientSocketHandle;
 class HostResolver;
+class HttpAuthCache;
 class HttpAuthController;
+class HttpAuthHandlerFactory;
 class HttpResponseInfo;
 class HttpUserAgentSettings;
 class NetLog;
@@ -36,6 +38,8 @@
 class SocketPerformanceWatcherFactory;
 class StreamSocket;
 class WebSocketEndpointLockManager;
+class QuicStreamFactory;
+class SpdySessionPool;
 
 // Immutable socket parameters intended for shared use by all ConnectJob types.
 // Excludes priority because it can be modified over the lifetime of a
@@ -46,6 +50,10 @@
   CommonConnectJobParams(
       ClientSocketFactory* client_socket_factory,
       HostResolver* host_resolver,
+      HttpAuthCache* http_auth_cache,
+      HttpAuthHandlerFactory* http_auth_handler_factory,
+      SpdySessionPool* spdy_session_pool,
+      QuicStreamFactory* quic_stream_factory,
       ProxyDelegate* proxy_delegate,
       const HttpUserAgentSettings* http_user_agent_settings,
       const SSLClientSocketContext& ssl_client_socket_context,
@@ -61,6 +69,10 @@
 
   ClientSocketFactory* client_socket_factory;
   HostResolver* host_resolver;
+  HttpAuthCache* http_auth_cache;
+  HttpAuthHandlerFactory* http_auth_handler_factory;
+  SpdySessionPool* spdy_session_pool;
+  QuicStreamFactory* quic_stream_factory;
   ProxyDelegate* proxy_delegate;
   const HttpUserAgentSettings* http_user_agent_settings;
   SSLClientSocketContext ssl_client_socket_context;
diff --git a/net/socket/connect_job_unittest.cc b/net/socket/connect_job_unittest.cc
index cfd1c58..e7d7164 100644
--- a/net/socket/connect_job_unittest.cc
+++ b/net/socket/connect_job_unittest.cc
@@ -94,6 +94,10 @@
         common_connect_job_params_(
             nullptr /* client_socket_factory */,
             nullptr /* host_resolver */,
+            nullptr /* http_auth_cache */,
+            nullptr /* http_auth_handler_factory */,
+            nullptr /* spdy_session_pool */,
+            nullptr /* quic_stream_factory */,
             nullptr /* proxy_delegate */,
             nullptr /* http_user_agent_settings */,
             SSLClientSocketContext(),
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index f80db6c..8e58abf 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -37,6 +37,7 @@
 #include "net/http/http_response_headers.h"
 #include "net/log/net_log_source.h"
 #include "net/log/net_log_source_type.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/socket.h"
 #include "net/socket/stream_socket.h"
 #include "net/socket/websocket_endpoint_lock_manager.h"
@@ -2070,27 +2071,14 @@
 MockTransportClientSocketPool::MockTransportClientSocketPool(
     int max_sockets,
     int max_sockets_per_group,
-    ClientSocketFactory* socket_factory)
+    const CommonConnectJobParams* common_connect_job_params)
     : TransportClientSocketPool(
           max_sockets,
           max_sockets_per_group,
           base::TimeDelta::FromSeconds(10) /* unused_idle_socket_timeout */,
-          socket_factory,
-          nullptr /* host_resolver */,
-          nullptr /* proxy_delegate */,
-          nullptr /* http_user_agent_settings */,
-          nullptr /* cert_verifier */,
-          nullptr /* channel_id_server */,
-          nullptr /* transport_security_state */,
-          nullptr /* cert_transparency_verifier */,
-          nullptr /* ct_policy_enforcer */,
-          nullptr /* ssl_client_session_cache */,
-          nullptr /* ssl_client_session_cache_privacy_mode */,
-          nullptr /* ssl_config_service */,
-          nullptr /* socket_performance_watcher_factory */,
-          nullptr /* network_quality_estimator */,
-          nullptr /* netlog */),
-      client_socket_factory_(socket_factory),
+          common_connect_job_params,
+          nullptr /* ssl_config_service */),
+      client_socket_factory_(common_connect_job_params->client_socket_factory),
       last_request_priority_(DEFAULT_PRIORITY),
       release_count_(0),
       cancel_count_(0) {}
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index bf66bb4c..6b023b906 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -53,6 +53,7 @@
 
 namespace net {
 
+struct CommonConnectJobParams;
 class NetLog;
 
 const NetworkChangeNotifier::NetworkHandle kDefaultNetworkForTests = 1;
@@ -1194,9 +1195,10 @@
     DISALLOW_COPY_AND_ASSIGN(MockConnectJob);
   };
 
-  MockTransportClientSocketPool(int max_sockets,
-                                int max_sockets_per_group,
-                                ClientSocketFactory* socket_factory);
+  MockTransportClientSocketPool(
+      int max_sockets,
+      int max_sockets_per_group,
+      const CommonConnectJobParams* common_connect_job_params);
 
   ~MockTransportClientSocketPool() override;
 
diff --git a/net/socket/socks_connect_job_unittest.cc b/net/socket/socks_connect_job_unittest.cc
index a0c86a7..193bff7 100644
--- a/net/socket/socks_connect_job_unittest.cc
+++ b/net/socket/socks_connect_job_unittest.cc
@@ -53,6 +53,10 @@
         common_connect_job_params_(
             &client_socket_factory_,
             &host_resolver_,
+            nullptr /* http_auth_cache */,
+            nullptr /* http_auth_handler_factory */,
+            nullptr /* spdy_session_pool */,
+            nullptr /* quic_stream_factory */,
             nullptr /* proxy_delegate */,
             nullptr /* http_user_agent_settings */,
             SSLClientSocketContext(),
diff --git a/net/socket/ssl_connect_job_unittest.cc b/net/socket/ssl_connect_job_unittest.cc
index 1a3b1d1..d6d174f3 100644
--- a/net/socket/ssl_connect_job_unittest.cc
+++ b/net/socket/ssl_connect_job_unittest.cc
@@ -108,24 +108,10 @@
                                       nullptr /* ssl_params */,
                                       quic::QUIC_VERSION_UNSUPPORTED,
                                       HostPortPair("host", 80),
-                                      session_->http_auth_cache(),
-                                      session_->http_auth_handler_factory(),
-                                      session_->spdy_session_pool(),
-                                      session_->quic_stream_factory(),
                                       /*is_trusted_proxy=*/false,
                                       /*tunnel=*/true,
                                       TRAFFIC_ANNOTATION_FOR_TESTS)),
-        common_connect_job_params_(
-            &socket_factory_,
-            &host_resolver_,
-            nullptr /* proxy_delegate */,
-            nullptr /* http_user_agent_settings */,
-            ssl_client_socket_context_,
-            ssl_client_socket_context_,
-            nullptr /* socket_performance_watcher */,
-            nullptr /* network_quality_estimator */,
-            nullptr /* net_log */,
-            nullptr /* websocket_lock_endpoint_manager */) {
+        common_connect_job_params_(session_->CreateCommonConnectJobParams()) {
     ssl_config_service_->GetSSLConfig(&ssl_config_);
 
     // Set an initial delay to ensure that the first call to TimeTicks::Now()
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
index a348138cf..3b3f5404 100644
--- a/net/socket/transport_client_socket_pool.cc
+++ b/net/socket/transport_client_socket_pool.cc
@@ -22,6 +22,7 @@
 #include "net/socket/client_socket_factory.h"
 #include "net/socket/client_socket_handle.h"
 #include "net/socket/client_socket_pool_base.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/socket_net_log_params.h"
 #include "net/socket/socks_connect_job.h"
 #include "net/socket/ssl_connect_job.h"
@@ -130,26 +131,8 @@
 
 TransportClientSocketPool::TransportConnectJobFactory::
     TransportConnectJobFactory(
-        ClientSocketFactory* client_socket_factory,
-        HostResolver* host_resolver,
-        ProxyDelegate* proxy_delegate,
-        const HttpUserAgentSettings* http_user_agent_settings,
-        const SSLClientSocketContext& ssl_client_socket_context,
-        const SSLClientSocketContext& ssl_client_socket_context_privacy_mode,
-        SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
-        NetworkQualityEstimator* network_quality_estimator,
-        NetLog* net_log)
-    : common_connect_job_params_(
-          client_socket_factory,
-          host_resolver,
-          proxy_delegate,
-          http_user_agent_settings,
-          ssl_client_socket_context,
-          ssl_client_socket_context_privacy_mode,
-          socket_performance_watcher_factory,
-          network_quality_estimator,
-          net_log,
-          nullptr /* websocket_endpoint_lock_manager */) {}
+        const CommonConnectJobParams* common_connect_job_params)
+    : common_connect_job_params_(common_connect_job_params) {}
 
 TransportClientSocketPool::TransportConnectJobFactory::
     ~TransportConnectJobFactory() = default;
@@ -159,7 +142,7 @@
     const PoolBase::Request& request,
     ConnectJob::Delegate* delegate) const {
   return request.params()->create_connect_job_callback().Run(
-      request.priority(), request.socket_tag(), &common_connect_job_params_,
+      request.priority(), request.socket_tag(), common_connect_job_params_,
       delegate);
 }
 
@@ -167,46 +150,14 @@
     int max_sockets,
     int max_sockets_per_group,
     base::TimeDelta unused_idle_socket_timeout,
-    ClientSocketFactory* client_socket_factory,
-    HostResolver* host_resolver,
-    ProxyDelegate* proxy_delegate,
-    const HttpUserAgentSettings* http_user_agent_settings,
-    CertVerifier* cert_verifier,
-    ChannelIDService* channel_id_service,
-    TransportSecurityState* transport_security_state,
-    CTVerifier* cert_transparency_verifier,
-    CTPolicyEnforcer* ct_policy_enforcer,
-    SSLClientSessionCache* ssl_client_session_cache,
-    SSLClientSessionCache* ssl_client_session_cache_privacy_mode,
-    SSLConfigService* ssl_config_service,
-    SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
-    NetworkQualityEstimator* network_quality_estimator,
-    NetLog* net_log)
+    const CommonConnectJobParams* common_connect_job_params,
+    SSLConfigService* ssl_config_service)
     : base_(max_sockets,
             max_sockets_per_group,
             unused_idle_socket_timeout,
             ClientSocketPool::used_idle_socket_timeout(),
-            new TransportConnectJobFactory(
-                client_socket_factory,
-                host_resolver,
-                proxy_delegate,
-                http_user_agent_settings,
-                SSLClientSocketContext(cert_verifier,
-                                       channel_id_service,
-                                       transport_security_state,
-                                       cert_transparency_verifier,
-                                       ct_policy_enforcer,
-                                       ssl_client_session_cache),
-                SSLClientSocketContext(cert_verifier,
-                                       channel_id_service,
-                                       transport_security_state,
-                                       cert_transparency_verifier,
-                                       ct_policy_enforcer,
-                                       ssl_client_session_cache_privacy_mode),
-                socket_performance_watcher_factory,
-                network_quality_estimator,
-                net_log)),
-      client_socket_factory_(client_socket_factory),
+            new TransportConnectJobFactory(common_connect_job_params)),
+      client_socket_factory_(common_connect_job_params->client_socket_factory),
       ssl_config_service_(ssl_config_service) {
   base_.EnableConnectBackupJobs();
   if (ssl_config_service_)
diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h
index 2c800ba4..bf20b90 100644
--- a/net/socket/transport_client_socket_pool.h
+++ b/net/socket/transport_client_socket_pool.h
@@ -14,7 +14,6 @@
 #include "net/base/net_export.h"
 #include "net/socket/client_socket_pool.h"
 #include "net/socket/client_socket_pool_base.h"
-#include "net/socket/connect_job.h"
 #include "net/socket/connection_attempts.h"
 #include "net/socket/socket_tag.h"
 #include "net/socket/ssl_client_socket.h"
@@ -22,22 +21,11 @@
 
 namespace net {
 
-class CertVerifier;
-class ChannelIDService;
+struct CommonConnectJobParams;
 class ClientSocketFactory;
-class CTVerifier;
-class CTPolicyEnforcer;
-class HostResolver;
 class HttpProxySocketParams;
-class HttpUserAgentSettings;
-class NetLog;
-class NetLogWithSource;
-class NetworkQualityEstimator;
-class ProxyDelegate;
-class SocketPerformanceWatcherFactory;
 class SOCKSSocketParams;
 class SSLSocketParams;
-class TransportSecurityState;
 class TransportSocketParams;
 
 class NET_EXPORT_PRIVATE TransportClientSocketPool
@@ -96,21 +84,8 @@
       int max_sockets,
       int max_sockets_per_group,
       base::TimeDelta unused_idle_socket_timeout,
-      ClientSocketFactory* client_socket_factory,
-      HostResolver* host_resolver,
-      ProxyDelegate* proxy_delegate,
-      const HttpUserAgentSettings* http_user_agent_settings,
-      CertVerifier* cert_verifier,
-      ChannelIDService* channel_id_service,
-      TransportSecurityState* transport_security_state,
-      CTVerifier* cert_transparency_verifier,
-      CTPolicyEnforcer* ct_policy_enforcer,
-      SSLClientSessionCache* ssl_client_session_cache,
-      SSLClientSessionCache* ssl_client_session_cache_privacy_mode,
-      SSLConfigService* ssl_config_service,
-      SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
-      NetworkQualityEstimator* network_quality_estimator,
-      NetLog* net_log);
+      const CommonConnectJobParams* common_connect_job_params,
+      SSLConfigService* ssl_config_service);
 
   ~TransportClientSocketPool() override;
 
@@ -172,15 +147,7 @@
       : public PoolBase::ConnectJobFactory {
    public:
     TransportConnectJobFactory(
-        ClientSocketFactory* client_socket_factory,
-        HostResolver* host_resolver,
-        ProxyDelegate* proxy_delegate,
-        const HttpUserAgentSettings* http_user_agent_settings,
-        const SSLClientSocketContext& ssl_client_socket_context,
-        const SSLClientSocketContext& ssl_client_socket_context_privacy_mode,
-        SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
-        NetworkQualityEstimator* network_quality_estimator,
-        NetLog* net_log);
+        const CommonConnectJobParams* common_connect_job_params);
     ~TransportConnectJobFactory() override;
 
     // ClientSocketPoolBase::ConnectJobFactory methods.
@@ -190,7 +157,7 @@
         ConnectJob::Delegate* delegate) const override;
 
    private:
-    const CommonConnectJobParams common_connect_job_params_;
+    const CommonConnectJobParams* common_connect_job_params_;
 
     DISALLOW_COPY_AND_ASSIGN(TransportConnectJobFactory);
   };
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc
index d06415e..160d20f 100644
--- a/net/socket/transport_client_socket_pool_unittest.cc
+++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -32,6 +32,7 @@
 #include "net/log/net_log_with_source.h"
 #include "net/log/test_net_log.h"
 #include "net/socket/client_socket_handle.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/socket_tag.h"
 #include "net/socket/socket_test_util.h"
 #include "net/socket/socks_connect_job.h"
@@ -121,48 +122,34 @@
 
     http_network_session_ =
         SpdySessionDependencies::SpdyCreateSession(&session_deps_);
+
+    common_connect_job_params_ = std::make_unique<CommonConnectJobParams>(
+        http_network_session_->CreateCommonConnectJobParams());
+    common_connect_job_params_->client_socket_factory = &client_socket_factory_;
     pool_ = std::make_unique<TransportClientSocketPool>(
         kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-        &client_socket_factory_, session_deps_.host_resolver.get(),
-        nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-        session_deps_.cert_verifier.get(), nullptr /* channel_id_server */,
-        session_deps_.transport_security_state.get(),
-        session_deps_.cert_transparency_verifier.get(),
-        session_deps_.ct_policy_enforcer.get(),
-        nullptr /* ssl_client_session_cache */,
-        nullptr /* ssl_client_session_cache_privacy_mode */,
-        session_deps_.ssl_config_service.get(),
-        nullptr /* socket_performance_watcher_factory */,
-        nullptr /* network_quality_estimator */, nullptr /* net_log */);
+        common_connect_job_params_.get(),
+        session_deps_.ssl_config_service.get());
 
+    tagging_common_connect_job_params_ =
+        std::make_unique<CommonConnectJobParams>(
+            http_network_session_->CreateCommonConnectJobParams());
+    tagging_common_connect_job_params_->client_socket_factory =
+        &tagging_client_socket_factory_;
     tagging_pool_ = std::make_unique<TransportClientSocketPool>(
         kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-        &tagging_client_socket_factory_, session_deps_.host_resolver.get(),
-        nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-        session_deps_.cert_verifier.get(), nullptr /* channel_id_server */,
-        session_deps_.transport_security_state.get(),
-        session_deps_.cert_transparency_verifier.get(),
-        session_deps_.ct_policy_enforcer.get(),
-        nullptr /* ssl_client_session_cache */,
-        nullptr /* ssl_client_session_cache_privacy_mode */,
-        session_deps_.ssl_config_service.get(),
-        nullptr /* socket_performance_watcher_factory */,
-        nullptr /* network_quality_estimator */, nullptr /* net_log */);
+        tagging_common_connect_job_params_.get(),
+        session_deps_.ssl_config_service.get());
 
+    common_connect_job_params_for_real_sockets_ =
+        std::make_unique<CommonConnectJobParams>(
+            http_network_session_->CreateCommonConnectJobParams());
+    common_connect_job_params_for_real_sockets_->client_socket_factory =
+        ClientSocketFactory::GetDefaultFactory();
     pool_for_real_sockets_ = std::make_unique<TransportClientSocketPool>(
         kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-        ClientSocketFactory::GetDefaultFactory(),
-        session_deps_.host_resolver.get(), nullptr /* proxy_delegate */,
-        nullptr /* http_user_agent_settings */,
-        session_deps_.cert_verifier.get(), nullptr /* channel_id_server */,
-        session_deps_.transport_security_state.get(),
-        session_deps_.cert_transparency_verifier.get(),
-        session_deps_.ct_policy_enforcer.get(),
-        nullptr /* ssl_client_session_cache */,
-        nullptr /* ssl_client_session_cache_privacy_mode */,
-        session_deps_.ssl_config_service.get(),
-        nullptr /* socket_performance_watcher_factory */,
-        nullptr /* network_quality_estimator */, nullptr /* net_log */);
+        common_connect_job_params_for_real_sockets_.get(),
+        session_deps_.ssl_config_service.get());
   }
 
   ~TransportClientSocketPoolTest() override {
@@ -226,13 +213,20 @@
   // these tests depend on.
   std::unique_ptr<HttpNetworkSession> http_network_session_;
 
+  std::unique_ptr<CommonConnectJobParams> common_connect_job_params_;
   std::unique_ptr<TransportClientSocketPool> pool_;
+
   // Just like |pool_|, except it uses a real MockTaggingClientSocketFactory
   // instead of MockTransportClientSocketFactory.
+  std::unique_ptr<CommonConnectJobParams> tagging_common_connect_job_params_;
   std::unique_ptr<TransportClientSocketPool> tagging_pool_;
+
   // Just like |pool_|, except it uses a real ClientSocketFactory instead of
   // |client_socket_factory_|.
+  std::unique_ptr<CommonConnectJobParams>
+      common_connect_job_params_for_real_sockets_;
   std::unique_ptr<TransportClientSocketPool> pool_for_real_sockets_;
+
   ClientSocketPoolTest test_base_;
 
  private:
@@ -515,17 +509,9 @@
 }
 
 TEST_F(TransportClientSocketPoolTest, RequestIgnoringLimitsIsReprioritized) {
-  TransportClientSocketPool pool(
-      kMaxSockets, 1, kUnusedIdleSocketTimeout, &client_socket_factory_,
-      session_deps_.host_resolver.get(), nullptr /* proxy_delegate */,
-      nullptr /* http_user_agent_settings */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */,
-      nullptr /* socket_performance_watcher_factory */,
-      nullptr /* network_quality_estimator */, nullptr /* net_log */);
+  TransportClientSocketPool pool(kMaxSockets, 1, kUnusedIdleSocketTimeout,
+                                 common_connect_job_params_.get(),
+                                 nullptr /* ssl_config_service */);
 
   // Creates a job which ignores limits whose priority is MAXIMUM_PRIORITY.
   TestCompletionCallback callback1;
@@ -1333,19 +1319,9 @@
   session_deps_.host_resolver->set_synchronous_mode(true);
 
   // Create a socket pool which only allows a single connection at a time.
-  TransportClientSocketPool pool(
-      1, 1, kUnusedIdleSocketTimeout, &tagging_client_socket_factory_,
-      session_deps_.host_resolver.get(), nullptr /* proxy_delegate */,
-      nullptr /* http_user_agent_settings */, session_deps_.cert_verifier.get(),
-      nullptr /* channel_id_server */,
-      session_deps_.transport_security_state.get(),
-      session_deps_.cert_transparency_verifier.get(),
-      session_deps_.ct_policy_enforcer.get(),
-      nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      session_deps_.ssl_config_service.get(),
-      nullptr /* socket_performance_watcher_factory */,
-      nullptr /* network_quality_estimator */, nullptr /* net_log */);
+  TransportClientSocketPool pool(1, 1, kUnusedIdleSocketTimeout,
+                                 tagging_common_connect_job_params_.get(),
+                                 session_deps_.ssl_config_service.get());
 
   // First connection attempt will get an error after creating the SpdyStream.
 
@@ -1392,11 +1368,8 @@
       base::MakeRefCounted<HttpProxySocketParams>(
           nullptr /* transport_params */, proxy_ssl_params,
           quic::QUIC_VERSION_UNSUPPORTED, kEndpoint,
-          http_network_session_->http_auth_cache(),
-          http_network_session_->http_auth_handler_factory(),
-          http_network_session_->spdy_session_pool(),
-          nullptr /* quic_stream_factory */, false /* is_trusted_proxy */,
-          true /* tunnel */, TRAFFIC_ANNOTATION_FOR_TESTS);
+          false /* is_trusted_proxy */, true /* tunnel */,
+          TRAFFIC_ANNOTATION_FOR_TESTS);
   scoped_refptr<SSLSocketParams> endpoint_ssl_params =
       base::MakeRefCounted<SSLSocketParams>(
           nullptr /* direct_params */, nullptr /* socks_proxy_params */,
@@ -1452,19 +1425,9 @@
   session_deps_.host_resolver->set_synchronous_mode(true);
 
   // Create a socket pool which only allows a single connection at a time.
-  TransportClientSocketPool pool(
-      1, 1, kUnusedIdleSocketTimeout, &tagging_client_socket_factory_,
-      session_deps_.host_resolver.get(), nullptr /* proxy_delegate */,
-      nullptr /* http_user_agent_settings */, session_deps_.cert_verifier.get(),
-      nullptr /* channel_id_server */,
-      session_deps_.transport_security_state.get(),
-      session_deps_.cert_transparency_verifier.get(),
-      session_deps_.ct_policy_enforcer.get(),
-      nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      session_deps_.ssl_config_service.get(),
-      nullptr /* socket_performance_watcher_factory */,
-      nullptr /* network_quality_estimator */, nullptr /* net_log */);
+  TransportClientSocketPool pool(1, 1, kUnusedIdleSocketTimeout,
+                                 tagging_common_connect_job_params_.get(),
+                                 session_deps_.ssl_config_service.get());
 
   SpdyTestUtil spdy_util;
   spdy::SpdySerializedFrame connect(spdy_util.ConstructSpdyConnect(
@@ -1524,11 +1487,8 @@
       base::MakeRefCounted<HttpProxySocketParams>(
           nullptr /* transport_params */, proxy_ssl_params,
           quic::QUIC_VERSION_UNSUPPORTED, kEndpoint,
-          http_network_session_->http_auth_cache(),
-          http_network_session_->http_auth_handler_factory(),
-          http_network_session_->spdy_session_pool(),
-          nullptr /* quic_stream_factory */, false /* is_trusted_proxy */,
-          true /* tunnel */, TRAFFIC_ANNOTATION_FOR_TESTS);
+          false /* is_trusted_proxy */, true /* tunnel */,
+          TRAFFIC_ANNOTATION_FOR_TESTS);
   scoped_refptr<SSLSocketParams> endpoint_ssl_params =
       base::MakeRefCounted<SSLSocketParams>(
           nullptr /* direct_params */, nullptr /* socks_proxy_params */,
@@ -2063,11 +2023,8 @@
                   HostPortPair("http.proxy.host", 80), false,
                   OnHostResolutionCallback()),
               nullptr /* ssl_params */, quic::QUIC_VERSION_UNSUPPORTED,
-              kDestination, http_network_session_->http_auth_cache(),
-              http_network_session_->http_auth_handler_factory(),
-              http_network_session_->spdy_session_pool(),
-              nullptr /* quic_stream_factory */, false /* is_trusted_proxy */,
-              false /* tunnel */, TRAFFIC_ANNOTATION_FOR_TESTS));
+              kDestination, false /* is_trusted_proxy */, false /* tunnel */,
+              TRAFFIC_ANNOTATION_FOR_TESTS));
 
   // Verify requested socket is tagged properly.
   ClientSocketHandle handle;
@@ -2135,11 +2092,8 @@
                   HostPortPair("http.proxy.host", 80), false,
                   OnHostResolutionCallback()),
               nullptr /* ssl_params */, quic::QUIC_VERSION_UNSUPPORTED,
-              kDestination, http_network_session_->http_auth_cache(),
-              http_network_session_->http_auth_handler_factory(),
-              http_network_session_->spdy_session_pool(),
-              nullptr /* quic_stream_factory */, false /* is_trusted_proxy */,
-              true /* tunnel */, TRAFFIC_ANNOTATION_FOR_TESTS));
+              kDestination, false /* is_trusted_proxy */, true /* tunnel */,
+              TRAFFIC_ANNOTATION_FOR_TESTS));
 
   // Verify requested socket is tagged properly.
   ClientSocketHandle handle;
diff --git a/net/socket/transport_connect_job_unittest.cc b/net/socket/transport_connect_job_unittest.cc
index decfde5..b68d3b2 100644
--- a/net/socket/transport_connect_job_unittest.cc
+++ b/net/socket/transport_connect_job_unittest.cc
@@ -36,6 +36,10 @@
         common_connect_job_params_(
             &client_socket_factory_,
             &host_resolver_,
+            nullptr /* http_auth_cache */,
+            nullptr /* http_auth_handler_factory */,
+            nullptr /* spdy_session_pool */,
+            nullptr /* quic_stream_factory */,
             nullptr /* proxy_delegate */,
             nullptr /* http_user_agent_settings */,
             SSLClientSocketContext(),
diff --git a/net/socket/websocket_transport_client_socket_pool.cc b/net/socket/websocket_transport_client_socket_pool.cc
index 288c696..abeafdd 100644
--- a/net/socket/websocket_transport_client_socket_pool.cc
+++ b/net/socket/websocket_transport_client_socket_pool.cc
@@ -21,6 +21,7 @@
 #include "net/log/net_log_source_type.h"
 #include "net/socket/client_socket_handle.h"
 #include "net/socket/client_socket_pool_base.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/websocket_endpoint_lock_manager.h"
 #include "net/socket/websocket_transport_connect_job.h"
 
@@ -30,65 +31,20 @@
     int max_sockets,
     int max_sockets_per_group,
     base::TimeDelta unused_idle_socket_timeout,
-    ClientSocketFactory* client_socket_factory,
-    HostResolver* host_resolver,
-    ProxyDelegate* proxy_delegate,
-    const HttpUserAgentSettings* http_user_agent_settings,
-    CertVerifier* cert_verifier,
-    ChannelIDService* channel_id_service,
-    TransportSecurityState* transport_security_state,
-    CTVerifier* cert_transparency_verifier,
-    CTPolicyEnforcer* ct_policy_enforcer,
-    SSLClientSessionCache* ssl_client_session_cache,
-    SSLClientSessionCache* ssl_client_session_cache_privacy_mode,
-    SSLConfigService* ssl_config_service,
-    NetworkQualityEstimator* network_quality_estimator,
-    WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
-    NetLog* net_log)
-    : TransportClientSocketPool(
-          max_sockets,
-          max_sockets_per_group,
-          unused_idle_socket_timeout,
-          client_socket_factory,
-          host_resolver,
-          proxy_delegate,
-          http_user_agent_settings,
-          cert_verifier,
-          channel_id_service,
-          transport_security_state,
-          cert_transparency_verifier,
-          ct_policy_enforcer,
-          ssl_client_session_cache,
-          ssl_client_session_cache_privacy_mode,
-          ssl_config_service,
-          nullptr /* socket_performance_watcher_factory */,
-          network_quality_estimator,
-          net_log),
-      common_connect_job_params_(
-          client_socket_factory,
-          host_resolver,
-          proxy_delegate,
-          http_user_agent_settings,
-          SSLClientSocketContext(cert_verifier,
-                                 channel_id_service,
-                                 transport_security_state,
-                                 cert_transparency_verifier,
-                                 ct_policy_enforcer,
-                                 ssl_client_session_cache),
-          SSLClientSocketContext(cert_verifier,
-                                 channel_id_service,
-                                 transport_security_state,
-                                 cert_transparency_verifier,
-                                 ct_policy_enforcer,
-                                 ssl_client_session_cache_privacy_mode),
-          nullptr /* SocketPerformanceWatcherFactory */,
-          network_quality_estimator,
-          net_log,
-          websocket_endpoint_lock_manager),
+    const CommonConnectJobParams* common_connect_job_params,
+    SSLConfigService* ssl_config_service)
+    : TransportClientSocketPool(max_sockets,
+                                max_sockets_per_group,
+                                unused_idle_socket_timeout,
+                                common_connect_job_params,
+                                ssl_config_service),
+      common_connect_job_params_(common_connect_job_params),
       max_sockets_(max_sockets),
       handed_out_socket_count_(0),
       flushing_(false),
-      weak_factory_(this) {}
+      weak_factory_(this) {
+  DCHECK(common_connect_job_params_->websocket_endpoint_lock_manager);
+}
 
 WebSocketTransportClientSocketPool::~WebSocketTransportClientSocketPool() {
   // Clean up any pending connect jobs.
@@ -160,7 +116,7 @@
   // pool types on top of a standard TransportClientSocketPool.
   std::unique_ptr<ConnectJob> connect_job =
       casted_params->create_connect_job_callback().Run(
-          priority, SocketTag(), &common_connect_job_params_,
+          priority, SocketTag(), common_connect_job_params_,
           connect_job_delegate.get());
 
   int result = connect_job_delegate->Connect(std::move(connect_job));
diff --git a/net/socket/websocket_transport_client_socket_pool.h b/net/socket/websocket_transport_client_socket_pool.h
index 8e851dc0..ac241d7 100644
--- a/net/socket/websocket_transport_client_socket_pool.h
+++ b/net/socket/websocket_transport_client_socket_pool.h
@@ -31,14 +31,8 @@
 
 namespace net {
 
-class ClientSocketFactory;
-class HostResolver;
-class HttpUserAgentSettings;
-class NetLog;
-class NetworkQualityEstimator;
-class ProxyDelegate;
+struct CommonConnectJobParams;
 class SSLConfigService;
-class WebSocketEndpointLockManager;
 class WebSocketTransportConnectJob;
 
 class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool
@@ -48,21 +42,8 @@
       int max_sockets,
       int max_sockets_per_group,
       base::TimeDelta unused_idle_socket_timeout,
-      ClientSocketFactory* client_socket_factory,
-      HostResolver* host_resolver,
-      ProxyDelegate* proxy_delegate,
-      const HttpUserAgentSettings* http_user_agent_settings,
-      CertVerifier* cert_verifier,
-      ChannelIDService* channel_id_service,
-      TransportSecurityState* transport_security_state,
-      CTVerifier* cert_transparency_verifier,
-      CTPolicyEnforcer* ct_policy_enforcer,
-      SSLClientSessionCache* ssl_client_session_cache,
-      SSLClientSessionCache* ssl_client_session_cache_privacy_mode,
-      SSLConfigService* ssl_config_service,
-      NetworkQualityEstimator* network_quality_estimator,
-      WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
-      NetLog* net_log);
+      const CommonConnectJobParams* common_connect_job_params,
+      SSLConfigService* ssl_config_service);
 
   ~WebSocketTransportClientSocketPool() override;
 
@@ -205,7 +186,7 @@
   void ActivateStalledRequest();
   bool DeleteStalledRequest(ClientSocketHandle* handle);
 
-  const CommonConnectJobParams common_connect_job_params_;
+  const CommonConnectJobParams* const common_connect_job_params_;
   std::set<const ClientSocketHandle*> pending_callbacks_;
   PendingConnectsMap pending_connects_;
   StalledRequestQueue stalled_request_queue_;
diff --git a/net/socket/websocket_transport_client_socket_pool_unittest.cc b/net/socket/websocket_transport_client_socket_pool_unittest.cc
index cd71b2d..224ef9f 100644
--- a/net/socket/websocket_transport_client_socket_pool_unittest.cc
+++ b/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -24,8 +24,10 @@
 #include "net/dns/mock_host_resolver.h"
 #include "net/log/test_net_log.h"
 #include "net/socket/client_socket_handle.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/socket_tag.h"
 #include "net/socket/socket_test_util.h"
+#include "net/socket/ssl_client_socket.h"
 #include "net/socket/stream_socket.h"
 #include "net/socket/transport_client_socket_pool_test_util.h"
 #include "net/socket/transport_connect_job.h"
@@ -72,24 +74,26 @@
                             OnHostResolutionCallback()))),
         host_resolver_(new MockHostResolver),
         client_socket_factory_(&net_log_),
+        common_connect_job_params_(
+            &client_socket_factory_,
+            host_resolver_.get(),
+            nullptr /* http_auth_cache */,
+            nullptr /* http_auth_handler_factory */,
+            nullptr /* spdy_session_pool */,
+            nullptr /* quic_stream_factory */,
+            nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
+            SSLClientSocketContext(),
+            SSLClientSocketContext(),
+            nullptr /* socket_performance_watcher_factory */,
+            nullptr /* network_quality_estimator */,
+            nullptr /* netlog */,
+            &websocket_endpoint_lock_manager_),
         pool_(kMaxSockets,
               kMaxSocketsPerGroup,
               kUnusedIdleSocketTimeout,
-              &client_socket_factory_,
-              host_resolver_.get(),
-              nullptr /* proxy_delegate */,
-              nullptr /* http_user_agent_settings */,
-              nullptr /* cert_verifier */,
-              nullptr /* channel_id_server */,
-              nullptr /* transport_security_state */,
-              nullptr /* cert_transparency_verifier */,
-              nullptr /* ct_policy_enforcer */,
-              nullptr /* ssl_client_session_cache */,
-              nullptr /* ssl_client_session_cache_privacy_mode */,
-              nullptr /* ssl_config_service */,
-              nullptr /* network_quality_estimator */,
-              &websocket_endpoint_lock_manager_,
-              nullptr /* netlog */) {
+              &common_connect_job_params_,
+              nullptr /* ssl_config_service */) {
     websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(
         base::TimeDelta());
   }
@@ -136,6 +140,7 @@
   std::unique_ptr<MockHostResolver> host_resolver_;
   MockTransportClientSocketFactory client_socket_factory_;
   WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
+  const CommonConnectJobParams common_connect_job_params_;
   WebSocketTransportClientSocketPool pool_;
   ClientSocketPoolTest test_base_;
 
@@ -564,18 +569,6 @@
 // socket which finishes first.
 TEST_F(WebSocketTransportClientSocketPoolTest,
        IPv6FallbackSocketIPv4FinishesFirst) {
-  WebSocketTransportClientSocketPool pool(
-      kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-      &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */, nullptr /* network_quality_estimator */,
-      &websocket_endpoint_lock_manager_, nullptr /* netlog */);
-
   MockTransportClientSocketFactory::ClientSocketType case_types[] = {
       // This is the IPv6 socket.
       MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
@@ -593,7 +586,7 @@
   int rv = handle.Init(
       group_id_, params_, LOW, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
-      ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource());
+      ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   EXPECT_FALSE(handle.is_initialized());
   EXPECT_FALSE(handle.socket());
@@ -612,18 +605,6 @@
 // finish first.
 TEST_F(WebSocketTransportClientSocketPoolTest,
        IPv6FallbackSocketIPv6FinishesFirst) {
-  WebSocketTransportClientSocketPool pool(
-      kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-      &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */, nullptr /* network_quality_estimator */,
-      &websocket_endpoint_lock_manager_, nullptr /* netlog */);
-
   MockTransportClientSocketFactory::ClientSocketType case_types[] = {
       // This is the IPv6 socket.
       MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
@@ -643,7 +624,7 @@
   int rv = handle.Init(
       group_id_, params_, LOW, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
-      ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource());
+      ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   EXPECT_FALSE(handle.is_initialized());
   EXPECT_FALSE(handle.socket());
@@ -659,18 +640,6 @@
 
 TEST_F(WebSocketTransportClientSocketPoolTest,
        IPv6NoIPv4AddressesToFallbackTo) {
-  WebSocketTransportClientSocketPool pool(
-      kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-      &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */, nullptr /* network_quality_estimator */,
-      &websocket_endpoint_lock_manager_, nullptr /* netlog */);
-
   client_socket_factory_.set_default_client_socket_type(
       MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
 
@@ -683,7 +652,7 @@
   int rv = handle.Init(
       group_id_, params_, LOW, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
-      ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource());
+      ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   EXPECT_FALSE(handle.is_initialized());
   EXPECT_FALSE(handle.socket());
@@ -698,18 +667,6 @@
 }
 
 TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
-  WebSocketTransportClientSocketPool pool(
-      kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-      &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */, nullptr /* network_quality_estimator */,
-      &websocket_endpoint_lock_manager_, nullptr /* netlog */);
-
   client_socket_factory_.set_default_client_socket_type(
       MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
 
@@ -721,7 +678,7 @@
   int rv = handle.Init(
       group_id_, params_, LOW, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
-      ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource());
+      ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   EXPECT_FALSE(handle.is_initialized());
   EXPECT_FALSE(handle.socket());
@@ -738,18 +695,6 @@
 // If all IPv6 addresses fail to connect synchronously, then IPv4 connections
 // proceeed immediately.
 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
-  WebSocketTransportClientSocketPool pool(
-      kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-      &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */, nullptr /* network_quality_estimator */,
-      &websocket_endpoint_lock_manager_, nullptr /* netlog */);
-
   MockTransportClientSocketFactory::ClientSocketType case_types[] = {
       // First IPv6 socket.
       MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET,
@@ -770,7 +715,7 @@
   int rv = handle.Init(
       group_id_, params_, LOW, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
-      ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource());
+      ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
   EXPECT_THAT(rv, IsOk());
   ASSERT_TRUE(handle.socket());
 
@@ -782,18 +727,6 @@
 // If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
 // connections proceed immediately.
 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
-  WebSocketTransportClientSocketPool pool(
-      kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-      &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */, nullptr /* network_quality_estimator */,
-      &websocket_endpoint_lock_manager_, nullptr /* netlog */);
-
   MockTransportClientSocketFactory::ClientSocketType case_types[] = {
       // First IPv6 socket.
       MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET,
@@ -814,7 +747,7 @@
   int rv = handle.Init(
       group_id_, params_, LOW, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
-      ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource());
+      ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   EXPECT_FALSE(handle.socket());
 
@@ -834,18 +767,6 @@
 // can only happen if the sockets are different types, since sockets of the same
 // type do not race).
 TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
-  WebSocketTransportClientSocketPool pool(
-      kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-      &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */, nullptr /* network_quality_estimator */,
-      &websocket_endpoint_lock_manager_, nullptr /* netlog */);
-
   client_socket_factory_.set_default_client_socket_type(
       MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET);
 
@@ -858,7 +779,7 @@
   int rv = handle.Init(
       group_id_, params_, LOW, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
-      ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource());
+      ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   ASSERT_FALSE(handle.socket());
 
@@ -880,18 +801,6 @@
 
 // We should not report failure until all connections have failed.
 TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
-  WebSocketTransportClientSocketPool pool(
-      kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-      &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */, nullptr /* network_quality_estimator */,
-      &websocket_endpoint_lock_manager_, nullptr /* netlog */);
-
   client_socket_factory_.set_default_client_socket_type(
       MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET);
   base::TimeDelta delay = base::TimeDelta::FromMilliseconds(
@@ -918,7 +827,7 @@
   int rv = handle.Init(
       group_id_, params_, LOW, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
-      ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource());
+      ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
 
   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
@@ -930,17 +839,6 @@
 // because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you
 // want to run it.
 TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) {
-  WebSocketTransportClientSocketPool pool(
-      kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
-      &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
-      nullptr /* cert_transparency_verifier */,
-      nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
-      nullptr /* ssl_client_session_cache_privacy_mode */,
-      nullptr /* ssl_config_service */, nullptr /* network_quality_estimator */,
-      &websocket_endpoint_lock_manager_, nullptr /* netlog */);
   const base::TimeDelta connect_job_timeout =
       TransportConnectJob::ConnectionTimeout();
 
@@ -964,7 +862,7 @@
   int rv = handle.Init(
       group_id_, params_, LOW, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
-      ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource());
+      ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
 
   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_TIMED_OUT));
diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc
index 9fb91f3..2ce9ae4 100644
--- a/net/spdy/spdy_proxy_client_socket_unittest.cc
+++ b/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -199,7 +199,7 @@
   HostPortPair endpoint_host_port_pair_;
   ProxyServer proxy_;
   SpdySessionKey endpoint_spdy_session_key_;
-  const CommonConnectJobParams common_connect_job_params_;
+  std::unique_ptr<CommonConnectJobParams> common_connect_job_params_;
 
   DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
 };
@@ -216,28 +216,7 @@
                                  proxy_,
                                  PRIVACY_MODE_DISABLED,
                                  SpdySessionKey::IsProxySession::kFalse,
-                                 SocketTag()),
-      common_connect_job_params_(
-          session_deps_.socket_factory.get(),
-          session_deps_.host_resolver.get(),
-          nullptr /* proxy_delegate */,
-          nullptr /* http_user_agent_settings */,
-          SSLClientSocketContext(session_deps_.cert_verifier.get(),
-                                 session_deps_.channel_id_service.get(),
-                                 session_deps_.transport_security_state.get(),
-                                 session_deps_.cert_transparency_verifier.get(),
-                                 session_deps_.ct_policy_enforcer.get(),
-                                 nullptr /* ssl_client_session_cache_arg */),
-          SSLClientSocketContext(session_deps_.cert_verifier.get(),
-                                 session_deps_.channel_id_service.get(),
-                                 session_deps_.transport_security_state.get(),
-                                 session_deps_.cert_transparency_verifier.get(),
-                                 session_deps_.ct_policy_enforcer.get(),
-                                 nullptr /* ssl_client_session_cache_arg */),
-          nullptr /* socket_performance_watcher_factory */,
-          nullptr /* network_quality_estimator */,
-          net_log_.bound().net_log(),
-          nullptr /* websocket_endpoint_lock_manager */) {
+                                 SocketTag()) {
   session_deps_.net_log = net_log_.bound().net_log();
 }
 
@@ -270,11 +249,13 @@
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
   session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
+  common_connect_job_params_ = std::make_unique<CommonConnectJobParams>(
+      session_->CreateCommonConnectJobParams());
 
   // Creates the SPDY session and stream.
   spdy_session_ = CreateSpdyProxySession(session_.get(), &session_deps_,
                                          endpoint_spdy_session_key_,
-                                         &common_connect_job_params_);
+                                         common_connect_job_params_.get());
 
   base::WeakPtr<SpdyStream> spdy_stream(
       CreateStreamSynchronously(
diff --git a/net/websockets/websocket_basic_stream_adapters_test.cc b/net/websockets/websocket_basic_stream_adapters_test.cc
index a8294fad..b1be831 100644
--- a/net/websockets/websocket_basic_stream_adapters_test.cc
+++ b/net/websockets/websocket_basic_stream_adapters_test.cc
@@ -23,9 +23,11 @@
 #include "net/log/net_log_with_source.h"
 #include "net/socket/client_socket_handle.h"
 #include "net/socket/client_socket_pool_manager_impl.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/socket_tag.h"
 #include "net/socket/socket_test_util.h"
 #include "net/socket/socks_connect_job.h"
+#include "net/socket/ssl_client_socket.h"
 #include "net/socket/ssl_connect_job.h"
 #include "net/socket/transport_client_socket_pool.h"
 #include "net/socket/transport_connect_job.h"
@@ -58,22 +60,37 @@
   WebSocketClientSocketHandleAdapterTest()
       : host_port_pair_("www.example.org", 443),
         socket_pool_manager_(std::make_unique<ClientSocketPoolManagerImpl>(
-            net_log_.net_log(),
-            &socket_factory_,
-            nullptr,
-            nullptr,
-            &host_resolver,
-            nullptr,
-            nullptr,
-            nullptr,
-            nullptr,
-            nullptr,
-            nullptr,
-            nullptr,
-            nullptr,
-            &websocket_endpoint_lock_manager_,
-            nullptr,
-            nullptr,
+            CommonConnectJobParams(
+                &socket_factory_,
+                &host_resolver,
+                nullptr /* http_auth_cache */,
+                nullptr /* http_auth_handler_factory */,
+                nullptr /* spdy_session_pool */,
+                nullptr /* quic_stream_factory */,
+                nullptr /* proxy_delegate */,
+                nullptr /* http_user_agent_settings */,
+                SSLClientSocketContext(),
+                SSLClientSocketContext(),
+                nullptr /* socket_performance_watcher_factory */,
+                nullptr /* network_quality_estimator */,
+                net_log_.net_log(),
+                nullptr /* websocket_endpoint_lock_manager */),
+            CommonConnectJobParams(
+                &socket_factory_,
+                &host_resolver,
+                nullptr /* http_auth_cache */,
+                nullptr /* http_auth_handler_factory */,
+                nullptr /* spdy_session_pool */,
+                nullptr /* quic_stream_factory */,
+                nullptr /* proxy_delegate */,
+                nullptr /* http_user_agent_settings */,
+                SSLClientSocketContext(),
+                SSLClientSocketContext(),
+                nullptr /* socket_performance_watcher_factory */,
+                nullptr /* network_quality_estimator */,
+                net_log_.net_log(),
+                &websocket_endpoint_lock_manager_),
+            nullptr /* ssl_config_service */,
             HttpNetworkSession::NORMAL_SOCKET_POOL)),
         transport_params_(base::MakeRefCounted<TransportSocketParams>(
             host_port_pair_,
diff --git a/net/websockets/websocket_basic_stream_test.cc b/net/websockets/websocket_basic_stream_test.cc
index 1cf54548..097325d 100644
--- a/net/websockets/websocket_basic_stream_test.cc
+++ b/net/websockets/websocket_basic_stream_test.cc
@@ -18,8 +18,10 @@
 #include "base/stl_util.h"
 #include "net/base/test_completion_callback.h"
 #include "net/log/test_net_log.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/socket_tag.h"
 #include "net/socket/socket_test_util.h"
+#include "net/socket/ssl_client_socket.h"
 #include "net/test/gtest_util.h"
 #include "net/test/test_with_scoped_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -103,7 +105,22 @@
 class WebSocketBasicStreamSocketTest : public TestWithScopedTaskEnvironment {
  protected:
   WebSocketBasicStreamSocketTest()
-      : pool_(1, 1, &factory_),
+      : common_connect_job_params_(
+            &factory_,
+            nullptr /* host_resolver */,
+            nullptr /* http_auth_cache */,
+            nullptr /* http_auth_handler_factory */,
+            nullptr /* spdy_session_pool */,
+            nullptr /* quic_stream_factory */,
+            nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
+            SSLClientSocketContext(),
+            SSLClientSocketContext(),
+            nullptr /* socket_performance_watcher_factory */,
+            nullptr /* network_quality_estimator */,
+            nullptr /* net_log */,
+            nullptr /* websocket_endpoint_lock_manager */),
+        pool_(1, 1, &common_connect_job_params_),
         generator_(&GenerateNulMaskingKey),
         expect_all_io_to_complete_(true) {}
 
@@ -149,6 +166,7 @@
 
   std::unique_ptr<SocketDataProvider> socket_data_;
   MockClientSocketFactory factory_;
+  const CommonConnectJobParams common_connect_job_params_;
   MockTransportClientSocketPool pool_;
   std::vector<std::unique_ptr<WebSocketFrame>> frames_;
   TestCompletionCallback cb_;
diff --git a/net/websockets/websocket_handshake_stream_create_helper_test.cc b/net/websockets/websocket_handshake_stream_create_helper_test.cc
index 48a0f72..5d07b22 100644
--- a/net/websockets/websocket_handshake_stream_create_helper_test.cc
+++ b/net/websockets/websocket_handshake_stream_create_helper_test.cc
@@ -22,8 +22,10 @@
 #include "net/http/http_response_info.h"
 #include "net/log/net_log_with_source.h"
 #include "net/socket/client_socket_handle.h"
+#include "net/socket/connect_job.h"
 #include "net/socket/socket_tag.h"
 #include "net/socket/socket_test_util.h"
+#include "net/socket/ssl_client_socket.h"
 #include "net/socket/websocket_endpoint_lock_manager.h"
 #include "net/spdy/spdy_session.h"
 #include "net/spdy/spdy_session_key.h"
@@ -59,7 +61,22 @@
 class MockClientSocketHandleFactory {
  public:
   MockClientSocketHandleFactory()
-      : pool_(1, 1, socket_factory_maker_.factory()) {}
+      : common_connect_job_params_(
+            socket_factory_maker_.factory(),
+            nullptr /* host_resolver */,
+            nullptr /* http_auth_cache */,
+            nullptr /* http_auth_handler_factory */,
+            nullptr /* spdy_session_pool */,
+            nullptr /* quic_stream_factory */,
+            nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
+            SSLClientSocketContext(),
+            SSLClientSocketContext(),
+            nullptr /* socket_performance_watcher_factory */,
+            nullptr /* network_quality_estimator */,
+            nullptr /* net_log */,
+            nullptr /* websocket_endpoint_lock_manager */),
+        pool_(1, 1, &common_connect_job_params_) {}
 
   // The created socket expects |expect_written| to be written to the socket,
   // and will respond with |return_to_read|. The test will fail if the expected
@@ -81,6 +98,7 @@
 
  private:
   WebSocketMockClientSocketFactoryMaker socket_factory_maker_;
+  const CommonConnectJobParams common_connect_job_params_;
   MockTransportClientSocketPool pool_;
 
   DISALLOW_COPY_AND_ASSIGN(MockClientSocketHandleFactory);
diff --git a/services/image_annotation/annotator_unittest.cc b/services/image_annotation/annotator_unittest.cc
index 8724076..a466615a 100644
--- a/services/image_annotation/annotator_unittest.cc
+++ b/services/image_annotation/annotator_unittest.cc
@@ -42,6 +42,10 @@
 using testing::SizeIs;
 using testing::UnorderedElementsAre;
 
+MATCHER_P3(AnnotatorEq, type, score, text, "") {
+  return (arg.type == type && arg.score == score && arg.text == text);
+}
+
 constexpr char kTestServerUrl[] = "https://ia-pa.googleapis.com/v1/annotation";
 
 // Example image URLs.
@@ -97,64 +101,56 @@
   ]
 })";
 
-// Successful text extraction for |kImage1Url|.
-constexpr char kSuccessResponse[] = R"(
+// Successful OCR text extraction for |kImage1Url| with no descriptions.
+constexpr char kOcrSuccessResponse[] = R"(
 {
   "results": [
     {
       "imageId": "https://www.example.com/image1.jpg",
-      "engineResults": [{
-        "status": {},
-        "ocrEngine": {
-          "ocrRegions": [
-            {
-              "words": [
-                 {
-                   "detectedText": "Region",
-                   "confidenceScore": 1.0
-                 },
-                 {
-                   "detectedText": "1",
-                   "confidenceScore": 1.0
-                 }
-              ]
-            },
-            {
-              "words": [
-                 {
-                   "detectedText": "Region",
-                   "confidenceScore": 1.0
-                 },
-                 {
-                   "detectedText": "2",
-                   "confidenceScore": 1.0
-                 }
-              ]
-            }
-          ]
+      "engineResults": [
+        {
+          "status": {},
+          "ocrEngine": {
+            "ocrRegions": [
+              {
+                "words": [
+                  {
+                    "detectedText": "Region",
+                    "confidenceScore": 1.0
+                  },
+                  {
+                    "detectedText": "1",
+                    "confidenceScore": 1.0
+                  }
+                ]
+              },
+              {
+                "words": [
+                  {
+                    "detectedText": "Region",
+                    "confidenceScore": 1.0
+                  },
+                  {
+                    "detectedText": "2",
+                    "confidenceScore": 1.0
+                  }
+                ]
+              }
+            ]
+          }
+        },
+        {
+          "status": {},
+          "descriptionEngine": {
+            "descriptionList": {}
+          }
         }
-      }]
+      ]
     }
   ]
 }
 )";
 
-// Failed text extraction for |kImage1Url|.
-constexpr char kErrorResponse[] = R"(
-{
-  "results": [{
-    "imageId": "https://www.example.com/image1.jpg",
-    "engineResults": [{
-      "status": {
-        "code": 8,
-        "message": "Resource exhaused"
-      },
-      "ocrEngine": {}
-    }]
-  }]
-}
-)";
-
 // Batch response containing successful annotations for |kImage1Url| and
 // |kImage2Url|, and a failure for |kImage3Url|.
 //
@@ -164,41 +160,66 @@
   "results": [
     {
       "imageId": "https://www.example.com/image2.jpg",
-      "engineResults": [{
-        "status": {},
-        "ocrEngine": {
-          "ocrRegions": [{
-            "words": [{
-              "detectedText": "2",
-              "confidenceScore": 1.0
+      "engineResults": [
+        {
+          "status": {},
+          "ocrEngine": {
+            "ocrRegions": [{
+              "words": [{
+                "detectedText": "2",
+                "confidenceScore": 1.0
+              }]
             }]
-          }]
+          }
+        },
+        {
+          "status": {},
+          "descriptionEngine": {
+            "descriptionList": {}
+          }
         }
-      }]
+      ]
     },
     {
       "imageId": "https://www.example.com/image1.jpg",
-      "engineResults": [{
-        "status": {},
-        "ocrEngine": {
-          "ocrRegions": [{
-            "words": [{
-              "detectedText": "1",
-              "confidenceScore": 1.0
+      "engineResults": [
+        {
+          "status": {},
+          "ocrEngine": {
+            "ocrRegions": [{
+              "words": [{
+                "detectedText": "1",
+                "confidenceScore": 1.0
+              }]
             }]
-          }]
+          }
+        },
+        {
+          "status": {},
+          "descriptionEngine": {
+            "descriptionList": {}
+          }
         }
-      }]
+      ]
     },
     {
       "imageId": "https://www.example.com/image3.jpg",
-      "engineResults": [{
-        "status": {
-          "code": 8,
-          "message": "Resource exhaused"
+      "engineResults": [
+        {
+          "status": {
+            "code": 8,
+            "message": "Resource exhausted"
+          },
+          "ocrEngine": {}
         },
-        "ocrEngine": {}
-      }]
+        {
+          "status": {
+            "code": 8,
+            "message": "Resource exhausted"
+          },
+          "descriptionEngine": {}
+        }
+      ]
     }
   ]
 })";
@@ -339,21 +360,23 @@
 // Receives the result of an annotation request and writes the result data into
 // the given variables.
 void ReportResult(base::Optional<mojom::AnnotateImageError>* const error,
-                  base::Optional<std::string>* const ocr_text,
+                  std::vector<mojom::Annotation>* const annotations,
                   mojom::AnnotateImageResultPtr result) {
   if (result->which() == mojom::AnnotateImageResult::Tag::ERROR_CODE) {
     *error = result->get_error_code();
   } else {
-    CHECK_EQ(result->get_annotations().size(), 1u);
-    CHECK_EQ(result->get_annotations()[0]->type, mojom::AnnotationType::kOcr);
-    *ocr_text = std::move(result->get_annotations()[0]->text);
+    // If annotations exists, then it is not empty.
+    ASSERT_THAT(result->get_annotations(), Not(IsEmpty()));
+    for (const auto& annotation_ptr : result->get_annotations()) {
+      annotations->push_back(*annotation_ptr);
+    }
   }
 }
 
 }  // namespace
 
 // Test that annotation works for one client, and that the cache is populated.
-TEST(AnnotatorTest, SuccessAndCache) {
+TEST(AnnotatorTest, OcrSuccessAndCache) {
   base::test::ScopedTaskEnvironment test_task_env(
       base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
   TestServerURLLoaderFactory test_url_factory(
@@ -370,10 +393,11 @@
   // First call performs original image annotation.
   {
     base::Optional<mojom::AnnotateImageError> error;
-    base::Optional<std::string> ocr_text;
+    std::vector<mojom::Annotation> annotations;
 
-    annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
-                            base::BindOnce(&ReportResult, &error, &ocr_text));
+    annotator.AnnotateImage(
+        kImage1Url, processor.GetPtr(),
+        base::BindOnce(&ReportResult, &error, &annotations));
     test_task_env.RunUntilIdle();
 
     // Annotator should have asked processor for pixels.
@@ -394,20 +418,20 @@
     const std::string request =
         ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID"));
     test_url_factory.ExpectRequestAndSimulateResponse(
-        "annotation", {} /* expected_headers */, request, kSuccessResponse,
+        "annotation", {} /* expected_headers */, request, kOcrSuccessResponse,
         net::HTTP_OK);
     test_task_env.RunUntilIdle();
 
     // HTTP response should have completed and callback should have been called.
     ASSERT_THAT(error, Eq(base::nullopt));
-    EXPECT_THAT(ocr_text, Eq("Region 1\nRegion 2"));
+    EXPECT_THAT(annotations,
+                UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr,
+                                                 1.0, "Region 1\nRegion 2")));
 
     // Metrics should have been logged for the major actions of the service.
     histogram_tester.ExpectUniqueSample(metrics_internal::kCacheHit, false, 1);
     histogram_tester.ExpectUniqueSample(metrics_internal::kPixelFetchSuccess,
                                         true, 1);
-    histogram_tester.ExpectUniqueSample(metrics_internal::kPixelFetchSuccess,
-                                        true, 1);
     histogram_tester.ExpectUniqueSample(metrics_internal::kServerRequestSize,
                                         request.size() / 1024, 1);
     histogram_tester.ExpectUniqueSample(metrics_internal::kServerNetError,
@@ -415,11 +439,16 @@
     histogram_tester.ExpectUniqueSample(
         metrics_internal::kServerHttpResponseCode, net::HTTP_OK, 1);
     histogram_tester.ExpectUniqueSample(metrics_internal::kServerResponseSize,
-                                        std::strlen(kSuccessResponse), 1);
+                                        std::strlen(kOcrSuccessResponse), 1);
+    histogram_tester.ExpectUniqueSample(metrics_internal::kJsonParseSuccess,
+                                        true, 1);
     histogram_tester.ExpectUniqueSample(
         base::StringPrintf(metrics_internal::kAnnotationStatus, "Ocr"),
         0 /* OK RPC status */, 1);
     histogram_tester.ExpectUniqueSample(
+        base::StringPrintf(metrics_internal::kAnnotationStatus, "Desc"),
+        0 /* OK RPC status */, 1);
+    histogram_tester.ExpectUniqueSample(
         base::StringPrintf(metrics_internal::kAnnotationConfidence, "Ocr"), 100,
         1);
     histogram_tester.ExpectUniqueSample(
@@ -430,10 +459,11 @@
   // Second call uses cached results.
   {
     base::Optional<mojom::AnnotateImageError> error;
-    base::Optional<std::string> ocr_text;
+    std::vector<mojom::Annotation> annotations;
 
-    annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
-                            base::BindOnce(&ReportResult, &error, &ocr_text));
+    annotator.AnnotateImage(
+        kImage1Url, processor.GetPtr(),
+        base::BindOnce(&ReportResult, &error, &annotations));
     test_task_env.RunUntilIdle();
 
     // Pixels shouldn't be requested.
@@ -441,7 +471,9 @@
 
     // Results should have been directly returned without any server call.
     ASSERT_THAT(error, Eq(base::nullopt));
-    EXPECT_THAT(ocr_text, Eq("Region 1\nRegion 2"));
+    EXPECT_THAT(annotations,
+                UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr,
+                                                 1.0, "Region 1\nRegion 2")));
 
     // Metrics should have been logged for a cache hit.
     EXPECT_THAT(histogram_tester.GetAllSamples(metrics_internal::kCacheHit),
@@ -449,6 +481,226 @@
   }
 }
 
+// Test that description annotations are successfully returned.
+TEST(AnnotatorTest, DescriptionSuccess) {
+  base::test::ScopedTaskEnvironment test_task_env(
+      base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
+  TestServerURLLoaderFactory test_url_factory(
+      "https://ia-pa.googleapis.com/v1/");
+  data_decoder::TestDataDecoderService test_dd_service;
+  base::HistogramTester histogram_tester;
+
+  Annotator annotator(
+      GURL(kTestServerUrl), std::string() /* api_key */, kThrottle,
+      1 /* batch_size */, 1.0 /* min_ocr_confidence */,
+      test_url_factory.AsSharedURLLoaderFactory(), test_dd_service.connector());
+  TestImageProcessor processor;
+
+  base::Optional<mojom::AnnotateImageError> error;
+  std::vector<mojom::Annotation> annotations;
+
+  annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
+                          base::BindOnce(&ReportResult, &error, &annotations));
+  test_task_env.RunUntilIdle();
+
+  // Annotator should have asked processor for pixels.
+  ASSERT_THAT(processor.callbacks(), SizeIs(1));
+
+  // Send back image data.
+  std::move(processor.callbacks()[0]).Run({1, 2, 3});
+  processor.callbacks().pop_back();
+  test_task_env.RunUntilIdle();
+
+  // No request should be sent yet (because service is waiting to batch up
+  // multiple requests).
+  EXPECT_THAT(test_url_factory.requests(), IsEmpty());
+  test_task_env.FastForwardBy(base::TimeDelta::FromSeconds(1));
+  test_task_env.RunUntilIdle();
+
+  // HTTP request should have been made.
+  test_url_factory.ExpectRequestAndSimulateResponse(
+      "annotation", {} /* expected_headers */,
+      ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
+      R"({
+           "results": [{
+             "imageId": "https://www.example.com/image1.jpg",
+             "engineResults": [
+               {
+                 "status": {},
+                 "ocrEngine": {}
+               },
+               {
+                 "status": {},
+                 "descriptionEngine": {
+                   "descriptionList": {
+                     "descriptions": [
+                       {
+                         "type": "CAPTION",
+                         "text": "This is an example image.",
+                         "score": 0.9
+                       },
+                       {
+                         "type": "LABEL",
+                         "text": "Example image",
+                         "score": 1.0
+                       }
+                     ]
+                   }
+                 }
+               }
+             ]
+           }]
+         })",
+      net::HTTP_OK);
+  test_task_env.RunUntilIdle();
+
+  // HTTP response should have completed and callback should have been called.
+  ASSERT_THAT(error, Eq(base::nullopt));
+  EXPECT_THAT(
+      annotations,
+      UnorderedElementsAre(
+          AnnotatorEq(mojom::AnnotationType::kOcr, 1.0, ""),
+          AnnotatorEq(mojom::AnnotationType::kCaption, 0.9,
+                      "This is an example image."),
+          AnnotatorEq(mojom::AnnotationType::kLabel, 1.0, "Example image")));
+
+  // Metrics about the description results should have been logged.
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationStatus, "Ocr"),
+      0 /* OK RPC status */, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationStatus, "Desc"),
+      0 /* OK RPC status */, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationConfidence,
+                         "DescCaption"),
+      90, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationConfidence, "DescLabel"),
+      100, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationEmpty, "DescCaption"),
+      false, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationEmpty, "DescLabel"),
+      false, 1);
+}
+
+// Test that the specialized OCR result takes precedence.
+TEST(AnnotatorTest, DoubleOcrResult) {
+  base::test::ScopedTaskEnvironment test_task_env(
+      base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
+  TestServerURLLoaderFactory test_url_factory(
+      "https://ia-pa.googleapis.com/v1/");
+  data_decoder::TestDataDecoderService test_dd_service;
+  base::HistogramTester histogram_tester;
+
+  Annotator annotator(
+      GURL(kTestServerUrl), std::string() /* api_key */, kThrottle,
+      1 /* batch_size */, 1.0 /* min_ocr_confidence */,
+      test_url_factory.AsSharedURLLoaderFactory(), test_dd_service.connector());
+  TestImageProcessor processor;
+
+  base::Optional<mojom::AnnotateImageError> error;
+  std::vector<mojom::Annotation> annotations;
+
+  annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
+                          base::BindOnce(&ReportResult, &error, &annotations));
+  test_task_env.RunUntilIdle();
+
+  // Annotator should have asked processor for pixels.
+  ASSERT_THAT(processor.callbacks(), SizeIs(1));
+
+  // Send back image data.
+  std::move(processor.callbacks()[0]).Run({1, 2, 3});
+  processor.callbacks().pop_back();
+  test_task_env.RunUntilIdle();
+
+  // No request should be sent yet (because service is waiting to batch up
+  // multiple requests).
+  EXPECT_THAT(test_url_factory.requests(), IsEmpty());
+  test_task_env.FastForwardBy(base::TimeDelta::FromSeconds(1));
+  test_task_env.RunUntilIdle();
+
+  // HTTP request should have been made.
+  test_url_factory.ExpectRequestAndSimulateResponse(
+      "annotation", {} /* expected_headers */,
+      ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
+      R"({
+           "results": [{
+             "imageId": "https://www.example.com/image1.jpg",
+             "engineResults": [
+               {
+                 "status": {},
+                 "ocrEngine": {
+                   "ocrRegions": [{
+                     "words": [{
+                       "detectedText": "Region 1",
+                       "confidenceScore": 1.0
+                     }]
+                   }]
+                 }
+               },
+               {
+                 "status": {},
+                 "descriptionEngine": {
+                   "descriptionList": {
+                     "descriptions": [
+                       {
+                         "type": "CAPTION",
+                         "text": "This is an example image.",
+                         "score": 0.9
+                       },
+                       {
+                         "type": "OCR",
+                         "text": "R3gi0n I",
+                         "score": 1.0
+                       }
+                     ]
+                   }
+                 }
+               }
+             ]
+           }]
+         })",
+      net::HTTP_OK);
+  test_task_env.RunUntilIdle();
+
+  // HTTP response should have completed and callback should have been called.
+  ASSERT_THAT(error, Eq(base::nullopt));
+  EXPECT_THAT(annotations,
+              UnorderedElementsAre(
+                  AnnotatorEq(mojom::AnnotationType::kOcr, 1.0, "Region 1"),
+                  AnnotatorEq(mojom::AnnotationType::kCaption, 0.9,
+                              "This is an example image.")));
+
+  // Metrics about the returned results should have been logged.
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationStatus, "Ocr"),
+      0 /* OK RPC status */, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationStatus, "Desc"),
+      0 /* OK RPC status */, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationConfidence, "Ocr"), 100,
+      1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationConfidence,
+                         "DescCaption"),
+      90, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationConfidence, "DescOcr"),
+      100, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationEmpty, "Ocr"), false, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationEmpty, "DescCaption"),
+      false, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationEmpty, "DescOcr"), false,
+      1);
+}
+
 // Test that HTTP failure is gracefully handled.
 TEST(AnnotatorTest, HttpError) {
   base::test::ScopedTaskEnvironment test_task_env(
@@ -465,10 +717,10 @@
 
   TestImageProcessor processor;
   base::Optional<mojom::AnnotateImageError> error;
-  base::Optional<std::string> ocr_text;
+  std::vector<mojom::Annotation> annotations;
 
   annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
-                          base::BindOnce(&ReportResult, &error, &ocr_text));
+                          base::BindOnce(&ReportResult, &error, &annotations));
   test_task_env.RunUntilIdle();
 
   // Annotator should have asked processor for pixels.
@@ -493,7 +745,7 @@
 
   // HTTP response should have completed and callback should have been called.
   EXPECT_THAT(error, Eq(mojom::AnnotateImageError::kFailure));
-  EXPECT_THAT(ocr_text, Eq(base::nullopt));
+  EXPECT_THAT(annotations, IsEmpty());
 
   // Metrics about the HTTP request failure should have been logged.
   histogram_tester.ExpectUniqueSample(metrics_internal::kServerNetError,
@@ -520,10 +772,10 @@
 
   TestImageProcessor processor;
   base::Optional<mojom::AnnotateImageError> error;
-  base::Optional<std::string> ocr_text;
+  std::vector<mojom::Annotation> annotations;
 
   annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
-                          base::BindOnce(&ReportResult, &error, &ocr_text));
+                          base::BindOnce(&ReportResult, &error, &annotations));
   test_task_env.RunUntilIdle();
 
   // Annotator should have asked processor for pixels.
@@ -543,13 +795,34 @@
   test_url_factory.ExpectRequestAndSimulateResponse(
       "annotation", {} /* expected_headers */,
       ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
-      kErrorResponse, net::HTTP_OK);
+      R"({
+           "results": [{
+             "imageId": "https://www.example.com/image1.jpg",
+             "engineResults": [
+               {
+                 "status": {
+                   "code": 8,
+                   "message": "Resource exhausted"
+                 },
+                 "ocrEngine": {}
+               },
+               {
+                 "status": {
+                   "code": 8,
+                   "messages": "Resource exhausted"
+                 },
+                 "descriptionEngine": {}
+               }
+             ]
+           }]
+         })",
+      net::HTTP_OK);
   test_task_env.RunUntilIdle();
 
   // HTTP response should have completed and callback should have been called
   // with an error status.
   EXPECT_THAT(error, Eq(mojom::AnnotateImageError::kFailure));
-  EXPECT_THAT(ocr_text, Eq(base::nullopt));
+  EXPECT_THAT(annotations, IsEmpty());
 
   // Metrics about the backend failure should have been logged.
   histogram_tester.ExpectUniqueSample(metrics_internal::kServerNetError,
@@ -559,10 +832,197 @@
   histogram_tester.ExpectUniqueSample(
       base::StringPrintf(metrics_internal::kAnnotationStatus, "Ocr"),
       8 /* Failed RPC status */, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationStatus, "Desc"),
+      8 /* Failed RPC status */, 1);
   histogram_tester.ExpectUniqueSample(metrics_internal::kClientResult,
                                       ClientResult::kFailed, 1);
 }
 
+// Test that partial results are returned if the OCR backend fails.
+TEST(AnnotatorTest, OcrBackendError) {
+  base::test::ScopedTaskEnvironment test_task_env(
+      base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
+  TestServerURLLoaderFactory test_url_factory(
+      "https://ia-pa.googleapis.com/v1/");
+  data_decoder::TestDataDecoderService test_dd_service;
+  base::HistogramTester histogram_tester;
+
+  Annotator annotator(
+      GURL(kTestServerUrl), std::string() /* api_key */, kThrottle,
+      1 /* batch_size */, 1.0 /* min_ocr_confidence */,
+      test_url_factory.AsSharedURLLoaderFactory(), test_dd_service.connector());
+
+  TestImageProcessor processor;
+  base::Optional<mojom::AnnotateImageError> error;
+  std::vector<mojom::Annotation> annotations;
+
+  annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
+                          base::BindOnce(&ReportResult, &error, &annotations));
+  test_task_env.RunUntilIdle();
+
+  // Annotator should have asked processor for pixels.
+  ASSERT_THAT(processor.callbacks(), SizeIs(1));
+
+  // Send back image data.
+  std::move(processor.callbacks()[0]).Run({1, 2, 3});
+  processor.callbacks().pop_back();
+  test_task_env.RunUntilIdle();
+
+  // No request should be sent yet (because service is waiting to batch up
+  // multiple requests).
+  EXPECT_THAT(test_url_factory.requests(), IsEmpty());
+  test_task_env.FastForwardBy(base::TimeDelta::FromSeconds(1));
+
+  // HTTP request should have been made.
+  test_url_factory.ExpectRequestAndSimulateResponse(
+      "annotation", {} /* expected_headers */,
+      ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
+      R"({
+           "results": [{
+             "imageId": "https://www.example.com/image1.jpg",
+             "engineResults": [
+               {
+                 "status": {
+                   "code": 8,
+                   "message": "Resource exhausted"
+                 },
+                 "ocrEngine": {}
+               },
+               {
+                 "status": {},
+                 "descriptionEngine": {
+                   "descriptionList": {
+                     "descriptions": [{
+                       "type": "CAPTION",
+                       "text": "This is an example image.",
+                       "score": 0.9
+                     }]
+                   }
+                 }
+               }
+             ]
+           }]
+         })",
+      net::HTTP_OK);
+  test_task_env.RunUntilIdle();
+
+  // HTTP response should have completed and callback should have been called.
+  EXPECT_THAT(error, Eq(base::nullopt));
+  EXPECT_THAT(annotations, UnorderedElementsAre(
+                               AnnotatorEq(mojom::AnnotationType::kCaption, 0.9,
+                                           "This is an example image.")));
+
+  // Metrics about the partial results should have been logged.
+  histogram_tester.ExpectUniqueSample(metrics_internal::kServerNetError,
+                                      net::Error::OK, 1);
+  histogram_tester.ExpectUniqueSample(metrics_internal::kServerHttpResponseCode,
+                                      net::HTTP_OK, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationStatus, "Ocr"),
+      8 /* Failed RPC status */, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationStatus, "Desc"),
+      0 /* OK RPC status */, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationConfidence,
+                         "DescCaption"),
+      90, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationEmpty, "DescCaption"),
+      false, 1);
+}
+
+// Test that partial results are returned if the description backend fails.
+TEST(AnnotatorTest, DescriptionBackendError) {
+  base::test::ScopedTaskEnvironment test_task_env(
+      base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
+  TestServerURLLoaderFactory test_url_factory(
+      "https://ia-pa.googleapis.com/v1/");
+  data_decoder::TestDataDecoderService test_dd_service;
+  base::HistogramTester histogram_tester;
+
+  Annotator annotator(
+      GURL(kTestServerUrl), std::string() /* api_key */, kThrottle,
+      1 /* batch_size */, 1.0 /* min_ocr_confidence */,
+      test_url_factory.AsSharedURLLoaderFactory(), test_dd_service.connector());
+
+  TestImageProcessor processor;
+  base::Optional<mojom::AnnotateImageError> error;
+  std::vector<mojom::Annotation> annotations;
+
+  annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
+                          base::BindOnce(&ReportResult, &error, &annotations));
+  test_task_env.RunUntilIdle();
+
+  // Annotator should have asked processor for pixels.
+  ASSERT_THAT(processor.callbacks(), SizeIs(1));
+
+  // Send back image data.
+  std::move(processor.callbacks()[0]).Run({1, 2, 3});
+  processor.callbacks().pop_back();
+  test_task_env.RunUntilIdle();
+
+  // No request should be sent yet (because service is waiting to batch up
+  // multiple requests).
+  EXPECT_THAT(test_url_factory.requests(), IsEmpty());
+  test_task_env.FastForwardBy(base::TimeDelta::FromSeconds(1));
+
+  // HTTP request should have been made.
+  test_url_factory.ExpectRequestAndSimulateResponse(
+      "annotation", {} /* expected_headers */,
+      ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
+      R"({
+           "results": [{
+             "imageId": "https://www.example.com/image1.jpg",
+             "engineResults": [
+               {
+                 "status": {},
+                 "ocrEngine": {
+                   "ocrRegions": [{
+                     "words": [{
+                       "detectedText": "1",
+                       "confidenceScore": 1.0
+                     }]
+                   }]
+                 }
+               },
+               {
+                 "status": {
+                   "code": 8,
+                   "message": "Resource exhausted"
+                 },
+                 "descriptionEngine": {}
+               }
+             ]
+           }]
+         })",
+      net::HTTP_OK);
+  test_task_env.RunUntilIdle();
+
+  // HTTP response should have completed and callback should have been called.
+  EXPECT_THAT(error, Eq(base::nullopt));
+  EXPECT_THAT(annotations, UnorderedElementsAre(AnnotatorEq(
+                               mojom::AnnotationType::kOcr, 1.0, "1")));
+
+  // Metrics about the partial results should have been logged.
+  histogram_tester.ExpectUniqueSample(metrics_internal::kServerNetError,
+                                      net::Error::OK, 1);
+  histogram_tester.ExpectUniqueSample(metrics_internal::kServerHttpResponseCode,
+                                      net::HTTP_OK, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationStatus, "Ocr"),
+      0 /* OK RPC status */, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationStatus, "Desc"),
+      8 /* Failed RPC status */, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationConfidence, "Ocr"), 100,
+      1);
+  histogram_tester.ExpectUniqueSample(
+      base::StringPrintf(metrics_internal::kAnnotationEmpty, "Ocr"), false, 1);
+}
+
 // Test that server failure (i.e. nonsense response) is gracefully handled.
 TEST(AnnotatorTest, ServerError) {
   base::test::ScopedTaskEnvironment test_task_env(
@@ -579,10 +1039,10 @@
 
   TestImageProcessor processor;
   base::Optional<mojom::AnnotateImageError> error;
-  base::Optional<std::string> ocr_text;
+  std::vector<mojom::Annotation> annotations;
 
   annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
-                          base::BindOnce(&ReportResult, &error, &ocr_text));
+                          base::BindOnce(&ReportResult, &error, &annotations));
   test_task_env.RunUntilIdle();
 
   // Annotator should have asked processor for pixels.
@@ -608,7 +1068,7 @@
   // HTTP response should have completed and callback should have been called
   // with an error status.
   EXPECT_THAT(error, Eq(mojom::AnnotateImageError::kFailure));
-  EXPECT_THAT(ocr_text, Eq(base::nullopt));
+  EXPECT_THAT(annotations, IsEmpty());
 
   // Metrics about the invalid response format should have been logged.
   histogram_tester.ExpectUniqueSample(metrics_internal::kServerNetError,
@@ -621,6 +1081,81 @@
                                       ClientResult::kFailed, 1);
 }
 
+// Test that adult content returns an error.
+TEST(AnnotatorTest, AdultError) {
+  base::test::ScopedTaskEnvironment test_task_env(
+      base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
+  TestServerURLLoaderFactory test_url_factory(
+      "https://ia-pa.googleapis.com/v1/");
+  data_decoder::TestDataDecoderService test_dd_service;
+  base::HistogramTester histogram_tester;
+
+  Annotator annotator(
+      GURL(kTestServerUrl), std::string() /* api_key */, kThrottle,
+      1 /* batch_size */, 1.0 /* min_ocr_confidence */,
+      test_url_factory.AsSharedURLLoaderFactory(), test_dd_service.connector());
+
+  TestImageProcessor processor;
+  base::Optional<mojom::AnnotateImageError> error;
+  std::vector<mojom::Annotation> annotations;
+
+  annotator.AnnotateImage(kImage1Url, processor.GetPtr(),
+                          base::BindOnce(&ReportResult, &error, &annotations));
+  test_task_env.RunUntilIdle();
+
+  // Annotator should have asked processor for pixels.
+  ASSERT_THAT(processor.callbacks(), SizeIs(1));
+
+  // Send back image data.
+  std::move(processor.callbacks()[0]).Run({1, 2, 3});
+  processor.callbacks().pop_back();
+  test_task_env.RunUntilIdle();
+
+  // No request should be sent yet (because service is waiting to batch up
+  // multiple requests).
+  EXPECT_THAT(test_url_factory.requests(), IsEmpty());
+  test_task_env.FastForwardBy(base::TimeDelta::FromSeconds(1));
+
+  // HTTP request should have been made.
+  test_url_factory.ExpectRequestAndSimulateResponse(
+      "annotation", {} /* expected headers */,
+      ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
+      R"({
+           "results": [{
+             "imageId": "https://www.example.com/image1.jpg",
+             "engineResults": [
+               {
+                 "status": {},
+                 "ocrEngine": {
+                   "ocrRegions": []
+                 }
+               },
+               {
+                 "status": {},
+                 "descriptionEngine": {
+                   "failureReason": "ADULT"
+                 }
+               }
+             ]
+           }]
+         })",
+      net::HTTP_OK);
+  test_task_env.RunUntilIdle();
+
+  // HTTP response should have completed and callback should have been called
+  // with an error status.
+  EXPECT_THAT(error, Eq(mojom::AnnotateImageError::kAdult));
+  EXPECT_THAT(annotations, IsEmpty());
+
+  // Metrics about the adult error should have been logged.
+  histogram_tester.ExpectUniqueSample(metrics_internal::kServerNetError,
+                                      net::Error::OK, 1);
+  histogram_tester.ExpectUniqueSample(metrics_internal::kServerHttpResponseCode,
+                                      net::HTTP_OK, 1);
+  histogram_tester.ExpectUniqueSample(metrics_internal::kDescFailure,
+                                      DescFailureReason::kAdult, 1);
+}
+
 // Test that work is reassigned if a processor fails.
 TEST(AnnotatorTest, ProcessorFails) {
   base::test::ScopedTaskEnvironment test_task_env(
@@ -637,12 +1172,12 @@
 
   TestImageProcessor processor[3];
   base::Optional<mojom::AnnotateImageError> error[3];
-  base::Optional<std::string> ocr_text[3];
+  std::vector<mojom::Annotation> annotations[3];
 
   for (int i = 0; i < 3; ++i) {
     annotator.AnnotateImage(
         kImage1Url, processor[i].GetPtr(),
-        base::BindOnce(&ReportResult, &error[i], &ocr_text[i]));
+        base::BindOnce(&ReportResult, &error[i], &annotations[i]));
   }
   test_task_env.RunUntilIdle();
 
@@ -675,15 +1210,20 @@
   test_url_factory.ExpectRequestAndSimulateResponse(
       "annotation", {} /* expected_headers */,
       ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
-      kSuccessResponse, net::HTTP_OK);
+      kOcrSuccessResponse, net::HTTP_OK);
   test_task_env.RunUntilIdle();
 
   // Annotator should have called all callbacks, but request 1 received an error
   // when we returned empty bytes.
   ASSERT_THAT(error, ElementsAre(mojom::AnnotateImageError::kFailure,
                                  base::nullopt, base::nullopt));
-  EXPECT_THAT(ocr_text, ElementsAre(base::nullopt, "Region 1\nRegion 2",
-                                    "Region 1\nRegion 2"));
+  EXPECT_THAT(annotations[0], IsEmpty());
+  EXPECT_THAT(annotations[1],
+              UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr, 1.0,
+                                               "Region 1\nRegion 2")));
+  EXPECT_THAT(annotations[2],
+              UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr, 1.0,
+                                               "Region 1\nRegion 2")));
 
   // Metrics about the pixel fetch failure should have been logged.
   EXPECT_THAT(
@@ -711,12 +1251,12 @@
 
   TestImageProcessor processor[3];
   base::Optional<mojom::AnnotateImageError> error[3];
-  base::Optional<std::string> ocr_text[3];
+  std::vector<mojom::Annotation> annotations[3];
 
   for (int i = 0; i < 3; ++i) {
     annotator.AnnotateImage(
         kImage1Url, processor[i].GetPtr(),
-        base::BindOnce(&ReportResult, &error[i], &ocr_text[i]));
+        base::BindOnce(&ReportResult, &error[i], &annotations[i]));
   }
   test_task_env.RunUntilIdle();
 
@@ -748,15 +1288,20 @@
   test_url_factory.ExpectRequestAndSimulateResponse(
       "annotation", {} /* expected_headers */,
       ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
-      kSuccessResponse, net::HTTP_OK);
+      kOcrSuccessResponse, net::HTTP_OK);
   test_task_env.RunUntilIdle();
 
   // Annotator should have called all callbacks, but request 1 was canceled when
   // we reset processor 1.
   ASSERT_THAT(error, ElementsAre(mojom::AnnotateImageError::kCanceled,
                                  base::nullopt, base::nullopt));
-  EXPECT_THAT(ocr_text, ElementsAre(base::nullopt, "Region 1\nRegion 2",
-                                    "Region 1\nRegion 2"));
+  EXPECT_THAT(annotations[0], IsEmpty());
+  EXPECT_THAT(annotations[1],
+              UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr, 1.0,
+                                               "Region 1\nRegion 2")));
+  EXPECT_THAT(annotations[2],
+              UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr, 1.0,
+                                               "Region 1\nRegion 2")));
 
   // Metrics about the client cancelation should have been logged.
   EXPECT_THAT(histogram_tester.GetAllSamples(metrics_internal::kClientResult),
@@ -781,18 +1326,18 @@
 
   TestImageProcessor processor[3];
   base::Optional<mojom::AnnotateImageError> error[3];
-  base::Optional<std::string> ocr_text[3];
+  std::vector<mojom::Annotation> annotations[3];
 
   // Request OCR for images 1, 2 and 3.
   annotator.AnnotateImage(
       kImage1Url, processor[0].GetPtr(),
-      base::BindOnce(&ReportResult, &error[0], &ocr_text[0]));
+      base::BindOnce(&ReportResult, &error[0], &annotations[0]));
   annotator.AnnotateImage(
       kImage2Url, processor[1].GetPtr(),
-      base::BindOnce(&ReportResult, &error[1], &ocr_text[1]));
+      base::BindOnce(&ReportResult, &error[1], &annotations[1]));
   annotator.AnnotateImage(
       kImage3Url, processor[2].GetPtr(),
-      base::BindOnce(&ReportResult, &error[2], &ocr_text[2]));
+      base::BindOnce(&ReportResult, &error[2], &annotations[2]));
   test_task_env.RunUntilIdle();
 
   // Annotator should have asked processor 1 for image 1's pixels, processor
@@ -825,7 +1370,11 @@
   // failure.
   ASSERT_THAT(error, ElementsAre(base::nullopt, base::nullopt,
                                  mojom::AnnotateImageError::kFailure));
-  EXPECT_THAT(ocr_text, ElementsAre("1", "2", base::nullopt));
+  EXPECT_THAT(annotations[0], UnorderedElementsAre(AnnotatorEq(
+                                  mojom::AnnotationType::kOcr, 1.0, "1")));
+  EXPECT_THAT(annotations[1], UnorderedElementsAre(AnnotatorEq(
+                                  mojom::AnnotationType::kOcr, 1.0, "2")));
+  EXPECT_THAT(annotations[2], IsEmpty());
 
   // Metrics should have been logged for a single server response with multiple
   // results included.
@@ -864,12 +1413,12 @@
 
   TestImageProcessor processor[2];
   base::Optional<mojom::AnnotateImageError> error[2];
-  base::Optional<std::string> ocr_text[2];
+  std::vector<mojom::Annotation> annotations[2];
 
   // Request OCR for image 1.
   annotator.AnnotateImage(
       kImage1Url, processor[0].GetPtr(),
-      base::BindOnce(&ReportResult, &error[0], &ocr_text[0]));
+      base::BindOnce(&ReportResult, &error[0], &annotations[0]));
   test_task_env.RunUntilIdle();
 
   // Annotator should have asked processor 1 for image 1's pixels.
@@ -889,7 +1438,7 @@
   // Request OCR for image 2.
   annotator.AnnotateImage(
       kImage2Url, processor[1].GetPtr(),
-      base::BindOnce(&ReportResult, &error[1], &ocr_text[1]));
+      base::BindOnce(&ReportResult, &error[1], &annotations[1]));
   test_task_env.RunUntilIdle();
 
   // Annotator should have asked processor 2 for image 2's pixels.
@@ -910,17 +1459,25 @@
       R"({
            "results": [{
              "imageId": "https://www.example.com/image1.jpg",
-             "engineResults": [{
-               "status": {},
-               "ocrEngine": {
-                 "ocrRegions": [{
-                   "words": [{
-                     "detectedText": "1",
-                     "confidenceScore": 1.0
+             "engineResults": [
+               {
+                 "status": {},
+                 "ocrEngine": {
+                   "ocrRegions": [{
+                     "words": [{
+                       "detectedText": "1",
+                       "confidenceScore": 1.0
+                     }]
                    }]
-                 }]
+                 }
+               },
+               {
+                 "status": {},
+                 "descriptionEngine": {
+                   "descriptionList": {}
+                 }
                }
-             }]
+             ]
            }]
          })",
       net::HTTP_OK);
@@ -935,17 +1492,25 @@
       R"({
            "results": [{
              "imageId": "https://www.example.com/image2.jpg",
-             "engineResults": [{
-               "status": {},
-               "ocrEngine": {
-                 "ocrRegions": [{
-                   "words": [{
-                     "detectedText": "2",
-                     "confidenceScore": 1.0
+             "engineResults": [
+               {
+                 "status": {},
+                 "ocrEngine": {
+                   "ocrRegions": [{
+                     "words": [{
+                       "detectedText": "2",
+                       "confidenceScore": 1.0
+                     }]
                    }]
-                 }]
+                 }
+               },
+               {
+                 "status": {},
+                 "descriptionEngine": {
+                   "descriptionList": {}
+                 }
                }
-             }]
+             ]
            }]
          })",
       net::HTTP_OK);
@@ -954,7 +1519,10 @@
 
   // Annotator should have called each callback with its corresponding text.
   ASSERT_THAT(error, ElementsAre(base::nullopt, base::nullopt));
-  EXPECT_THAT(ocr_text, ElementsAre("1", "2"));
+  EXPECT_THAT(annotations[0], UnorderedElementsAre(AnnotatorEq(
+                                  mojom::AnnotationType::kOcr, 1.0, "1")));
+  EXPECT_THAT(annotations[1], UnorderedElementsAre(AnnotatorEq(
+                                  mojom::AnnotationType::kOcr, 1.0, "2")));
 
   // Metrics should have been logged for two server responses.
   histogram_tester.ExpectUniqueSample(metrics_internal::kServerNetError,
@@ -989,12 +1557,12 @@
 
   TestImageProcessor processor[4];
   base::Optional<mojom::AnnotateImageError> error[4];
-  base::Optional<std::string> ocr_text[4];
+  std::vector<mojom::Annotation> annotations[4];
 
   // First request annotation of the image with processor 1.
   annotator.AnnotateImage(
       kImage1Url, processor[0].GetPtr(),
-      base::BindOnce(&ReportResult, &error[0], &ocr_text[0]));
+      base::BindOnce(&ReportResult, &error[0], &annotations[0]));
   test_task_env.RunUntilIdle();
 
   // Annotator should have asked processor 1 for the image's pixels.
@@ -1006,7 +1574,7 @@
   // Now request annotation of the image with processor 2.
   annotator.AnnotateImage(
       kImage1Url, processor[1].GetPtr(),
-      base::BindOnce(&ReportResult, &error[1], &ocr_text[1]));
+      base::BindOnce(&ReportResult, &error[1], &annotations[1]));
   test_task_env.RunUntilIdle();
 
   // Annotator *should not* have asked processor 2 for the image's pixels (since
@@ -1024,7 +1592,7 @@
   // Now request annotation of the image with processor 3.
   annotator.AnnotateImage(
       kImage1Url, processor[2].GetPtr(),
-      base::BindOnce(&ReportResult, &error[2], &ocr_text[2]));
+      base::BindOnce(&ReportResult, &error[2], &annotations[2]));
   test_task_env.RunUntilIdle();
 
   // Annotator *should not* have asked processor 3 for the image's pixels (since
@@ -1041,7 +1609,7 @@
   EXPECT_THAT(test_url_factory.requests(), SizeIs(1));
   annotator.AnnotateImage(
       kImage1Url, processor[3].GetPtr(),
-      base::BindOnce(&ReportResult, &error[3], &ocr_text[3]));
+      base::BindOnce(&ReportResult, &error[3], &annotations[3]));
   test_task_env.RunUntilIdle();
 
   // Annotator *should not* have asked processor 4 for the image's pixels (since
@@ -1056,15 +1624,24 @@
   test_url_factory.ExpectRequestAndSimulateResponse(
       "annotation", {} /* expected_headers */,
       ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
-      kSuccessResponse, net::HTTP_OK);
+      kOcrSuccessResponse, net::HTTP_OK);
   test_task_env.RunUntilIdle();
 
   // Annotator should have called all callbacks with annotation results.
   ASSERT_THAT(error, ElementsAre(base::nullopt, base::nullopt, base::nullopt,
                                  base::nullopt));
-  EXPECT_THAT(ocr_text,
-              ElementsAre("Region 1\nRegion 2", "Region 1\nRegion 2",
-                          "Region 1\nRegion 2", "Region 1\nRegion 2"));
+  EXPECT_THAT(annotations[0],
+              UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr, 1.0,
+                                               "Region 1\nRegion 2")));
+  EXPECT_THAT(annotations[1],
+              UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr, 1.0,
+                                               "Region 1\nRegion 2")));
+  EXPECT_THAT(annotations[2],
+              UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr, 1.0,
+                                               "Region 1\nRegion 2")));
+  EXPECT_THAT(annotations[3],
+              UnorderedElementsAre(AnnotatorEq(mojom::AnnotationType::kOcr, 1.0,
+                                               "Region 1\nRegion 2")));
 
   // Metrics should have been logged for a single pixel fetch.
   histogram_tester.ExpectUniqueSample(metrics_internal::kPixelFetchSuccess,
@@ -1106,7 +1683,7 @@
     test_url_factory.ExpectRequestAndSimulateResponse(
         "annotation", {{Annotator::kGoogApiKeyHeader, "my_api_key"}},
         ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
-        kSuccessResponse, net::HTTP_OK);
+        kOcrSuccessResponse, net::HTTP_OK);
   }
 
   // A call to a Google-owned server URL should not include the API key if the
@@ -1139,7 +1716,7 @@
     test_url_factory.ExpectRequestAndSimulateResponse(
         "annotation", {{Annotator::kGoogApiKeyHeader, base::nullopt}},
         ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
-        kSuccessResponse, net::HTTP_OK);
+        kOcrSuccessResponse, net::HTTP_OK);
   }
 
   // A call to a non-Google-owned URL should not include the API key.
@@ -1169,10 +1746,8 @@
     test_url_factory.ExpectRequestAndSimulateResponse(
         "annotation", {{Annotator::kGoogApiKeyHeader, base::nullopt}},
         ReformatJson(base::StringPrintf(kTemplateRequest, kImage1Url, "AQID")),
-        kSuccessResponse, net::HTTP_OK);
+        kOcrSuccessResponse, net::HTTP_OK);
   }
 }
 
-// TODO(crbug.com/916420): add unit tests for description annotations.
-
 }  // namespace image_annotation
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 9ce4c619..26f69284 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4478,25 +4478,6 @@
             ]
         }
     ],
-    "ScheduledScriptStreaming": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "ScheduledScriptStreaming",
-                    "enable_features": [
-                        "ScheduledScriptStreaming"
-                    ]
-                }
-            ]
-        }
-    ],
     "SearchEnginePromo": [
         {
             "platforms": [
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index d038e60..ce0a530 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -656,7 +656,6 @@
     "platform/modules/bluetooth/web_bluetooth.mojom",
     "platform/modules/idle/idle_manager.mojom",
     "platform/modules/notifications/notification_service.mojom",
-    "platform/modules/webdatabase/web_database.mojom",
     "web/commit_result.mojom",
     "web/devtools_frontend.mojom",
     "web/selection_menu_behavior.mojom",
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn
index 991bcfe..95e17553 100644
--- a/third_party/blink/public/mojom/BUILD.gn
+++ b/third_party/blink/public/mojom/BUILD.gn
@@ -105,6 +105,7 @@
     "v8_cache_options.mojom",
     "wake_lock/wake_lock.mojom",
     "webaudio/audio_context_manager.mojom",
+    "webdatabase/web_database.mojom",
     "worker/shared_worker.mojom",
     "worker/shared_worker_client.mojom",
     "worker/shared_worker_connector.mojom",
diff --git a/third_party/blink/public/mojom/service_worker/controller_service_worker.mojom b/third_party/blink/public/mojom/service_worker/controller_service_worker.mojom
index 97f7d70..80951cf 100644
--- a/third_party/blink/public/mojom/service_worker/controller_service_worker.mojom
+++ b/third_party/blink/public/mojom/service_worker/controller_service_worker.mojom
@@ -11,6 +11,7 @@
 import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom";
 import "third_party/blink/public/mojom/service_worker/service_worker_fetch_response_callback.mojom";
 import "third_party/blink/public/mojom/service_worker/service_worker_object.mojom";
+import "third_party/blink/public/mojom/web_feature/web_feature.mojom";
 
 // S13nServiceWorker:
 // Represents a service worker that is a 'controller'.
@@ -76,6 +77,9 @@
   // Represents ServiceWorkerContainer#controller.
   // Null if there is no controller.
   blink.mojom.ServiceWorkerObjectInfo? object_info;
+
+  // The set of features the controller has used, for UseCounter purposes.
+  array<WebFeature> used_features;
 };
 
 // A renderer-side interface for talking across threads. The main thread
diff --git a/third_party/blink/public/mojom/service_worker/service_worker_container.mojom b/third_party/blink/public/mojom/service_worker/service_worker_container.mojom
index 93b112f..2f176e2 100644
--- a/third_party/blink/public/mojom/service_worker/service_worker_container.mojom
+++ b/third_party/blink/public/mojom/service_worker/service_worker_container.mojom
@@ -133,12 +133,9 @@
   // Corresponds to setting ServiceWorkerContainer#controller.
   // If |controller_info| is invalid (its |object_info| is null), then
   // ServiceWorkerContainer#controller is cleared.
-  // If |controller_info| is valid, |used_features| is the set of
-  // features the controller has used, for UseCounter purposes.
   // If |should_notify_controllerchange| is true, dispatch a 'controllerchange'
   // event.
   SetController(ControllerServiceWorkerInfo controller_info,
-                array<WebFeature> used_features,
                 bool should_notify_controllerchange);
 
   // Corresponds to Client#postMessage().
diff --git a/third_party/blink/public/platform/modules/webdatabase/OWNERS b/third_party/blink/public/mojom/webdatabase/OWNERS
similarity index 100%
rename from third_party/blink/public/platform/modules/webdatabase/OWNERS
rename to third_party/blink/public/mojom/webdatabase/OWNERS
diff --git a/third_party/blink/public/platform/modules/webdatabase/web_database.mojom b/third_party/blink/public/mojom/webdatabase/web_database.mojom
similarity index 100%
rename from third_party/blink/public/platform/modules/webdatabase/web_database.mojom
rename to third_party/blink/public/mojom/webdatabase/web_database.mojom
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h
index b4f96ac..269bd4e9 100644
--- a/third_party/blink/public/platform/web_runtime_features.h
+++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -224,7 +224,6 @@
   BLINK_PLATFORM_EXPORT static void EnableMediaEngagementBypassAutoplayPolicies(
       bool);
   BLINK_PLATFORM_EXPORT static void EnableAutomationControlled(bool);
-  BLINK_PLATFORM_EXPORT static void EnableScheduledScriptStreaming(bool);
   BLINK_PLATFORM_EXPORT static void EnableScriptStreamingOnPreload(bool);
   BLINK_PLATFORM_EXPORT static void EnableExperimentalProductivityFeatures(
       bool);
@@ -237,6 +236,8 @@
   BLINK_PLATFORM_EXPORT static void EnableShadowDOMV0(bool);
   BLINK_PLATFORM_EXPORT static void EnableCustomElementsV0(bool);
   BLINK_PLATFORM_EXPORT static void EnableHTMLImports(bool);
+  BLINK_PLATFORM_EXPORT static void EnableSignedExchangeSubresourcePrefetch(
+      bool);
 
  private:
   WebRuntimeFeatures();
diff --git a/third_party/blink/public/platform/web_thread_type.h b/third_party/blink/public/platform/web_thread_type.h
index 7f0cf64..38ace6b 100644
--- a/third_party/blink/public/platform/web_thread_type.h
+++ b/third_party/blink/public/platform/web_thread_type.h
@@ -21,7 +21,7 @@
   kFileThread = 8,
   kDatabaseThread = 9,
   kWebAudioThread = 10,
-  kScriptStreamerThread = 11,
+  // 11 was kScriptStreamerThread, which was deleted
   kOfflineAudioRenderThread = 12,
   kReverbConvolutionBackgroundThread = 13,
   kHRTFDatabaseLoaderThread = 14,
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h
index 5b96e0e..cfca63b 100644
--- a/third_party/blink/public/web/web_local_frame.h
+++ b/third_party/blink/public/web/web_local_frame.h
@@ -101,7 +101,8 @@
   // frame pointer, the parent frame's children list will not contain the
   // provisional frame. Thus, a provisional frame is invisible to the rest of
   // Blink unless the navigation commits and the provisional frame is fully
-  // attached to the frame tree by calling Swap().
+  // attached to the frame tree by calling Swap(). It swaps with the
+  // |previous_web_frame|.
   //
   // Otherwise, if the load should not commit, call Detach() to discard the
   // frame.
@@ -109,7 +110,7 @@
       WebLocalFrameClient*,
       blink::InterfaceRegistry*,
       mojo::ScopedMessagePipeHandle,
-      WebRemoteFrame*,
+      WebFrame* previous_web_frame,
       WebSandboxFlags,
       ParsedFeaturePolicy);
 
diff --git a/third_party/blink/renderer/bindings/bindings.gni b/third_party/blink/renderer/bindings/bindings.gni
index 89dc4ff..0da42a9 100644
--- a/third_party/blink/renderer/bindings/bindings.gni
+++ b/third_party/blink/renderer/bindings/bindings.gni
@@ -99,8 +99,6 @@
                     "core/v8/script_source_location_type.h",
                     "core/v8/script_streamer.cc",
                     "core/v8/script_streamer.h",
-                    "core/v8/script_streamer_thread.cc",
-                    "core/v8/script_streamer_thread.h",
                     "core/v8/script_value.cc",
                     "core/v8/script_value.h",
                     "core/v8/serialization/post_message_helper.cc",
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
index 0b5f2d5..fa21f0f4 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -8,7 +8,6 @@
 
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
@@ -352,21 +351,6 @@
   streamer->StreamingCompleteOnBackgroundThread();
 }
 
-void RunBlockingScriptStreamingTask(
-    std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
-    ScriptStreamer* streamer,
-    std::atomic_flag* blocking_task_started_or_cancelled) {
-  if (blocking_task_started_or_cancelled->test_and_set())
-    return;
-  RunScriptStreamingTask(std::move(task), streamer);
-}
-
-void RunNonBlockingScriptStreamingTask(
-    std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
-    ScriptStreamer* streamer) {
-  RunScriptStreamingTask(std::move(task), streamer);
-}
-
 }  // namespace
 
 bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) {
@@ -415,16 +399,6 @@
       }
     }
 
-    if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled() &&
-        ScriptStreamerThread::Shared()->IsRunningTask()) {
-      // If scheduled script streaming is disabled, we only have one thread for
-      // running the tasks. A new task shouldn't be queued before the running
-      // task completes, because the running task can block and wait for data
-      // from the network.
-      SuppressStreaming(kThreadBusy);
-      return;
-    }
-
     DCHECK(!stream_);
     DCHECK(!source_);
     stream_ = new SourceStream;
@@ -451,31 +425,16 @@
         inspector_parse_script_event::Data(this->ScriptResourceIdentifier(),
                                            this->ScriptURLString()));
 
-    if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
-      // Script streaming tasks are high priority, as they can block the parser,
-      // and they can (and probably will) block during their own execution as
-      // they wait for more input.
-      //
-      // Pass through the atomic cancellation token which is set to true by the
-      // task when it is started, or set to true by the streamer if it wants to
-      // cancel the task.
-      //
-      // TODO(leszeks): Decrease the priority of these tasks where possible.
-      worker_pool::PostTaskWithTraits(
-          FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
-          CrossThreadBind(RunBlockingScriptStreamingTask,
-                          WTF::Passed(std::move(script_streaming_task)),
-                          WrapCrossThreadPersistent(this),
-                          WTF::CrossThreadUnretained(
-                              &blocking_task_started_or_cancelled_)));
-    } else {
-      blocking_task_started_or_cancelled_.test_and_set();
-      ScriptStreamerThread::Shared()->PostTask(
-          CrossThreadBind(&ScriptStreamerThread::RunScriptStreamingTask,
-                          WTF::Passed(std::move(script_streaming_task)),
-                          WrapCrossThreadPersistent(this)));
-    }
-
+    // Script streaming tasks are high priority, as they can block the parser,
+    // and they can (and probably will) block during their own execution as
+    // they wait for more input.
+    //
+    // TODO(leszeks): Decrease the priority of these tasks where possible.
+    worker_pool::PostTaskWithTraits(
+        FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
+        CrossThreadBind(RunScriptStreamingTask,
+                        WTF::Passed(std::move(script_streaming_task)),
+                        WrapCrossThreadPersistent(this)));
   }
   if (stream_)
     stream_->DidReceiveData(script_resource_, this);
@@ -492,34 +451,7 @@
   }
 
   if (stream_) {
-    // Mark the stream as finished loading before potentially re-posting the
-    // task to avoid a race between this finish and the task's first read.
     stream_->DidFinishLoading();
-
-    // If the corresponding blocking task hasn't started yet, cancel it and post
-    // a non-blocking task, since we know now that all the data is received and
-    // we will no longer block.
-    //
-    // TODO(874080): Remove this once blocking and non-blocking pools are
-    // merged.
-    if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled() &&
-        !RuntimeEnabledFeatures::MergeBlockingNonBlockingPoolsEnabled() &&
-        !blocking_task_started_or_cancelled_.test_and_set()) {
-      std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask>
-          script_streaming_task(
-              base::WrapUnique(v8::ScriptCompiler::StartStreamingScript(
-                  V8PerIsolateData::MainThreadIsolate(), source_.get(),
-                  compile_options_)));
-
-      // The task creation shouldn't fail, since it didn't fail before during
-      // NotifyAppendData.
-      CHECK(script_streaming_task);
-      worker_pool::PostTaskWithTraits(
-          FROM_HERE, {base::TaskPriority::USER_BLOCKING},
-          CrossThreadBind(RunNonBlockingScriptStreamingTask,
-                          WTF::Passed(std::move(script_streaming_task)),
-                          WrapCrossThreadPersistent(this)));
-    }
   }
   loading_finished_ = true;
 
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.h b/third_party/blink/renderer/bindings/core/v8/script_streamer.h
index 1290225a..07b81d4 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.h
@@ -5,7 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_H_
 #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_H_
 
-#include <atomic>
 #include <memory>
 
 #include "base/macros.h"
@@ -41,8 +40,7 @@
     kRevalidate,
     kContextNotValid,  // DEPRECATED
     kEncodingNotSupported,
-    // TODO(leszeks): Deprecate once scheduled streaming is on by default
-    kThreadBusy,
+    kThreadBusy,  // DEPRECATED
     kV8CannotStream,
     kScriptTooSmall,
     kNoResourceBuffer,
@@ -155,11 +153,6 @@
   // Whether we have received enough data to start the streaming.
   bool have_enough_data_for_streaming_;
 
-  // Flag used to allow atomic cancelling and reposting of the streaming task
-  // when the load completes without the task yet starting.
-  // TODO(874080): Remove this once blocking and non-blocking pools are merged.
-  std::atomic_flag blocking_task_started_or_cancelled_ = ATOMIC_FLAG_INIT;
-
   // Whether the script source code should be retrieved from the Resource
   // instead of the ScriptStreamer.
   bool streaming_suppressed_;
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
index 8fd2036..3a6f3ba 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
@@ -13,7 +13,6 @@
 #include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
 #include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
@@ -29,6 +28,7 @@
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader.h"
 #include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
 #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
 #include "v8/include/v8.h"
@@ -40,7 +40,7 @@
 class ScriptStreamingTest : public testing::Test {
  public:
   ScriptStreamingTest()
-      : loading_task_runner_(scheduler::GetSingleThreadTaskRunnerForTesting()),
+      : loading_task_runner_(platform_->test_task_runner()),
         dummy_page_holder_(DummyPageHolder::Create(IntSize(800, 600))) {
     dummy_page_holder_->GetPage().GetSettings().SetScriptEnabled(true);
     MockScriptElementBase* element = MockScriptElementBase::Create();
@@ -122,16 +122,10 @@
     GetResource()->SetStatus(ResourceStatus::kCached);
   }
 
-  void ProcessTasksUntilStreamingComplete() {
-    if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
-      while (ScriptStreamerThread::Shared()->IsRunningTask()) {
-        test::RunPendingTasks();
-      }
-    }
-    // Once more, because the "streaming complete" notification might only
-    // now be in the task queue.
-    test::RunPendingTasks();
-  }
+  void ProcessTasksUntilStreamingComplete() { platform_->RunUntilIdle(); }
+
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform_;
 
   scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
   // The PendingScript where we stream from. These don't really
@@ -156,7 +150,11 @@
   bool finished_;
 };
 
-TEST_F(ScriptStreamingTest, CompilingStreamedScript) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_CompilingStreamedScript) {
+  return;
+
   // Test that we can successfully compile a streamed script.
   V8TestingScope scope;
   GetResource()->StartStreaming(loading_task_runner_);
@@ -193,7 +191,9 @@
   EXPECT_FALSE(try_catch.HasCaught());
 }
 
-TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_CompilingStreamedScriptWithParseError) {
   // Test that scripts with parse errors are handled properly. In those cases,
   // the V8 side typically finished before loading finishes: make sure we
   // handle it gracefully.
@@ -234,7 +234,9 @@
   EXPECT_TRUE(try_catch.HasCaught());
 }
 
-TEST_F(ScriptStreamingTest, CancellingStreaming) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_CancellingStreaming) {
   // Test that the upper layers (PendingScript and up) can be ramped down
   // while streaming is ongoing, and ScriptStreamer handles it gracefully.
   V8TestingScope scope;
@@ -260,7 +262,9 @@
   EXPECT_FALSE(client->Finished());
 }
 
-TEST_F(ScriptStreamingTest, DataAfterDisposingPendingScript) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_DataAfterDisposingPendingScript) {
   // Test that the upper layers (PendingScript and up) can be ramped down
   // before streaming is started, and ScriptStreamer handles it gracefully.
   V8TestingScope scope;
@@ -295,7 +299,9 @@
   EXPECT_FALSE(client->Finished());
 }
 
-TEST_F(ScriptStreamingTest, SuppressingStreaming) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_SuppressingStreaming) {
   // If we notice during streaming that there is a code cache, streaming
   // is suppressed (V8 doesn't parse while the script is loading), and the
   // upper layer (ScriptResourceClient) should get a notification when the
@@ -326,7 +332,9 @@
   EXPECT_FALSE(source_code.Streamer());
 }
 
-TEST_F(ScriptStreamingTest, EmptyScripts) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_EmptyScripts) {
   // Empty scripts should also be streamed properly, that is, the upper layer
   // (ScriptResourceClient) should be notified when an empty script has been
   // loaded.
@@ -346,7 +354,9 @@
   EXPECT_FALSE(source_code.Streamer());
 }
 
-TEST_F(ScriptStreamingTest, SmallScripts) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_SmallScripts) {
   // Small scripts shouldn't be streamed.
   V8TestingScope scope;
   ScriptStreamer::SetSmallScriptThresholdForTesting(100);
@@ -368,7 +378,9 @@
   EXPECT_FALSE(source_code.Streamer());
 }
 
-TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_ScriptsWithSmallFirstChunk) {
   // If a script is long enough, if should be streamed, even if the first data
   // chunk is small.
   V8TestingScope scope;
@@ -406,7 +418,9 @@
   EXPECT_FALSE(try_catch.HasCaught());
 }
 
-TEST_F(ScriptStreamingTest, EncodingChanges) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_EncodingChanges) {
   // It's possible that the encoding of the Resource changes after we start
   // loading it.
   V8TestingScope scope;
@@ -444,7 +458,9 @@
   EXPECT_FALSE(try_catch.HasCaught());
 }
 
-TEST_F(ScriptStreamingTest, EncodingFromBOM) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_EncodingFromBOM) {
   // Byte order marks should be removed before giving the data to V8. They
   // will also affect encoding detection.
   V8TestingScope scope;
@@ -483,8 +499,10 @@
   EXPECT_FALSE(try_catch.HasCaught());
 }
 
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
 // A test for crbug.com/711703. Should not crash.
-TEST_F(ScriptStreamingTest, GarbageCollectDuringStreaming) {
+TEST_F(ScriptStreamingTest, DISABLED_GarbageCollectDuringStreaming) {
   V8TestingScope scope;
   GetResource()->StartStreaming(loading_task_runner_);
 
@@ -499,7 +517,9 @@
       BlinkGC::kEagerSweeping, BlinkGC::GCReason::kForcedGC);
 }
 
-TEST_F(ScriptStreamingTest, ResourceSetRevalidatingRequest) {
+// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
+// currently unable to block and wait for the script streaming thread.
+TEST_F(ScriptStreamingTest, DISABLED_ResourceSetRevalidatingRequest) {
   V8TestingScope scope;
   GetResource()->StartStreaming(loading_task_runner_);
 
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
deleted file mode 100644
index e1b3c34..0000000
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h"
-
-#include <memory>
-#include "base/location.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"
-#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-
-namespace blink {
-
-static ScriptStreamerThread* g_shared_thread = nullptr;
-// Guards s_sharedThread. s_sharedThread is initialized and deleted in the main
-// thread, but also used by the streamer thread. Races can occur during
-// shutdown.
-static Mutex* g_mutex = nullptr;
-
-void ScriptStreamerThread::Init() {
-  // Only enabled when ScheduledScriptStreaming is disabled.
-  if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
-    DCHECK(!g_shared_thread);
-    DCHECK(IsMainThread());
-    // This is called in the main thread before any tasks are created, so no
-    // locking is needed.
-    g_mutex = new Mutex();
-    g_shared_thread = new ScriptStreamerThread();
-  }
-}
-
-ScriptStreamerThread* ScriptStreamerThread::Shared() {
-  DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled());
-  return g_shared_thread;
-}
-
-void ScriptStreamerThread::PostTask(CrossThreadClosure task) {
-  DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled());
-  DCHECK(IsMainThread());
-  MutexLocker locker(mutex_);
-  DCHECK(!running_task_);
-  running_task_ = true;
-  PostCrossThreadTask(*PlatformThread().GetTaskRunner(), FROM_HERE,
-                      std::move(task));
-}
-
-void ScriptStreamerThread::TaskDone() {
-  MutexLocker locker(mutex_);
-  DCHECK(running_task_);
-  running_task_ = false;
-}
-
-Thread& ScriptStreamerThread::PlatformThread() {
-  if (!IsRunning()) {
-    thread_ = Platform::Current()->CreateThread(
-        ThreadCreationParams(WebThreadType::kScriptStreamerThread));
-  }
-  return *thread_;
-}
-
-void ScriptStreamerThread::RunScriptStreamingTask(
-    std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
-    ScriptStreamer* streamer) {
-  DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled());
-  TRACE_EVENT1(
-      "v8,devtools.timeline", "v8.parseOnBackground", "data",
-      inspector_parse_script_event::Data(streamer->ScriptResourceIdentifier(),
-                                         streamer->ScriptURLString()));
-  TRACE_EVENT_WITH_FLOW1(
-      TRACE_DISABLED_BY_DEFAULT("v8.compile"), "v8.streamingCompile.run",
-      streamer, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "data",
-      inspector_parse_script_event::Data(streamer->ScriptResourceIdentifier(),
-                                         streamer->ScriptURLString()));
-  // Running the task can and will block: SourceStream::GetSomeData will get
-  // called and it will block and wait for data from the network.
-  task->Run();
-  streamer->StreamingCompleteOnBackgroundThread();
-  MutexLocker locker(*g_mutex);
-  ScriptStreamerThread* thread = Shared();
-  if (thread)
-    thread->TaskDone();
-  // If thread is 0, we're shutting down.
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h
deleted file mode 100644
index 664df34e..0000000
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_THREAD_H_
-#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_THREAD_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-#include "v8/include/v8.h"
-
-namespace blink {
-
-class ScriptStreamer;
-
-// A singleton thread for running background tasks for script streaming.
-class CORE_EXPORT ScriptStreamerThread {
-  USING_FAST_MALLOC(ScriptStreamerThread);
-
- public:
-  static void Init();
-  static ScriptStreamerThread* Shared();
-
-  void PostTask(CrossThreadClosure);
-
-  bool IsRunningTask() const {
-    MutexLocker locker(mutex_);
-    return running_task_;
-  }
-
-  void TaskDone();
-
-  static void RunScriptStreamingTask(
-      std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask>,
-      ScriptStreamer*);
-
- private:
-  ScriptStreamerThread() : running_task_(false) {}
-
-  bool IsRunning() const { return !!thread_; }
-
-  Thread& PlatformThread();
-
-  // At the moment, we only use one thread, so we can only stream one script
-  // at a time. FIXME: Use a thread pool and stream multiple scripts.
-  std::unique_ptr<Thread> thread_;
-  bool running_task_ GUARDED_BY(mutex_);
-  mutable Mutex mutex_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScriptStreamerThread);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_THREAD_H_
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc b/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
index 519b6ee7..f4cfc08 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
@@ -55,8 +55,8 @@
   if (!cached_metadata)
     return false;
   double time_stamp;
-  const int size = sizeof(time_stamp);
-  DCHECK_EQ(cached_metadata->size(), static_cast<unsigned long>(size));
+  const uint32_t size = sizeof(time_stamp);
+  DCHECK_EQ(cached_metadata->size(), size);
   memcpy(&time_stamp, cached_metadata->Data(), size);
   return (WTF::CurrentTime() - time_stamp) < hot_seconds;
 }
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute.py b/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute.py
index d22b6e8..b532622 100644
--- a/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute.py
+++ b/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute.py
@@ -5,20 +5,73 @@
 # This file defines some classes to implement extended attributes
 # https://heycam.github.io/webidl/#idl-extended-attributes
 
-import exceptions
+from itertools import groupby
 
 
 class ExtendedAttribute(object):
-    """ExtendedAttribute represents an exnteded attribute, except for attributes
-    that have their own classes.
-    i.e. [Constructor], [CustomConstructor], [NamedConstructor], and [Exposed].
-    ExtendedAttribute assumes following formats as spec defines.
+    """ExtendedAttribute represents an exnteded attribute that
+    is described in either of following formats as spec defines.
     a. [Key]
     b. [Key=Value]
     c. [Key=(Value1,Value2,...)]
-    d. [Key(Type1 Value1, Type2 Value2,...)]
-    e. [Key=Name(Type1 Value1, Type2 Value2,...)]
+    d. [Key(ValueL1 ValueR1, ValueL2 ValueR2,...)]
+    e. [Key=Name(ValueL1 ValueR1, ValueL2 ValueR2,...)]
     """
+    _FORM_NO_ARGS = 'NoArgs'  # for (a)
+    _FORM_IDENT = 'Ident'  # for (b)
+    _FORM_IDENT_LIST = 'IdentList'  # for (c)
+    _FORM_ARG_LIST = 'ArgList'  # for (d)
+    _FORM_NAMED_ARG_LIST = 'NamedArgList'  # for (e)
+
+    def __init__(self, key, values=None, arguments=None, name=None):
+        # |values| can be either of None, a single string, or a list.
+        assert values is None or isinstance(values, (str, tuple, list))
+        # |arguments| can be either of None or a list of pairs of strings.
+        assert arguments is None or isinstance(arguments, (tuple, list))
+
+        self._format = None
+        self._key = key
+        self._values = values
+        self._arguments = arguments
+        self._name = name
+
+        if name is not None:
+            self._format = self._FORM_NAMED_ARG_LIST
+            if values is not None or arguments is None:
+                raise ValueError('Unknown format for ExtendedAttribute')
+        elif arguments is not None:
+            assert all(
+                isinstance(arg, (tuple, list)) and len(arg) == 2
+                and isinstance(arg[0], str) and isinstance(arg[1], str)
+                for arg in arguments)
+            self._format = self._FORM_ARG_LIST
+            if values is not None:
+                raise ValueError('Unknown format for ExtendedAttribute')
+        elif values is None:
+            self._format = self._FORM_NO_ARGS
+        elif isinstance(values, (tuple, list)):
+            self._format = self._FORM_IDENT_LIST
+            self._values = tuple(values)
+        elif isinstance(values, str):
+            self._format = self._FORM_IDENT
+        else:
+            raise ValueError('Unknown format for ExtendedAttribute')
+
+    def __str__(self):
+        if self._format == self._FORM_NO_ARGS:
+            return self._key
+        if self._format == self._FORM_IDENT:
+            return '{}={}'.format(self._key, self._values)
+        if self._format == self._FORM_IDENT_LIST:
+            return '{}=({})'.format(self._key, ', '.join(self._values))
+        args_str = '({})'.format(', '.join(
+            [' '.join(arg) for arg in self._arguments]))
+        if self._format == self._FORM_ARG_LIST:
+            return '{}{}'.format(self._key, args_str)
+        if self._format == self._FORM_NAMED_ARG_LIST:
+            return '{}={}{}'.format(self._key, self._name, args_str)
+        # Should not reach here.
+        assert False, 'Unknown format: {}'.format(self._format)
 
     @property
     def key(self):
@@ -26,54 +79,91 @@
         Returns the key.
         @return str
         """
-        raise exceptions.NotImplementedError()
+        return self._key
 
     @property
     def value(self):
         """
-        Returns the value for (b). Returns None for (a). Crashes otherwise.
+        Returns the value for the format Ident. Returns None for the format
+        NoArgs. Raises an error otherwise.
         @return str
         """
-        raise exceptions.NotImplementedError()
+        if self._format in (self._FORM_NO_ARGS, self._FORM_IDENT):
+            return self._values
+        raise ValueError('"{}" does not have a single value.'.format(
+            str(self)))
 
     @property
     def values(self):
         """
-        Returns a list of values for (b) and (c). Returns an empty list
-        for (a). Crashes otherwise.
+        Returns a list of values for formats Ident and IdentList. Returns an
+        empty list for the format NorArgs. Raises an error otherwise.
         @return tuple(str)
         """
-        raise exceptions.NotImplementedError()
+        if self._format == self._FORM_NO_ARGS:
+            return ()
+        if self._format == self._FORM_IDENT:
+            return (self._values, )
+        if self._format == self._FORM_IDENT_LIST:
+            return self._values
+        raise ValueError('"{}" does not have values.'.format(str(self)))
 
     @property
     def arguments(self):
         """
-        Returns a tuple of arguments for (d) and (e). Crashes otherwise.
+        Returns a tuple of value pairs for formats ArgList and NamedArgList.
+        Raises an error otherwise.
         @return tuple(Argument)
         """
-        raise exceptions.NotImplementedError()
+        if self._format in (self._FORM_ARG_LIST, self._FORM_NAMED_ARG_LIST):
+            return self._arguments
+        raise ValueError('"{}" does not have arguments.'.format(str(self)))
 
     @property
     def name(self):
         """
-        Returns |Name| for (e). Crashes otherwise.
+        Returns |Name| for the format NamedArgList. Raises an error otherwise.
         @return str
         """
-        raise exceptions.NotImplementedError()
+        if self._format == self._FORM_NAMED_ARG_LIST:
+            return self._name
+        raise ValueError('"{}" does not have a name.'.format(str(self)))
 
 
 class ExtendedAttributes(object):
-    """ExtendedAttributes is a dict-like container for ExtendedAttribute instances."""
+    """
+    ExtendedAttributes is a dict-like container for ExtendedAttribute instances.
+    With a key string, you can get an ExtendedAttribute or a list of them.
 
-    def has_key(self, _):
+    For an IDL fragment
+      [A, A=(foo, bar), B=baz]
+    the generated ExtendedAttributes instance will be like
+      {
+        'A': (ExtendedAttribute('A'), ExtendedAttribute('A', values=('foo', 'bar'))),
+        'B': (ExtendedAttribute('B', value='baz')),
+      }
+    """
+
+    def __init__(self, attributes=None):
+        assert attributes is None or (isinstance(attributes, (list, tuple))
+                                      and all(
+                                          isinstance(attr, ExtendedAttribute)
+                                          for attr in attributes))
+        attributes = sorted(attributes or [], key=lambda x: x.key)
+        self._attributes = {
+            k: tuple(v)
+            for k, v in groupby(attributes, key=lambda x: x.key)
+        }
+
+    def __contains__(self, key):
         """
         Returns True if this has an extended attribute with the |key|.
         @param  str key
         @return bool
         """
-        raise exceptions.NotImplementedError()
+        return key in self._attributes
 
-    def get(self, _):
+    def get(self, key):
         """
         Returns an exnteded attribute whose key is |key|.
         If |self| has no such elements, returns None,
@@ -81,12 +171,24 @@
         @param  str key
         @return ExtendedAttriute?
         """
-        raise exceptions.NotImplementedError()
+        values = self.get_list_of(key)
+        if len(values) == 0:
+            return None
+        if len(values) == 1:
+            return values[0]
+        raise ValueError(
+            'There are multiple extended attributes for the key "{}"'.format(
+                key))
 
-    def get_list_of(self, _):
+    def get_list_of(self, key):
         """
         Returns a list of extended attributes whose keys are |identifier|.
         @param  str key
         @return tuple(ExtendedAttribute)
         """
-        raise exceptions.NotImplementedError()
+        return self._attributes.get(key, ())
+
+    def append(self, extended_attribute):
+        assert isinstance(extended_attribute, ExtendedAttribute)
+        key = extended_attribute.key
+        self._attributes[key] = self.get_list_of(key) + (extended_attribute, )
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute_test.py b/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute_test.py
new file mode 100644
index 0000000..d668aae
--- /dev/null
+++ b/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute_test.py
@@ -0,0 +1,103 @@
+# Copyright 2019 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.
+
+# pylint: disable=import-error,print-statement,relative-import
+"""Unit tests for extended_attributes.py."""
+
+import unittest
+
+from .extended_attribute import ExtendedAttribute
+from .extended_attribute import ExtendedAttributes
+
+
+class TestableExtendedAttribute(ExtendedAttribute):
+    FORM_NO_ARGS = ExtendedAttribute._FORM_NO_ARGS
+    FORM_IDENT = ExtendedAttribute._FORM_IDENT
+    FORM_IDENT_LIST = ExtendedAttribute._FORM_IDENT_LIST
+    FORM_ARG_LIST = ExtendedAttribute._FORM_ARG_LIST
+    FORM_NAMED_ARG_LIST = ExtendedAttribute._FORM_NAMED_ARG_LIST
+
+    def __init__(self, key, values=None, arguments=None, name=None):
+        super(TestableExtendedAttribute, self).__init__(
+            key=key, values=values, arguments=arguments, name=name)
+
+    @property
+    def format(self):
+        return self._format
+
+
+class ExtendedAttributeTest(unittest.TestCase):
+    def test_attribute_create(self):
+        # NoArgs
+        attr = TestableExtendedAttribute(key='Foo')
+        self.assertEqual(attr.format, TestableExtendedAttribute.FORM_NO_ARGS)
+        self.assertEqual(attr.key, 'Foo')
+        self.assertEqual(attr.value, None)
+        self.assertEqual(attr.values, ())
+        with self.assertRaises(ValueError):
+            _ = attr.arguments
+        with self.assertRaises(ValueError):
+            _ = attr.name
+
+        # Ident
+        attr = TestableExtendedAttribute(key='Bar', values='Val')
+        self.assertEqual(attr.format, TestableExtendedAttribute.FORM_IDENT)
+        self.assertEqual(attr.key, 'Bar')
+        self.assertEqual(attr.value, 'Val')
+        self.assertEqual(attr.values, ('Val', ))
+        with self.assertRaises(ValueError):
+            _ = attr.arguments
+        with self.assertRaises(ValueError):
+            _ = attr.name
+
+        # IdentList
+        attr = TestableExtendedAttribute(key='Buz', values=('Val', 'ue'))
+        self.assertEqual(attr.format,
+                         TestableExtendedAttribute.FORM_IDENT_LIST)
+        self.assertEqual(attr.key, 'Buz')
+        self.assertEqual(attr.values, ('Val', 'ue'))
+        attr = TestableExtendedAttribute(
+            key='IdentList', values=['Val', 'ue', 'List'])
+        self.assertEqual(attr.values, ('Val', 'ue', 'List'))
+        with self.assertRaises(ValueError):
+            _ = attr.arguments
+        with self.assertRaises(ValueError):
+            _ = attr.name
+
+        # ArgList
+        attr = TestableExtendedAttribute(
+            key='Foo', arguments=(('Left', 'Right'), ('foo', 'bar')))
+        self.assertEqual(attr.format, TestableExtendedAttribute.FORM_ARG_LIST)
+        self.assertEqual(attr.key, 'Foo')
+        with self.assertRaises(ValueError):
+            _ = attr.values
+        self.assertEqual(attr.arguments, (('Left', 'Right'), ('foo', 'bar')))
+        with self.assertRaises(ValueError):
+            _ = attr.name
+
+        # NamedArgList
+        attr = TestableExtendedAttribute(
+            key='Bar', arguments=(('Left', 'Right'), ), name='Buz')
+        self.assertEqual(attr.format,
+                         TestableExtendedAttribute.FORM_NAMED_ARG_LIST)
+        self.assertEqual(attr.key, 'Bar')
+        with self.assertRaises(ValueError):
+            _ = attr.values
+        self.assertEqual(attr.arguments, (('Left', 'Right'), ))
+        self.assertEqual(attr.name, 'Buz')
+
+    def test_attributes(self):
+        attrs = [
+            ExtendedAttribute(key='A', values='val'),
+            ExtendedAttribute(key='B'),
+            ExtendedAttribute(key='C', values=('Val', 'ue')),
+            ExtendedAttribute(key='B', values=('Val', 'ue', 'B'))
+        ]
+        attributes = ExtendedAttributes(attrs)
+        self.assertTrue('A' in attributes)
+        self.assertFalse('D' in attributes)
+        self.assertEqual(attributes.get('A').value, 'val')
+        b_values = attributes.get_list_of('B')
+        self.assertEqual(b_values[0].values, ())
+        self.assertEqual(b_values[1].values, ('Val', 'ue', 'B'))
diff --git a/third_party/blink/renderer/build/scripts/core/css/css_properties.py b/third_party/blink/renderer/build/scripts/core/css/css_properties.py
index 786e96ce..78a704a 100755
--- a/third_party/blink/renderer/build/scripts/core/css/css_properties.py
+++ b/third_party/blink/renderer/build/scripts/core/css/css_properties.py
@@ -6,7 +6,8 @@
 from blinkbuild.name_style_converter import NameStyleConverter
 from core.css.field_alias_expander import FieldAliasExpander
 import json5_generator
-from name_utilities import enum_for_css_property, enum_for_css_property_alias
+from name_utilities import enum_key_for_css_property, id_for_css_property
+from name_utilities import enum_key_for_css_property_alias, id_for_css_property_alias
 
 
 # These values are converted using CSSPrimitiveValue in the setter function,
@@ -155,12 +156,14 @@
                 "but runtime flags do not currently work for aliases.".format(
                     alias['name'])
             aliased_property = self._properties_by_id[
-                enum_for_css_property(alias['alias_for'])]
+                id_for_css_property(alias['alias_for'])]
             updated_alias = aliased_property.copy()
             updated_alias['name'] = alias['name']
             updated_alias['alias_for'] = alias['alias_for']
             updated_alias['aliased_property'] = aliased_property['name'].to_upper_camel_case()
-            updated_alias['property_id'] = enum_for_css_property_alias(
+            updated_alias['property_id'] = id_for_css_property_alias(
+                alias['name'])
+            updated_alias['enum_key'] = enum_key_for_css_property_alias(
                 alias['name'])
             updated_alias['enum_value'] = aliased_property['enum_value'] + \
                 self._alias_offset
@@ -173,7 +176,8 @@
 
         # Basic info.
         name = property_['name']
-        property_['property_id'] = enum_for_css_property(name)
+        property_['property_id'] = id_for_css_property(name)
+        property_['enum_key'] = enum_key_for_css_property(name)
         property_['is_internal'] = name.original.startswith('-internal-')
         method_name = property_['name_for_methods']
         if not method_name:
diff --git a/third_party/blink/renderer/build/scripts/core/css/make_css_property_names.py b/third_party/blink/renderer/build/scripts/core/css/make_css_property_names.py
index 665487db..2746b75d 100755
--- a/third_party/blink/renderer/build/scripts/core/css/make_css_property_names.py
+++ b/third_party/blink/renderer/build/scripts/core/css/make_css_property_names.py
@@ -19,7 +19,11 @@
         self._css_properties = css_properties.CSSProperties(json5_file_path)
 
     def _enum_declaration(self, property_):
-        return "    %(property_id)s = %(enum_value)s," % property_
+        return "    %(enum_key)s = %(enum_value)s," % property_
+
+    def _unscoped_enum_declaration_compat(self, property_):
+        return "constexpr CSSPropertyID %(property_id)s = " \
+            "CSSPropertyID::%(enum_key)s;" % property_
 
     def _array_item(self, property_):
         return "    static_cast<CSSPropertyID>(%(enum_value)s), " \
@@ -33,6 +37,9 @@
             'property_enums': "\n".join(map(
                 self._enum_declaration,
                 self._css_properties.properties_including_aliases)),
+            'property_enums_compat': "\n".join(map(
+                self._unscoped_enum_declaration_compat,
+                self._css_properties.properties_including_aliases)),
             'property_aliases': "\n".join(
                 map(self._array_item, self._css_properties.aliases)),
             'first_property_id': self._css_properties.first_property_id,
@@ -63,7 +70,8 @@
                 current_offset += len(name) + 1
 
         css_name_and_enum_pairs = [
-            (property_['name'].original, property_['property_id'])
+            (property_['name'].original,
+             'static_cast<int>(' + property_['property_id'] + ')')
             for property_ in self._css_properties.properties_including_aliases]
 
         return {
diff --git a/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py b/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py
index a166b36..361fb6f 100755
--- a/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py
+++ b/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py
@@ -30,7 +30,7 @@
 from core.css import css_properties
 from collections import defaultdict
 import json5_generator
-from name_utilities import enum_for_css_property
+from name_utilities import id_for_css_property
 import template_expander
 
 
@@ -54,7 +54,7 @@
         self._longhand_dictionary = defaultdict(list)
         for property_ in json5_properties.shorthands:
             property_['longhand_property_ids'] = map(
-                enum_for_css_property, property_['longhands'])
+                id_for_css_property, property_['longhands'])
             for longhand in property_['longhand_property_ids']:
                 self._longhand_dictionary[longhand].append(property_)
 
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_instances.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_instances.cc.tmpl
index 32e13519..19f5351 100644
--- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_instances.cc.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_instances.cc.tmpl
@@ -37,8 +37,8 @@
 {% endfor %}
 
 const CSSUnresolvedProperty* GetAliasPropertyInternal(CSSPropertyID id) {
-  DCHECK_GT(id, {{last_property_id}}); // last property id
-  DCHECK_LE(id, {{last_unresolved_property_id}}); // last unresolved property id
+  DCHECK_GT(id, lastCSSProperty);  // last property id
+  DCHECK_LE(id, lastUnresolvedCSSProperty);  // last unresolved property id
   switch (id) {
     {% for property_class_data in alias_classes_by_property_id %}
     case {{property_class_data.property_id}}:
@@ -53,7 +53,7 @@
 const CSSUnresolvedProperty& GetNonAliasPropertyInternal(CSSPropertyID id) {
   DCHECK_NE(id, CSSPropertyInvalid);
   DCHECK_NE(id, CSSPropertyVariable);
-  DCHECK_LE(id, {{last_property_id}}); // last property id
+  DCHECK_LE(id, lastCSSProperty);  // last property id
   static constexpr const CSSUnresolvedProperty* const property_classes[] = {
     {% for property_class_data in property_classes_by_property_id %}
     &property_{{property_class_data.property_id.lower()}},  // {{property_class_data.property_id}}
@@ -61,7 +61,7 @@
   };
   // Subtract 2 because CSSPropertyInvalid and CSSPropertyVariable do not
   // appear in the array.
-  return *property_classes[id - 2];
+  return *property_classes[static_cast<int>(id) - 2];
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.h.tmpl b/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.h.tmpl
index 3b8186fa..02afa72 100644
--- a/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.h.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.h.tmpl
@@ -15,24 +15,36 @@
 
 namespace blink {
 
-enum CSSPropertyID {
-    CSSPropertyInvalid = 0,
-    CSSPropertyVariable = 1,
+enum class CSSPropertyID {
+    kInvalid = 0,
+    kVariable = 1,
 {{property_enums}}
 };
 
+constexpr CSSPropertyID CSSPropertyInvalid = CSSPropertyID::kInvalid;
+constexpr CSSPropertyID CSSPropertyVariable = CSSPropertyID::kVariable;
+{{property_enums_compat}}
+
 const CSSPropertyID kCSSPropertyAliasList[] = {
 {{property_aliases}}
 };
 
-const CSSPropertyID firstCSSProperty = static_cast<CSSPropertyID>({{first_property_id}});
+const int kIntFirstCSSProperty = {{first_property_id}};
+const CSSPropertyID firstCSSProperty = static_cast<CSSPropertyID>(kIntFirstCSSProperty);
 const int numCSSProperties = {{properties_count}};
-const CSSPropertyID lastCSSProperty = static_cast<CSSPropertyID>({{last_property_id}});
+const int kIntLastCSSProperty = {{last_property_id}};
+const CSSPropertyID lastCSSProperty = static_cast<CSSPropertyID>(kIntLastCSSProperty);
 const CSSPropertyID lastUnresolvedCSSProperty = static_cast<CSSPropertyID>({{last_unresolved_property_id}});
-const int numCSSPropertyIDs = lastUnresolvedCSSProperty + 1;
+const int numCSSPropertyIDs = static_cast<int>(lastUnresolvedCSSProperty) + 1;
 const size_t maxCSSPropertyNameLength = {{max_name_length}};
 
-inline bool isCSSPropertyIDWithName(int id)
+inline int GetCSSPropertyIDIndex(CSSPropertyID id) {
+    DCHECK_GE(id, firstCSSProperty);
+    DCHECK_LE(id, lastCSSProperty);
+    return static_cast<int>(id) - kIntFirstCSSProperty;
+}
+
+inline bool isCSSPropertyIDWithName(CSSPropertyID id)
 {
     return id >= firstCSSProperty && id <= lastUnresolvedCSSProperty;
 }
@@ -44,17 +56,17 @@
 
 inline CSSPropertyID convertToCSSPropertyID(int value)
 {
-    DCHECK_GE(value, CSSPropertyInvalid);
-    DCHECK_LE(value, lastCSSProperty);
+    DCHECK_GE(value, static_cast<int>(CSSPropertyID::kInvalid));
+    DCHECK_LE(value, kIntLastCSSProperty);
     return static_cast<CSSPropertyID>(value);
 }
 
 inline CSSPropertyID resolveCSSPropertyID(CSSPropertyID id)
 {
-    return convertToCSSPropertyID(id & ~{{alias_offset}});
+    return convertToCSSPropertyID(static_cast<int>(id) & ~{{alias_offset}});
 }
 
-inline bool isPropertyAlias(CSSPropertyID id) { return id & {{alias_offset}}; }
+inline bool isPropertyAlias(CSSPropertyID id) { return static_cast<int>(id) & {{alias_offset}}; }
 
 CSSPropertyID unresolvedCSSPropertyID(const WTF::String&);
 
diff --git a/third_party/blink/renderer/build/scripts/name_utilities.py b/third_party/blink/renderer/build/scripts/name_utilities.py
index 2ef88dad..dbb95e6 100644
--- a/third_party/blink/renderer/build/scripts/name_utilities.py
+++ b/third_party/blink/renderer/build/scripts/name_utilities.py
@@ -44,14 +44,27 @@
 
 
 def enum_for_css_keyword(keyword):
-    converter = NameStyleConverter(keyword) if type(keyword) is str else keyword
-    return 'CSSValue' + converter.to_upper_camel_case()
+    return 'CSSValue' + _upper_camel_case(keyword)
 
 
-def enum_for_css_property(property_name):
-    converter = NameStyleConverter(property_name) if type(property_name) is str else property_name
-    return 'CSSProperty' + converter.to_upper_camel_case()
+def enum_key_for_css_property(property_name):
+    return 'k' + _upper_camel_case(property_name)
 
 
-def enum_for_css_property_alias(property_name):
+def enum_key_for_css_property_alias(property_name):
+    return 'kAlias' + property_name.to_upper_camel_case()
+
+
+# This id is used to build function names returning CSS properties (e.g.
+# GetCSSPropertyX(), GetCSSPropertyXInternal(), etc.)
+def id_for_css_property(property_name):
+    return 'CSSProperty' + _upper_camel_case(property_name)
+
+
+def id_for_css_property_alias(property_name):
     return 'CSSPropertyAlias' + property_name.to_upper_camel_case()
+
+
+def _upper_camel_case(property_name):
+    converter = NameStyleConverter(property_name) if isinstance(property_name, str) else property_name
+    return converter.to_upper_camel_case()
diff --git a/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc b/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
index f687e99..e21c401 100644
--- a/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
@@ -175,8 +175,7 @@
 
 InterpolationValue ConvertCSSValue(
     const cssvalue::CSSBasicShapeCircleValue& circle) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kCircleComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kCircleComponentIndexCount);
   list->Set(kCircleCenterXIndex, ConvertCSSCoordinate(circle.CenterX()));
   list->Set(kCircleCenterYIndex, ConvertCSSCoordinate(circle.CenterY()));
 
@@ -192,8 +191,7 @@
 
 InterpolationValue ConvertBasicShape(const BasicShapeCircle& circle,
                                      double zoom) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kCircleComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kCircleComponentIndexCount);
   list->Set(kCircleCenterXIndex, ConvertCoordinate(circle.CenterX(), zoom));
   list->Set(kCircleCenterYIndex, ConvertCoordinate(circle.CenterY(), zoom));
 
@@ -208,8 +206,7 @@
 }
 
 std::unique_ptr<InterpolableValue> CreateNeutralValue() {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kCircleComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kCircleComponentIndexCount);
   list->Set(kCircleCenterXIndex, CreateNeutralInterpolableCoordinate());
   list->Set(kCircleCenterYIndex, CreateNeutralInterpolableCoordinate());
   list->Set(kCircleRadiusIndex, CreateNeutralInterpolableRadius());
@@ -244,8 +241,7 @@
 
 InterpolationValue ConvertCSSValue(
     const cssvalue::CSSBasicShapeEllipseValue& ellipse) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kEllipseComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kEllipseComponentIndexCount);
   list->Set(kEllipseCenterXIndex, ConvertCSSCoordinate(ellipse.CenterX()));
   list->Set(kEllipseCenterYIndex, ConvertCSSCoordinate(ellipse.CenterY()));
 
@@ -264,8 +260,7 @@
 
 InterpolationValue ConvertBasicShape(const BasicShapeEllipse& ellipse,
                                      double zoom) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kEllipseComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kEllipseComponentIndexCount);
   list->Set(kEllipseCenterXIndex, ConvertCoordinate(ellipse.CenterX(), zoom));
   list->Set(kEllipseCenterYIndex, ConvertCoordinate(ellipse.CenterY(), zoom));
 
@@ -283,8 +278,7 @@
 }
 
 std::unique_ptr<InterpolableValue> CreateNeutralValue() {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kEllipseComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kEllipseComponentIndexCount);
   list->Set(kEllipseCenterXIndex, CreateNeutralInterpolableCoordinate());
   list->Set(kEllipseCenterYIndex, CreateNeutralInterpolableCoordinate());
   list->Set(kEllipseRadiusXIndex, CreateNeutralInterpolableRadius());
@@ -330,8 +324,7 @@
 
 InterpolationValue ConvertCSSValue(
     const cssvalue::CSSBasicShapeInsetValue& inset) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kInsetComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kInsetComponentIndexCount);
   list->Set(kInsetTopIndex, ConvertCSSLength(inset.Top()));
   list->Set(kInsetRightIndex, ConvertCSSLength(inset.Right()));
   list->Set(kInsetBottomIndex, ConvertCSSLength(inset.Bottom()));
@@ -360,8 +353,7 @@
 
 InterpolationValue ConvertBasicShape(const BasicShapeInset& inset,
                                      double zoom) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kInsetComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kInsetComponentIndexCount);
   list->Set(kInsetTopIndex, ConvertLength(inset.Top(), zoom));
   list->Set(kInsetRightIndex, ConvertLength(inset.Right(), zoom));
   list->Set(kInsetBottomIndex, ConvertLength(inset.Bottom(), zoom));
@@ -389,8 +381,7 @@
 }
 
 std::unique_ptr<InterpolableValue> CreateNeutralValue() {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kInsetComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kInsetComponentIndexCount);
   list->Set(kInsetTopIndex,
             LengthInterpolationFunctions::CreateNeutralInterpolableValue());
   list->Set(kInsetRightIndex,
@@ -455,7 +446,7 @@
 InterpolationValue ConvertCSSValue(
     const cssvalue::CSSBasicShapePolygonValue& polygon) {
   wtf_size_t size = polygon.Values().size();
-  std::unique_ptr<InterpolableList> list = InterpolableList::Create(size);
+  auto list = std::make_unique<InterpolableList>(size);
   for (wtf_size_t i = 0; i < size; i++)
     list->Set(i, ConvertCSSLength(polygon.Values()[i].Get()));
   return InterpolationValue(std::move(list),
@@ -466,7 +457,7 @@
 InterpolationValue ConvertBasicShape(const BasicShapePolygon& polygon,
                                      double zoom) {
   wtf_size_t size = polygon.Values().size();
-  std::unique_ptr<InterpolableList> list = InterpolableList::Create(size);
+  auto list = std::make_unique<InterpolableList>(size);
   for (wtf_size_t i = 0; i < size; i++)
     list->Set(i, ConvertLength(polygon.Values()[i], zoom));
   return InterpolationValue(std::move(list),
@@ -476,8 +467,7 @@
 
 std::unique_ptr<InterpolableValue> CreateNeutralValue(
     const BasicShapeNonInterpolableValue& non_interpolable_value) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(non_interpolable_value.size());
+  auto list = std::make_unique<InterpolableList>(non_interpolable_value.size());
   for (wtf_size_t i = 0; i < non_interpolable_value.size(); i++)
     list->Set(i,
               LengthInterpolationFunctions::CreateNeutralInterpolableValue());
diff --git a/third_party/blink/renderer/core/animation/compositor_animations.cc b/third_party/blink/renderer/core/animation/compositor_animations.cc
index 8b99c1a8a..c4a6ebf6 100644
--- a/third_party/blink/renderer/core/animation/compositor_animations.cc
+++ b/third_party/blink/renderer/core/animation/compositor_animations.cc
@@ -659,8 +659,7 @@
     switch (property.GetCSSProperty().PropertyID()) {
       case CSSPropertyOpacity: {
         target_property = compositor_target_property::OPACITY;
-        std::unique_ptr<CompositorFloatAnimationCurve> float_curve =
-            CompositorFloatAnimationCurve::Create();
+        auto float_curve = std::make_unique<CompositorFloatAnimationCurve>();
         AddKeyframesToCurve(*float_curve, values);
         float_curve->SetTimingFunction(*timing.timing_function);
         float_curve->SetScaledDuration(scale);
@@ -670,8 +669,7 @@
       case CSSPropertyFilter:
       case CSSPropertyBackdropFilter: {
         target_property = compositor_target_property::FILTER;
-        std::unique_ptr<CompositorFilterAnimationCurve> filter_curve =
-            CompositorFilterAnimationCurve::Create();
+        auto filter_curve = std::make_unique<CompositorFilterAnimationCurve>();
         AddKeyframesToCurve(*filter_curve, values);
         filter_curve->SetTimingFunction(*timing.timing_function);
         filter_curve->SetScaledDuration(scale);
@@ -683,8 +681,8 @@
       case CSSPropertyTranslate:
       case CSSPropertyTransform: {
         target_property = compositor_target_property::TRANSFORM;
-        std::unique_ptr<CompositorTransformAnimationCurve> transform_curve =
-            CompositorTransformAnimationCurve::Create();
+        auto transform_curve =
+            std::make_unique<CompositorTransformAnimationCurve>();
         AddKeyframesToCurve(*transform_curve, values);
         transform_curve->SetTimingFunction(*timing.timing_function);
         transform_curve->SetScaledDuration(scale);
@@ -695,8 +693,7 @@
         DCHECK(RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled());
         target_property = compositor_target_property::CSS_CUSTOM_PROPERTY;
         // TODO(kevers): Extend support to non-float types.
-        std::unique_ptr<CompositorFloatAnimationCurve> float_curve =
-            CompositorFloatAnimationCurve::Create();
+        auto float_curve = std::make_unique<CompositorFloatAnimationCurve>();
         AddKeyframesToCurve(*float_curve, values);
         float_curve->SetTimingFunction(*timing.timing_function);
         float_curve->SetScaledDuration(scale);
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc
index 856dc6f..7d16491 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -1273,7 +1273,7 @@
   DEFINE_STATIC_LOCAL(Vector<const CSSProperty*>, properties, ());
   DEFINE_STATIC_LOCAL(StylePropertyShorthand, property_shorthand, ());
   if (properties.IsEmpty()) {
-    for (int i = firstCSSProperty; i <= lastCSSProperty; ++i) {
+    for (int i = kIntFirstCSSProperty; i <= kIntLastCSSProperty; ++i) {
       CSSPropertyID id = convertToCSSPropertyID(i);
       // Avoid creating overlapping transitions with perspective-origin and
       // transition-origin.
diff --git a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
index 128c3c4..f6f7eb0 100644
--- a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
@@ -37,7 +37,7 @@
         return nullptr;
       if (style.ClipPath()->GetType() != ClipPathOperation::SHAPE)
         return nullptr;
-      return ToShapeClipPathOperation(style.ClipPath())->GetBasicShape();
+      return To<ShapeClipPathOperation>(style.ClipPath())->GetBasicShape();
     default:
       NOTREACHED();
       return nullptr;
diff --git a/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc
index d4148db2..5622f4e0 100644
--- a/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc
@@ -171,12 +171,6 @@
 class UnderlyingSideTypesChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<UnderlyingSideTypesChecker> Create(
-      const SideTypes& underlying_side_types) {
-    return base::WrapUnique(
-        new UnderlyingSideTypesChecker(underlying_side_types));
-  }
-
   static SideTypes GetUnderlyingSideTypes(
       const InterpolationValue& underlying) {
     return ToCSSBorderImageLengthBoxNonInterpolableValue(
@@ -184,10 +178,10 @@
         .GetSideTypes();
   }
 
- private:
-  UnderlyingSideTypesChecker(const SideTypes& underlying_side_types)
+  explicit UnderlyingSideTypesChecker(const SideTypes& underlying_side_types)
       : underlying_side_types_(underlying_side_types) {}
 
+ private:
   bool IsValid(const StyleResolverState&,
                const InterpolationValue& underlying) const final {
     return underlying_side_types_ == GetUnderlyingSideTypes(underlying);
@@ -199,18 +193,11 @@
 class InheritedSideTypesChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedSideTypesChecker> Create(
-      const CSSProperty& property,
-      const SideTypes& inherited_side_types) {
-    return base::WrapUnique(
-        new InheritedSideTypesChecker(property, inherited_side_types));
-  }
-
- private:
   InheritedSideTypesChecker(const CSSProperty& property,
                             const SideTypes& inherited_side_types)
       : property_(property), inherited_side_types_(inherited_side_types) {}
 
+ private:
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue& underlying) const final {
     return inherited_side_types_ ==
@@ -223,8 +210,7 @@
 
 InterpolationValue ConvertBorderImageLengthBox(const BorderImageLengthBox& box,
                                                double zoom) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kSideIndexCount);
+  auto list = std::make_unique<InterpolableList>(kSideIndexCount);
   Vector<scoped_refptr<NonInterpolableValue>> non_interpolable_values(
       kSideIndexCount);
   const BorderImageLength* sides[kSideIndexCount] = {};
@@ -238,7 +224,7 @@
     if (side.IsNumber()) {
       list->Set(i, std::make_unique<InterpolableNumber>(side.Number()));
     } else if (side.length().IsAuto()) {
-      list->Set(i, InterpolableList::Create(0));
+      list->Set(i, std::make_unique<InterpolableList>(0));
     } else {
       InterpolationValue converted_side =
           LengthInterpolationFunctions::MaybeConvertLength(side.length(), zoom);
@@ -264,7 +250,7 @@
   SideTypes underlying_side_types =
       UnderlyingSideTypesChecker::GetUnderlyingSideTypes(underlying);
   conversion_checkers.push_back(
-      UnderlyingSideTypesChecker::Create(underlying_side_types));
+      std::make_unique<UnderlyingSideTypesChecker>(underlying_side_types));
   return InterpolationValue(underlying.interpolable_value->CloneAndZero(),
                             ToCSSBorderImageLengthBoxNonInterpolableValue(
                                 *underlying.non_interpolable_value)
@@ -285,8 +271,8 @@
     ConversionCheckers& conversion_checkers) const {
   const BorderImageLengthBox& inherited =
       GetBorderImageLengthBox(CssProperty(), *state.ParentStyle());
-  conversion_checkers.push_back(
-      InheritedSideTypesChecker::Create(CssProperty(), SideTypes(inherited)));
+  conversion_checkers.push_back(std::make_unique<InheritedSideTypesChecker>(
+      CssProperty(), SideTypes(inherited)));
   return ConvertBorderImageLengthBox(inherited,
                                      state.ParentStyle()->EffectiveZoom());
 }
@@ -299,8 +285,7 @@
   if (!quad)
     return nullptr;
 
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kSideIndexCount);
+  auto list = std::make_unique<InterpolableList>(kSideIndexCount);
   Vector<scoped_refptr<NonInterpolableValue>> non_interpolable_values(
       kSideIndexCount);
   const CSSValue* sides[kSideIndexCount] = {};
@@ -321,7 +306,7 @@
     auto* side_identifier_value = DynamicTo<CSSIdentifierValue>(side);
     if (side_identifier_value &&
         side_identifier_value->GetValueID() == CSSValueAuto) {
-      list->Set(i, InterpolableList::Create(0));
+      list->Set(i, std::make_unique<InterpolableList>(0));
       continue;
     }
 
diff --git a/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc
index 2298e0c..a354844 100644
--- a/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc
@@ -148,14 +148,13 @@
     const Length& length,
     double zoom) {
   if (length.IsAuto())
-    return InterpolableList::Create(0);
+    return std::make_unique<InterpolableList>(0);
   return LengthInterpolationFunctions::MaybeConvertLength(length, zoom)
       .interpolable_value;
 }
 
 static InterpolationValue CreateClipValue(const LengthBox& clip, double zoom) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kClipComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kClipComponentIndexCount);
   list->Set(kClipTop, ConvertClipComponent(clip.Top(), zoom));
   list->Set(kClipRight, ConvertClipComponent(clip.Right(), zoom));
   list->Set(kClipBottom, ConvertClipComponent(clip.Bottom(), zoom));
@@ -206,7 +205,7 @@
 static std::unique_ptr<InterpolableValue> ConvertClipComponent(
     const CSSValue& length) {
   if (IsCSSAuto(length))
-    return InterpolableList::Create(0);
+    return std::make_unique<InterpolableList>(0);
   return LengthInterpolationFunctions::MaybeConvertCSSValue(length)
       .interpolable_value;
 }
@@ -218,8 +217,7 @@
   const auto* quad = DynamicTo<CSSQuadValue>(value);
   if (!quad)
     return nullptr;
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kClipComponentIndexCount);
+  auto list = std::make_unique<InterpolableList>(kClipComponentIndexCount);
   list->Set(kClipTop, ConvertClipComponent(*quad->Top()));
   list->Set(kClipRight, ConvertClipComponent(*quad->Right()));
   list->Set(kClipBottom, ConvertClipComponent(*quad->Bottom()));
diff --git a/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
index 93ea04eb..8e173d6 100644
--- a/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
@@ -33,8 +33,7 @@
 static std::unique_ptr<InterpolableValue> CreateInterpolableColorForIndex(
     InterpolableColorIndex index) {
   DCHECK_LT(index, kInterpolableColorIndexCount);
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kInterpolableColorIndexCount);
+  auto list = std::make_unique<InterpolableList>(kInterpolableColorIndexCount);
   for (unsigned i = 0; i < kInterpolableColorIndexCount; i++)
     list->Set(i, std::make_unique<InterpolableNumber>(i == index));
   return std::move(list);
@@ -42,8 +41,7 @@
 
 std::unique_ptr<InterpolableValue>
 CSSColorInterpolationType::CreateInterpolableColor(const Color& color) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kInterpolableColorIndexCount);
+  auto list = std::make_unique<InterpolableList>(kInterpolableColorIndexCount);
   list->Set(kRed,
             std::make_unique<InterpolableNumber>(color.Red() * color.Alpha()));
   list->Set(kGreen, std::make_unique<InterpolableNumber>(color.Green() *
@@ -240,8 +238,8 @@
       MaybeCreateInterpolableColor(value);
   if (!interpolable_color)
     return nullptr;
-  std::unique_ptr<InterpolableList> color_pair =
-      InterpolableList::Create(kInterpolableColorPairIndexCount);
+  auto color_pair =
+      std::make_unique<InterpolableList>(kInterpolableColorPairIndexCount);
   color_pair->Set(kUnvisited, interpolable_color->Clone());
   color_pair->Set(kVisited, std::move(interpolable_color));
   return InterpolationValue(std::move(color_pair));
@@ -253,8 +251,8 @@
   if (unvisited_color.IsNull() || visited_color.IsNull()) {
     return nullptr;
   }
-  std::unique_ptr<InterpolableList> color_pair =
-      InterpolableList::Create(kInterpolableColorPairIndexCount);
+  auto color_pair =
+      std::make_unique<InterpolableList>(kInterpolableColorPairIndexCount);
   color_pair->Set(kUnvisited,
                   CreateInterpolableColor(unvisited_color.Access()));
   color_pair->Set(kVisited, CreateInterpolableColor(visited_color.Access()));
diff --git a/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc
index 7cb1a88..25eba0f 100644
--- a/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc
@@ -28,7 +28,7 @@
     return nullptr;
   }
   return InterpolationValue(
-      InterpolableList::Create(0),
+      std::make_unique<InterpolableList>(0),
       CSSDefaultNonInterpolableValue::Create(
           ToCSSPropertySpecificKeyframe(keyframe).Value()));
 }
diff --git a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
index 2c4be5a..d879d8781 100644
--- a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
@@ -52,11 +52,9 @@
 class UnderlyingFilterListChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<UnderlyingFilterListChecker> Create(
-      scoped_refptr<NonInterpolableList> non_interpolable_list) {
-    return base::WrapUnique(
-        new UnderlyingFilterListChecker(std::move(non_interpolable_list)));
-  }
+  UnderlyingFilterListChecker(
+      scoped_refptr<NonInterpolableList> non_interpolable_list)
+      : non_interpolable_list_(std::move(non_interpolable_list)) {}
 
   bool IsValid(const StyleResolverState&,
                const InterpolationValue& underlying) const final {
@@ -75,22 +73,17 @@
   }
 
  private:
-  UnderlyingFilterListChecker(
-      scoped_refptr<NonInterpolableList> non_interpolable_list)
-      : non_interpolable_list_(std::move(non_interpolable_list)) {}
-
   scoped_refptr<NonInterpolableList> non_interpolable_list_;
 };
 
 class InheritedFilterListChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedFilterListChecker> Create(
-      const CSSProperty& property,
-      const FilterOperations& filter_operations) {
-    return base::WrapUnique(
-        new InheritedFilterListChecker(property, filter_operations));
-  }
+  InheritedFilterListChecker(const CSSProperty& property,
+                             const FilterOperations& filter_operations)
+      : property_(property),
+        filter_operations_wrapper_(
+            FilterOperationsWrapper::Create(filter_operations)) {}
 
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue&) const final {
@@ -100,12 +93,6 @@
   }
 
  private:
-  InheritedFilterListChecker(const CSSProperty& property,
-                             const FilterOperations& filter_operations)
-      : property_(property),
-        filter_operations_wrapper_(
-            FilterOperationsWrapper::Create(filter_operations)) {}
-
   const CSSProperty& property_;
   Persistent<FilterOperationsWrapper> filter_operations_wrapper_;
 };
@@ -113,8 +100,7 @@
 InterpolationValue ConvertFilterList(const FilterOperations& filter_operations,
                                      double zoom) {
   wtf_size_t length = filter_operations.size();
-  std::unique_ptr<InterpolableList> interpolable_list =
-      InterpolableList::Create(length);
+  auto interpolable_list = std::make_unique<InterpolableList>(length);
   Vector<scoped_refptr<NonInterpolableValue>> non_interpolable_values(length);
   for (wtf_size_t i = 0; i < length; i++) {
     InterpolationValue filter_result =
@@ -140,7 +126,7 @@
   NonInterpolableList& non_interpolable_list = const_cast<NonInterpolableList&>(
       ToNonInterpolableList(*underlying.non_interpolable_value));
   conversion_checkers.push_back(
-      UnderlyingFilterListChecker::Create(&non_interpolable_list));
+      std::make_unique<UnderlyingFilterListChecker>(&non_interpolable_list));
   return InterpolationValue(underlying.interpolable_value->CloneAndZero(),
                             &non_interpolable_list);
 }
@@ -157,7 +143,7 @@
     ConversionCheckers& conversion_checkers) const {
   const FilterOperations& inherited_filter_operations =
       GetFilterList(CssProperty(), *state.ParentStyle());
-  conversion_checkers.push_back(InheritedFilterListChecker::Create(
+  conversion_checkers.push_back(std::make_unique<InheritedFilterListChecker>(
       CssProperty(), inherited_filter_operations));
   return ConvertFilterList(inherited_filter_operations,
                            state.Style()->EffectiveZoom());
@@ -169,7 +155,7 @@
     ConversionCheckers&) const {
   auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
   if (identifier_value && identifier_value->GetValueID() == CSSValueNone)
-    return InterpolationValue(InterpolableList::Create(0),
+    return InterpolationValue(std::make_unique<InterpolableList>(0),
                               NonInterpolableList::Create());
 
   if (!value.IsBaseValueList())
@@ -177,8 +163,7 @@
 
   const auto& list = To<CSSValueList>(value);
   wtf_size_t length = list.length();
-  std::unique_ptr<InterpolableList> interpolable_list =
-      InterpolableList::Create(length);
+  auto interpolable_list = std::make_unique<InterpolableList>(length);
   Vector<scoped_refptr<NonInterpolableValue>> non_interpolable_values(length);
   for (wtf_size_t i = 0; i < length; i++) {
     InterpolationValue item_result =
@@ -235,8 +220,8 @@
       ToInterpolableList(*shorter.interpolable_value);
   const NonInterpolableList& longer_non_interpolable_list =
       ToNonInterpolableList(*longer.non_interpolable_value);
-  std::unique_ptr<InterpolableList> extended_interpolable_list =
-      InterpolableList::Create(longer_length);
+  auto extended_interpolable_list =
+      std::make_unique<InterpolableList>(longer_length);
   for (wtf_size_t i = 0; i < longer_length; i++) {
     if (i < shorter_length)
       extended_interpolable_list->Set(
@@ -289,8 +274,7 @@
   if (length <= underlying_length)
     return;
 
-  std::unique_ptr<InterpolableList> extended_interpolable_list =
-      InterpolableList::Create(length);
+  auto extended_interpolable_list = std::make_unique<InterpolableList>(length);
   for (wtf_size_t i = 0; i < length; i++) {
     if (i < underlying_length)
       extended_interpolable_list->Set(
diff --git a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
index ce4ea07..6262ba2 100644
--- a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
@@ -73,18 +73,13 @@
 class InheritedFontVariationSettingsChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  ~InheritedFontVariationSettingsChecker() final = default;
-
-  static std::unique_ptr<InheritedFontVariationSettingsChecker> Create(
-      const FontVariationSettings* settings) {
-    return base::WrapUnique(
-        new InheritedFontVariationSettingsChecker(settings));
-  }
-
- private:
-  InheritedFontVariationSettingsChecker(const FontVariationSettings* settings)
+  explicit InheritedFontVariationSettingsChecker(
+      const FontVariationSettings* settings)
       : settings_(settings) {}
 
+  ~InheritedFontVariationSettingsChecker() final = default;
+
+ private:
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue&) const final {
     return DataEquivalent(
@@ -101,7 +96,7 @@
     return nullptr;
   }
   wtf_size_t length = settings->size();
-  std::unique_ptr<InterpolableList> numbers = InterpolableList::Create(length);
+  auto numbers = std::make_unique<InterpolableList>(length);
   Vector<AtomicString> tags;
   for (wtf_size_t i = 0; i < length; ++i) {
     numbers->Set(i,
@@ -137,7 +132,7 @@
   const FontVariationSettings* inherited =
       state.ParentStyle()->GetFontDescription().VariationSettings();
   conversion_checkers.push_back(
-      InheritedFontVariationSettingsChecker::Create(inherited));
+      std::make_unique<InheritedFontVariationSettingsChecker>(inherited));
   return ConvertFontVariationSettings(inherited);
 }
 
@@ -150,7 +145,7 @@
     return nullptr;
   }
   wtf_size_t length = list->length();
-  std::unique_ptr<InterpolableList> numbers = InterpolableList::Create(length);
+  auto numbers = std::make_unique<InterpolableList>(length);
   Vector<AtomicString> tags;
   for (wtf_size_t i = 0; i < length; ++i) {
     const auto& item = To<cssvalue::CSSFontVariationValue>(list->Item(i));
diff --git a/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc
index 9525dcd..280cf6d 100644
--- a/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc
@@ -17,15 +17,10 @@
 class InheritedFontWeightChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedFontWeightChecker> Create(
-      FontSelectionValue font_weight) {
-    return base::WrapUnique(new InheritedFontWeightChecker(font_weight));
-  }
-
- private:
-  InheritedFontWeightChecker(FontSelectionValue font_weight)
+  explicit InheritedFontWeightChecker(FontSelectionValue font_weight)
       : font_weight_(font_weight) {}
 
+ private:
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue&) const final {
     return font_weight_ == state.ParentStyle()->GetFontWeight();
@@ -59,7 +54,7 @@
   FontSelectionValue inherited_font_weight =
       state.ParentStyle()->GetFontWeight();
   conversion_checkers.push_back(
-      InheritedFontWeightChecker::Create(inherited_font_weight));
+      std::make_unique<InheritedFontWeightChecker>(inherited_font_weight));
   return CreateFontWeightValue(inherited_font_weight);
 }
 
@@ -89,7 +84,7 @@
       FontSelectionValue inherited_font_weight =
           state->ParentStyle()->GetFontWeight();
       conversion_checkers.push_back(
-          InheritedFontWeightChecker::Create(inherited_font_weight));
+          std::make_unique<InheritedFontWeightChecker>(inherited_font_weight));
       if (keyword == CSSValueBolder) {
         return CreateFontWeightValue(
             FontDescription::BolderWeight(inherited_font_weight));
diff --git a/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc
index bf46181..cc406ca 100644
--- a/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc
@@ -21,17 +21,11 @@
 class UnderlyingImageListChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
+  explicit UnderlyingImageListChecker(const InterpolationValue& underlying)
+      : underlying_(underlying.Clone()) {}
   ~UnderlyingImageListChecker() final = default;
 
-  static std::unique_ptr<UnderlyingImageListChecker> Create(
-      const InterpolationValue& underlying) {
-    return base::WrapUnique(new UnderlyingImageListChecker(underlying));
-  }
-
  private:
-  UnderlyingImageListChecker(const InterpolationValue& underlying)
-      : underlying_(underlying.Clone()) {}
-
   bool IsValid(const StyleResolverState&,
                const InterpolationValue& underlying) const final {
     return ListInterpolationFunctions::EqualValues(
@@ -45,7 +39,8 @@
 InterpolationValue CSSImageListInterpolationType::MaybeConvertNeutral(
     const InterpolationValue& underlying,
     ConversionCheckers& conversion_checkers) const {
-  conversion_checkers.push_back(UnderlyingImageListChecker::Create(underlying));
+  conversion_checkers.push_back(
+      std::make_unique<UnderlyingImageListChecker>(underlying));
   return underlying.Clone();
 }
 
@@ -123,8 +118,7 @@
   const auto& value_list = temp_list ? *temp_list : To<CSSValueList>(value);
 
   const wtf_size_t length = value_list.length();
-  std::unique_ptr<InterpolableList> interpolable_list =
-      InterpolableList::Create(length);
+  auto interpolable_list = std::make_unique<InterpolableList>(length);
   Vector<scoped_refptr<NonInterpolableValue>> non_interpolable_values(length);
   for (wtf_size_t i = 0; i < length; i++) {
     InterpolationValue component =
diff --git a/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
index 31fc9b2..2686262f 100644
--- a/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
@@ -91,10 +91,8 @@
 class UnderlyingSliceTypesChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<UnderlyingSliceTypesChecker> Create(
-      const SliceTypes& underlying_types) {
-    return base::WrapUnique(new UnderlyingSliceTypesChecker(underlying_types));
-  }
+  explicit UnderlyingSliceTypesChecker(const SliceTypes& underlying_types)
+      : underlying_types_(underlying_types) {}
 
   static SliceTypes GetUnderlyingSliceTypes(
       const InterpolationValue& underlying) {
@@ -104,9 +102,6 @@
   }
 
  private:
-  UnderlyingSliceTypesChecker(const SliceTypes& underlying_types)
-      : underlying_types_(underlying_types) {}
-
   bool IsValid(const StyleResolverState&,
                const InterpolationValue& underlying) const final {
     return underlying_types_ == GetUnderlyingSliceTypes(underlying);
@@ -135,8 +130,7 @@
 };
 
 InterpolationValue ConvertImageSlice(const ImageSlice& slice, double zoom) {
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kSideIndexCount);
+  auto list = std::make_unique<InterpolableList>(kSideIndexCount);
   const Length* sides[kSideIndexCount] = {};
   sides[kSideTop] = &slice.slices.Top();
   sides[kSideRight] = &slice.slices.Right();
@@ -162,7 +156,7 @@
   SliceTypes underlying_types =
       UnderlyingSliceTypesChecker::GetUnderlyingSliceTypes(underlying);
   conversion_checkers.push_back(
-      UnderlyingSliceTypesChecker::Create(underlying_types));
+      std::make_unique<UnderlyingSliceTypesChecker>(underlying_types));
   LengthBox zero_box(
       underlying_types.is_number[kSideTop] ? Length::Fixed(0)
                                            : Length::Percent(0),
@@ -203,8 +197,7 @@
 
   const cssvalue::CSSBorderImageSliceValue& slice =
       To<cssvalue::CSSBorderImageSliceValue>(value);
-  std::unique_ptr<InterpolableList> list =
-      InterpolableList::Create(kSideIndexCount);
+  auto list = std::make_unique<InterpolableList>(kSideIndexCount);
   const CSSValue* sides[kSideIndexCount];
   sides[kSideTop] = slice.Slices().Top();
   sides[kSideRight] = slice.Slices().Right();
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_interpolation_type.cc
index 4971ad0..2908159 100644
--- a/third_party/blink/renderer/core/animation/css_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_interpolation_type.cc
@@ -56,16 +56,6 @@
 class InheritedCustomPropertyChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedCustomPropertyChecker> Create(
-      const AtomicString& property,
-      bool is_inherited_property,
-      const CSSValue* inherited_value,
-      const CSSValue* initial_value) {
-    return base::WrapUnique(new InheritedCustomPropertyChecker(
-        property, is_inherited_property, inherited_value, initial_value));
-  }
-
- private:
   InheritedCustomPropertyChecker(const AtomicString& name,
                                  bool is_inherited_property,
                                  const CSSValue* inherited_value,
@@ -75,6 +65,7 @@
         inherited_value_(inherited_value),
         initial_value_(initial_value) {}
 
+ private:
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue&) const final {
     const CSSValue* inherited_value =
@@ -95,20 +86,13 @@
 class ResolvedRegisteredCustomPropertyChecker
     : public InterpolationType::ConversionChecker {
  public:
-  static std::unique_ptr<ResolvedRegisteredCustomPropertyChecker> Create(
-      const CSSCustomPropertyDeclaration& declaration,
-      scoped_refptr<CSSVariableData> resolved_tokens) {
-    return base::WrapUnique(new ResolvedRegisteredCustomPropertyChecker(
-        declaration, std::move(resolved_tokens)));
-  }
-
- private:
   ResolvedRegisteredCustomPropertyChecker(
       const CSSCustomPropertyDeclaration& declaration,
       scoped_refptr<CSSVariableData> resolved_tokens)
       : declaration_(declaration),
         resolved_tokens_(std::move(resolved_tokens)) {}
 
+ private:
   bool IsValid(const InterpolationEnvironment& environment,
                const InterpolationValue&) const final {
     DCHECK(ToCSSInterpolationEnvironment(environment).HasVariableResolver());
@@ -213,8 +197,9 @@
       if (!value) {
         value = Registration().Initial();
       }
-      conversion_checkers.push_back(InheritedCustomPropertyChecker::Create(
-          name, is_inherited_property, value, Registration().Initial()));
+      conversion_checkers.push_back(
+          std::make_unique<InheritedCustomPropertyChecker>(
+              name, is_inherited_property, value, Registration().Initial()));
     }
     if (!value) {
       return nullptr;
@@ -230,8 +215,8 @@
         declaration, cycle_detected);
     DCHECK(!cycle_detected);
     conversion_checkers.push_back(
-        ResolvedRegisteredCustomPropertyChecker::Create(declaration,
-                                                        resolved_tokens));
+        std::make_unique<ResolvedRegisteredCustomPropertyChecker>(
+            declaration, resolved_tokens));
   } else {
     resolved_tokens = declaration.Value();
   }
diff --git a/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc
index d83b0ce..eb886c3 100644
--- a/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc
@@ -43,11 +43,9 @@
 class UnderlyingRotationTypeChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<UnderlyingRotationTypeChecker> Create(
-      OffsetRotationType underlying_rotation_type) {
-    return base::WrapUnique(
-        new UnderlyingRotationTypeChecker(underlying_rotation_type));
-  }
+  explicit UnderlyingRotationTypeChecker(
+      OffsetRotationType underlying_rotation_type)
+      : underlying_rotation_type_(underlying_rotation_type) {}
 
   bool IsValid(const StyleResolverState&,
                const InterpolationValue& underlying) const final {
@@ -57,20 +55,15 @@
   }
 
  private:
-  UnderlyingRotationTypeChecker(OffsetRotationType underlying_rotation_type)
-      : underlying_rotation_type_(underlying_rotation_type) {}
-
   OffsetRotationType underlying_rotation_type_;
 };
 
 class InheritedOffsetRotationChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedOffsetRotationChecker> Create(
-      StyleOffsetRotation inherited_rotation) {
-    return base::WrapUnique(
-        new InheritedOffsetRotationChecker(inherited_rotation));
-  }
+  explicit InheritedOffsetRotationChecker(
+      StyleOffsetRotation inherited_rotation)
+      : inherited_rotation_(inherited_rotation) {}
 
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue& underlying) const final {
@@ -78,9 +71,6 @@
   }
 
  private:
-  InheritedOffsetRotationChecker(StyleOffsetRotation inherited_rotation)
-      : inherited_rotation_(inherited_rotation) {}
-
   StyleOffsetRotation inherited_rotation_;
 };
 
@@ -99,8 +89,8 @@
       ToCSSOffsetRotationNonInterpolableValue(
           *underlying.non_interpolable_value)
           .RotationType();
-  conversion_checkers.push_back(
-      UnderlyingRotationTypeChecker::Create(underlying_rotation_type));
+  conversion_checkers.push_back(std::make_unique<UnderlyingRotationTypeChecker>(
+      underlying_rotation_type));
   return ConvertOffsetRotate(StyleOffsetRotation(0, underlying_rotation_type));
 }
 
@@ -116,7 +106,7 @@
   const StyleOffsetRotation& inherited_rotation =
       state.ParentStyle()->OffsetRotate();
   conversion_checkers.push_back(
-      InheritedOffsetRotationChecker::Create(inherited_rotation));
+      std::make_unique<InheritedOffsetRotationChecker>(inherited_rotation));
   return ConvertOffsetRotate(inherited_rotation);
 }
 
diff --git a/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc
index b7e5e95..6229fa8 100644
--- a/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc
@@ -59,7 +59,7 @@
 };
 
 std::unique_ptr<InterpolableValue> CreateScaleIdentity() {
-  std::unique_ptr<InterpolableList> list = InterpolableList::Create(3);
+  auto list = std::make_unique<InterpolableList>(3);
   for (wtf_size_t i = 0; i < 3; i++)
     list->Set(i, std::make_unique<InterpolableNumber>(1));
   return std::move(list);
@@ -132,11 +132,11 @@
 
 InterpolationValue Scale::CreateInterpolationValue() const {
   if (is_none) {
-    return InterpolationValue(InterpolableList::Create(0),
+    return InterpolationValue(std::make_unique<InterpolableList>(0),
                               CSSScaleNonInterpolableValue::Create(*this));
   }
 
-  std::unique_ptr<InterpolableList> list = InterpolableList::Create(3);
+  auto list = std::make_unique<InterpolableList>(3);
   for (wtf_size_t i = 0; i < 3; i++)
     list->Set(i, std::make_unique<InterpolableNumber>(array[i]));
   return InterpolationValue(std::move(list),
diff --git a/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc
index 5794827b..dda5ec6 100644
--- a/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc
@@ -68,18 +68,11 @@
 class InheritedShadowListChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedShadowListChecker> Create(
-      const CSSProperty& property,
-      scoped_refptr<ShadowList> shadow_list) {
-    return base::WrapUnique(
-        new InheritedShadowListChecker(property, std::move(shadow_list)));
-  }
-
- private:
   InheritedShadowListChecker(const CSSProperty& property,
                              scoped_refptr<ShadowList> shadow_list)
       : property_(property), shadow_list_(std::move(shadow_list)) {}
 
+ private:
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue& underlying) const final {
     const ShadowList* inherited_shadow_list =
@@ -102,7 +95,7 @@
     return nullptr;
   const ShadowList* inherited_shadow_list =
       GetShadowList(CssProperty(), *state.ParentStyle());
-  conversion_checkers.push_back(InheritedShadowListChecker::Create(
+  conversion_checkers.push_back(std::make_unique<InheritedShadowListChecker>(
       CssProperty(),
       const_cast<ShadowList*>(inherited_shadow_list)));  // Take ref.
   return ConvertShadowList(inherited_shadow_list,
diff --git a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc
index ed33d1de..a6f1f64 100644
--- a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc
@@ -75,10 +75,7 @@
 class UnderlyingIndentModeChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<UnderlyingIndentModeChecker> Create(
-      const IndentMode& mode) {
-    return base::WrapUnique(new UnderlyingIndentModeChecker(mode));
-  }
+  explicit UnderlyingIndentModeChecker(const IndentMode& mode) : mode_(mode) {}
 
   bool IsValid(const StyleResolverState&,
                const InterpolationValue& underlying) const final {
@@ -88,19 +85,14 @@
   }
 
  private:
-  UnderlyingIndentModeChecker(const IndentMode& mode) : mode_(mode) {}
-
   const IndentMode mode_;
 };
 
 class InheritedIndentChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedIndentChecker> Create(
-      const Length& length,
-      const IndentMode& mode) {
-    return base::WrapUnique(new InheritedIndentChecker(length, mode));
-  }
+  InheritedIndentChecker(const Length& length, const IndentMode& mode)
+      : length_(length), mode_(mode) {}
 
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue&) const final {
@@ -109,9 +101,6 @@
   }
 
  private:
-  InheritedIndentChecker(const Length& length, const IndentMode& mode)
-      : length_(length), mode_(mode) {}
-
   const Length length_;
   const IndentMode mode_;
 };
@@ -136,7 +125,8 @@
   IndentMode mode =
       ToCSSTextIndentNonInterpolableValue(*underlying.non_interpolable_value)
           .Mode();
-  conversion_checkers.push_back(UnderlyingIndentModeChecker::Create(mode));
+  conversion_checkers.push_back(
+      std::make_unique<UnderlyingIndentModeChecker>(mode));
   return CreateValue(Length::Fixed(0), mode, 1);
 }
 
@@ -153,8 +143,8 @@
     ConversionCheckers& conversion_checkers) const {
   const ComputedStyle& parent_style = *state.ParentStyle();
   IndentMode mode(parent_style);
-  conversion_checkers.push_back(
-      InheritedIndentChecker::Create(parent_style.TextIndent(), mode));
+  conversion_checkers.push_back(std::make_unique<InheritedIndentChecker>(
+      parent_style.TextIndent(), mode));
   return CreateValue(parent_style.TextIndent(), mode,
                      parent_style.EffectiveZoom());
 }
diff --git a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc
index 635e3b9..1841482 100644
--- a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc
@@ -136,10 +136,8 @@
 class InheritedTransformChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedTransformChecker> Create(
-      const TransformOperations& inherited_transform) {
-    return base::WrapUnique(new InheritedTransformChecker(inherited_transform));
-  }
+  InheritedTransformChecker(const TransformOperations& inherited_transform)
+      : inherited_transform_(inherited_transform) {}
 
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue& underlying) const final {
@@ -147,9 +145,6 @@
   }
 
  private:
-  InheritedTransformChecker(const TransformOperations& inherited_transform)
-      : inherited_transform_(inherited_transform) {}
-
   const TransformOperations inherited_transform_;
 };
 
@@ -173,7 +168,7 @@
   const TransformOperations& inherited_transform =
       state.ParentStyle()->Transform();
   conversion_checkers.push_back(
-      InheritedTransformChecker::Create(inherited_transform));
+      std::make_unique<InheritedTransformChecker>(inherited_transform));
   return ConvertTransform(inherited_transform);
 }
 
diff --git a/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc
index dd9842ae..d763aa9 100644
--- a/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc
@@ -19,7 +19,7 @@
 namespace {
 
 InterpolationValue CreateNoneValue() {
-  return InterpolationValue(InterpolableList::Create(0));
+  return InterpolationValue(std::make_unique<InterpolableList>(0));
 }
 
 bool IsNoneValue(const InterpolationValue& value) {
@@ -29,13 +29,11 @@
 class InheritedTranslateChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
+  InheritedTranslateChecker(
+      scoped_refptr<TranslateTransformOperation> inherited_translate)
+      : inherited_translate_(std::move(inherited_translate)) {}
   ~InheritedTranslateChecker() override = default;
 
-  static std::unique_ptr<InheritedTranslateChecker> Create(
-      scoped_refptr<TranslateTransformOperation> inherited_translate) {
-    return base::WrapUnique(
-        new InheritedTranslateChecker(std::move(inherited_translate)));
-  }
 
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue& underlying) const final {
@@ -49,10 +47,6 @@
   }
 
  private:
-  InheritedTranslateChecker(
-      scoped_refptr<TranslateTransformOperation> inherited_translate)
-      : inherited_translate_(std::move(inherited_translate)) {}
-
   scoped_refptr<TransformOperation> inherited_translate_;
 };
 
@@ -64,8 +58,8 @@
 };
 
 std::unique_ptr<InterpolableValue> CreateTranslateIdentity() {
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(kTranslateComponentIndexCount);
+  auto result =
+      std::make_unique<InterpolableList>(kTranslateComponentIndexCount);
   result->Set(kTranslateX,
               LengthInterpolationFunctions::CreateNeutralInterpolableValue());
   result->Set(kTranslateY,
@@ -81,8 +75,8 @@
   if (!translate)
     return CreateNoneValue();
 
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(kTranslateComponentIndexCount);
+  auto result =
+      std::make_unique<InterpolableList>(kTranslateComponentIndexCount);
   result->Set(kTranslateX, LengthInterpolationFunctions::MaybeConvertLength(
                                translate->X(), zoom)
                                .interpolable_value);
@@ -115,7 +109,7 @@
   TranslateTransformOperation* inherited_translate =
       state.ParentStyle()->Translate();
   conversion_checkers.push_back(
-      InheritedTranslateChecker::Create(inherited_translate));
+      std::make_unique<InheritedTranslateChecker>(inherited_translate));
   return ConvertTranslateOperation(inherited_translate,
                                    state.ParentStyle()->EffectiveZoom());
 }
@@ -132,8 +126,8 @@
   if (list.length() < 1 || list.length() > 3)
     return nullptr;
 
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(kTranslateComponentIndexCount);
+  auto result =
+      std::make_unique<InterpolableList>(kTranslateComponentIndexCount);
   for (wtf_size_t i = 0; i < kTranslateComponentIndexCount; i++) {
     InterpolationValue component = nullptr;
     if (i < list.length()) {
diff --git a/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
index 227d193..8f378e73 100644
--- a/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
@@ -48,7 +48,7 @@
 }
 
 static InterpolationValue CreateCycleDetectedValue() {
-  return InterpolationValue(InterpolableList::Create(0));
+  return InterpolationValue(std::make_unique<InterpolableList>(0));
 }
 
 InterpolationValue CSSVarCycleInterpolationType::MaybeConvertSingle(
diff --git a/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc
index 1e25242..741ad88 100644
--- a/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc
@@ -54,17 +54,13 @@
 class UnderlyingVisibilityChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  ~UnderlyingVisibilityChecker() final = default;
-
-  static std::unique_ptr<UnderlyingVisibilityChecker> Create(
-      EVisibility visibility) {
-    return base::WrapUnique(new UnderlyingVisibilityChecker(visibility));
-  }
-
- private:
-  UnderlyingVisibilityChecker(EVisibility visibility)
+  explicit UnderlyingVisibilityChecker(EVisibility visibility)
       : visibility_(visibility) {}
 
+  ~UnderlyingVisibilityChecker() final = default;
+
+
+ private:
   bool IsValid(const StyleResolverState&,
                const InterpolationValue& underlying) const final {
     double underlying_fraction =
@@ -81,15 +77,10 @@
 class InheritedVisibilityChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedVisibilityChecker> Create(
-      EVisibility visibility) {
-    return base::WrapUnique(new InheritedVisibilityChecker(visibility));
-  }
-
- private:
-  InheritedVisibilityChecker(EVisibility visibility)
+  explicit InheritedVisibilityChecker(EVisibility visibility)
       : visibility_(visibility) {}
 
+ private:
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue& underlying) const final {
     return visibility_ == state.ParentStyle()->Visibility();
@@ -114,7 +105,7 @@
       ToCSSVisibilityNonInterpolableValue(*underlying.non_interpolable_value)
           .Visibility(underlying_fraction);
   conversion_checkers.push_back(
-      UnderlyingVisibilityChecker::Create(underlying_visibility));
+      std::make_unique<UnderlyingVisibilityChecker>(underlying_visibility));
   return CreateVisibilityValue(underlying_visibility);
 }
 
@@ -131,7 +122,7 @@
     return nullptr;
   EVisibility inherited_visibility = state.ParentStyle()->Visibility();
   conversion_checkers.push_back(
-      InheritedVisibilityChecker::Create(inherited_visibility));
+      std::make_unique<InheritedVisibilityChecker>(inherited_visibility));
   return CreateVisibilityValue(inherited_visibility);
 }
 
diff --git a/third_party/blink/renderer/core/animation/document_timeline.cc b/third_party/blink/renderer/core/animation/document_timeline.cc
index 43b8369..62464ff 100644
--- a/third_party/blink/renderer/core/animation/document_timeline.cc
+++ b/third_party/blink/renderer/core/animation/document_timeline.cc
@@ -88,7 +88,7 @@
     timing_ = timing;
 
   if (Platform::Current()->IsThreadedAnimationEnabled())
-    compositor_timeline_ = CompositorAnimationTimeline::Create();
+    compositor_timeline_ = std::make_unique<CompositorAnimationTimeline>();
 
   DCHECK(document);
 }
diff --git a/third_party/blink/renderer/core/animation/interpolable_value.cc b/third_party/blink/renderer/core/animation/interpolable_value.cc
index 56cd711..fbf0b68 100644
--- a/third_party/blink/renderer/core/animation/interpolable_value.cc
+++ b/third_party/blink/renderer/core/animation/interpolable_value.cc
@@ -56,7 +56,7 @@
 }
 
 std::unique_ptr<InterpolableValue> InterpolableList::CloneAndZero() const {
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(length());
+  auto result = std::make_unique<InterpolableList>(length());
   for (wtf_size_t i = 0; i < length(); i++)
     result->Set(i, values_[i]->CloneAndZero());
   return std::move(result);
diff --git a/third_party/blink/renderer/core/animation/interpolable_value.h b/third_party/blink/renderer/core/animation/interpolable_value.h
index 4ece6f68..652a2ba 100644
--- a/third_party/blink/renderer/core/animation/interpolable_value.h
+++ b/third_party/blink/renderer/core/animation/interpolable_value.h
@@ -85,13 +85,11 @@
   // has its own copy constructor. So just delete operator= here.
   InterpolableList& operator=(const InterpolableList&) = delete;
 
-  static std::unique_ptr<InterpolableList> Create(
-      const InterpolableList& other) {
-    return base::WrapUnique(new InterpolableList(other));
-  }
+  explicit InterpolableList(wtf_size_t size) : values_(size) {}
 
-  static std::unique_ptr<InterpolableList> Create(wtf_size_t size) {
-    return base::WrapUnique(new InterpolableList(size));
+  InterpolableList(const InterpolableList& other) : values_(other.length()) {
+    for (wtf_size_t i = 0; i < length(); i++)
+      Set(i, other.values_[i]->Clone());
   }
 
   bool IsList() const final { return true; }
@@ -107,7 +105,7 @@
   wtf_size_t length() const { return values_.size(); }
   bool Equals(const InterpolableValue& other) const final;
   std::unique_ptr<InterpolableValue> Clone() const final {
-    return Create(*this);
+    return std::make_unique<InterpolableList>(*this);
   }
   std::unique_ptr<InterpolableValue> CloneAndZero() const final;
   void Scale(double scale) final;
@@ -117,12 +115,6 @@
   void Interpolate(const InterpolableValue& to,
                    const double progress,
                    InterpolableValue& result) const final;
-  explicit InterpolableList(wtf_size_t size) : values_(size) {}
-
-  InterpolableList(const InterpolableList& other) : values_(other.length()) {
-    for (wtf_size_t i = 0; i < length(); i++)
-      Set(i, other.values_[i]->Clone());
-  }
 
   Vector<std::unique_ptr<InterpolableValue>> values_;
 };
diff --git a/third_party/blink/renderer/core/animation/interpolable_value_test.cc b/third_party/blink/renderer/core/animation/interpolable_value_test.cc
index 15ea031..5bbe52b 100644
--- a/third_party/blink/renderer/core/animation/interpolable_value_test.cc
+++ b/third_party/blink/renderer/core/animation/interpolable_value_test.cc
@@ -71,12 +71,12 @@
 }
 
 TEST_F(AnimationInterpolableValueTest, SimpleList) {
-  std::unique_ptr<InterpolableList> list_a = InterpolableList::Create(3);
+  auto list_a = std::make_unique<InterpolableList>(3);
   list_a->Set(0, std::make_unique<InterpolableNumber>(0));
   list_a->Set(1, std::make_unique<InterpolableNumber>(42));
   list_a->Set(2, std::make_unique<InterpolableNumber>(20.5));
 
-  std::unique_ptr<InterpolableList> list_b = InterpolableList::Create(3);
+  auto list_b = std::make_unique<InterpolableList>(3);
   list_b->Set(0, std::make_unique<InterpolableNumber>(100));
   list_b->Set(1, std::make_unique<InterpolableNumber>(-200));
   list_b->Set(2, std::make_unique<InterpolableNumber>(300));
@@ -92,16 +92,16 @@
 }
 
 TEST_F(AnimationInterpolableValueTest, NestedList) {
-  std::unique_ptr<InterpolableList> list_a = InterpolableList::Create(3);
+  auto list_a = std::make_unique<InterpolableList>(3);
   list_a->Set(0, std::make_unique<InterpolableNumber>(0));
-  std::unique_ptr<InterpolableList> sub_list_a = InterpolableList::Create(1);
+  auto sub_list_a = std::make_unique<InterpolableList>(1);
   sub_list_a->Set(0, std::make_unique<InterpolableNumber>(100));
   list_a->Set(1, std::move(sub_list_a));
   list_a->Set(2, std::make_unique<InterpolableNumber>(0));
 
-  std::unique_ptr<InterpolableList> list_b = InterpolableList::Create(3);
+  auto list_b = std::make_unique<InterpolableList>(3);
   list_b->Set(0, std::make_unique<InterpolableNumber>(100));
-  std::unique_ptr<InterpolableList> sub_list_b = InterpolableList::Create(1);
+  auto sub_list_b = std::make_unique<InterpolableList>(1);
   sub_list_b->Set(0, std::make_unique<InterpolableNumber>(50));
   list_b->Set(1, std::move(sub_list_b));
   list_b->Set(2, std::make_unique<InterpolableNumber>(1));
@@ -134,11 +134,11 @@
 }
 
 TEST_F(AnimationInterpolableValueTest, ScaleAndAddLists) {
-  std::unique_ptr<InterpolableList> base_list = InterpolableList::Create(3);
+  auto base_list = std::make_unique<InterpolableList>(3);
   base_list->Set(0, std::make_unique<InterpolableNumber>(5));
   base_list->Set(1, std::make_unique<InterpolableNumber>(10));
   base_list->Set(2, std::make_unique<InterpolableNumber>(15));
-  std::unique_ptr<InterpolableList> add_list = InterpolableList::Create(3);
+  auto add_list = std::make_unique<InterpolableList>(3);
   add_list->Set(0, std::make_unique<InterpolableNumber>(1));
   add_list->Set(1, std::make_unique<InterpolableNumber>(2));
   add_list->Set(2, std::make_unique<InterpolableNumber>(3));
diff --git a/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc b/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc
index 5b38eb6..4b99e714 100644
--- a/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc
+++ b/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc
@@ -45,7 +45,7 @@
             underlying_value_owner.Value(), conversion_checkers);
     AddConversionCheckers(*interpolation_type, conversion_checkers);
     if (result) {
-      return PairwisePrimitiveInterpolation::Create(
+      return std::make_unique<PairwisePrimitiveInterpolation>(
           *interpolation_type, std::move(result.start_interpolable_value),
           std::move(result.end_interpolable_value),
           std::move(result.non_interpolable_value));
@@ -167,7 +167,7 @@
       cached_value_ = pairwise_conversion->InitialValue();
       cached_pair_conversion_ = std::move(pairwise_conversion);
     } else {
-      cached_pair_conversion_ = FlipPrimitiveInterpolation::Create(
+      cached_pair_conversion_ = std::make_unique<FlipPrimitiveInterpolation>(
           ConvertSingleKeyframe(*start_keyframe_, environment,
                                 underlying_value_owner),
           ConvertSingleKeyframe(*end_keyframe_, environment,
diff --git a/third_party/blink/renderer/core/animation/length_interpolation_functions.cc b/third_party/blink/renderer/core/animation/length_interpolation_functions.cc
index 57d9f6a1..84f713f8 100644
--- a/third_party/blink/renderer/core/animation/length_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/length_interpolation_functions.cc
@@ -48,8 +48,7 @@
 
 std::unique_ptr<InterpolableValue>
 LengthInterpolationFunctions::CreateInterpolablePixels(double pixels) {
-  std::unique_ptr<InterpolableList> interpolable_list =
-      CreateNeutralInterpolableValue();
+  auto interpolable_list = CreateNeutralInterpolableValue();
   interpolable_list->Set(CSSPrimitiveValue::kUnitTypePixels,
                          std::make_unique<InterpolableNumber>(pixels));
   return std::move(interpolable_list);
@@ -57,8 +56,7 @@
 
 InterpolationValue LengthInterpolationFunctions::CreateInterpolablePercent(
     double percent) {
-  std::unique_ptr<InterpolableList> interpolable_list =
-      CreateNeutralInterpolableValue();
+  auto interpolable_list = CreateNeutralInterpolableValue();
   interpolable_list->Set(CSSPrimitiveValue::kUnitTypePercentage,
                          std::make_unique<InterpolableNumber>(percent));
   return InterpolationValue(std::move(interpolable_list),
@@ -68,7 +66,7 @@
 std::unique_ptr<InterpolableList>
 LengthInterpolationFunctions::CreateNeutralInterpolableValue() {
   const size_t kLength = CSSPrimitiveValue::kLengthUnitTypeCount;
-  std::unique_ptr<InterpolableList> values = InterpolableList::Create(kLength);
+  auto values = std::make_unique<InterpolableList>(kLength);
   for (wtf_size_t i = 0; i < kLength; i++)
     values->Set(i, std::make_unique<InterpolableNumber>(0));
   return values;
@@ -87,8 +85,8 @@
   CSSLengthArray length_array;
   primitive_value->AccumulateLengthArray(length_array);
 
-  std::unique_ptr<InterpolableList> values =
-      InterpolableList::Create(CSSPrimitiveValue::kLengthUnitTypeCount);
+  auto values = std::make_unique<InterpolableList>(
+      CSSPrimitiveValue::kLengthUnitTypeCount);
   for (wtf_size_t i = 0; i < CSSPrimitiveValue::kLengthUnitTypeCount; i++) {
     values->Set(i,
                 std::make_unique<InterpolableNumber>(length_array.values[i]));
@@ -107,7 +105,7 @@
     return nullptr;
 
   PixelsAndPercent pixels_and_percent = length.GetPixelsAndPercent();
-  std::unique_ptr<InterpolableList> values = CreateNeutralInterpolableValue();
+  auto values = CreateNeutralInterpolableValue();
   values->Set(
       CSSPrimitiveValue::kUnitTypePixels,
       std::make_unique<InterpolableNumber>(pixels_and_percent.pixels / zoom));
diff --git a/third_party/blink/renderer/core/animation/list_interpolation_functions.cc b/third_party/blink/renderer/core/animation/list_interpolation_functions.cc
index 09bfde3a..5025955 100644
--- a/third_party/blink/renderer/core/animation/list_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/list_interpolation_functions.cc
@@ -118,10 +118,10 @@
 
   const wtf_size_t final_length =
       MatchLengths(start_length, end_length, length_matching_strategy);
-  std::unique_ptr<InterpolableList> result_start_interpolable_list =
-      InterpolableList::Create(final_length);
-  std::unique_ptr<InterpolableList> result_end_interpolable_list =
-      InterpolableList::Create(final_length);
+  auto result_start_interpolable_list =
+      std::make_unique<InterpolableList>(final_length);
+  auto result_end_interpolable_list =
+      std::make_unique<InterpolableList>(final_length);
   Vector<scoped_refptr<NonInterpolableValue>> result_non_interpolable_values(
       final_length);
 
@@ -190,8 +190,7 @@
   if (current_length == length)
     return;
   DCHECK_LT(current_length, length);
-  std::unique_ptr<InterpolableList> new_interpolable_list =
-      InterpolableList::Create(length);
+  auto new_interpolable_list = std::make_unique<InterpolableList>(length);
   Vector<scoped_refptr<NonInterpolableValue>> new_non_interpolable_values(
       length);
   for (wtf_size_t i = length; i-- > 0;) {
@@ -222,8 +221,8 @@
       ToNonInterpolableList(*length_value.non_interpolable_value);
   const wtf_size_t target_length = target_interpolable_list.length();
   DCHECK_LT(current_length, target_length);
-  std::unique_ptr<InterpolableList> new_interpolable_list =
-      InterpolableList::Create(target_length);
+  auto new_interpolable_list =
+      std::make_unique<InterpolableList>(target_length);
   Vector<scoped_refptr<NonInterpolableValue>> new_non_interpolable_values(
       target_length);
   wtf_size_t index = 0;
diff --git a/third_party/blink/renderer/core/animation/list_interpolation_functions.h b/third_party/blink/renderer/core/animation/list_interpolation_functions.h
index 3cca4332..15491312 100644
--- a/third_party/blink/renderer/core/animation/list_interpolation_functions.h
+++ b/third_party/blink/renderer/core/animation/list_interpolation_functions.h
@@ -23,7 +23,7 @@
   template <typename CreateItemCallback>
   static InterpolationValue CreateList(wtf_size_t length, CreateItemCallback);
   static InterpolationValue CreateEmptyList() {
-    return InterpolationValue(InterpolableList::Create(0));
+    return InterpolationValue(std::make_unique<InterpolableList>(0));
   }
 
   enum class LengthMatchingStrategy {
@@ -105,8 +105,7 @@
     CreateItemCallback create_item) {
   if (length == 0)
     return CreateEmptyList();
-  std::unique_ptr<InterpolableList> interpolable_list =
-      InterpolableList::Create(length);
+  auto interpolable_list = std::make_unique<InterpolableList>(length);
   Vector<scoped_refptr<NonInterpolableValue>> non_interpolable_values(length);
   for (wtf_size_t i = 0; i < length; i++) {
     InterpolationValue item = create_item(i);
diff --git a/third_party/blink/renderer/core/animation/path_interpolation_functions.cc b/third_party/blink/renderer/core/animation/path_interpolation_functions.cc
index 339a0d90..3260e29 100644
--- a/third_party/blink/renderer/core/animation/path_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/path_interpolation_functions.cc
@@ -70,13 +70,11 @@
     length++;
   }
 
-  std::unique_ptr<InterpolableList> path_args =
-      InterpolableList::Create(length);
+  auto path_args = std::make_unique<InterpolableList>(length);
   for (wtf_size_t i = 0; i < interpolable_path_segs.size(); i++)
     path_args->Set(i, std::move(interpolable_path_segs[i]));
 
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(kPathComponentIndexCount);
+  auto result = std::make_unique<InterpolableList>(kPathComponentIndexCount);
   result->Set(kPathArgsIndex, std::move(path_args));
   result->Set(kPathNeutralIndex, std::make_unique<InterpolableNumber>(0));
 
@@ -129,8 +127,7 @@
     InterpolationType::ConversionCheckers& conversion_checkers) {
   conversion_checkers.push_back(
       UnderlyingPathSegTypesChecker::Create(underlying));
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(kPathComponentIndexCount);
+  auto result = std::make_unique<InterpolableList>(kPathComponentIndexCount);
   result->Set(kPathArgsIndex, ToInterpolableList(*underlying.interpolable_value)
                                   .Get(kPathArgsIndex)
                                   ->CloneAndZero());
diff --git a/third_party/blink/renderer/core/animation/primitive_interpolation.h b/third_party/blink/renderer/core/animation/primitive_interpolation.h
index d9a15b0..0caf5e2f 100644
--- a/third_party/blink/renderer/core/animation/primitive_interpolation.h
+++ b/third_party/blink/renderer/core/animation/primitive_interpolation.h
@@ -44,26 +44,6 @@
 // eg. "0px" and "100px".
 class PairwisePrimitiveInterpolation : public PrimitiveInterpolation {
  public:
-  ~PairwisePrimitiveInterpolation() override = default;
-
-  static std::unique_ptr<PairwisePrimitiveInterpolation> Create(
-      const InterpolationType& type,
-      std::unique_ptr<InterpolableValue> start,
-      std::unique_ptr<InterpolableValue> end,
-      scoped_refptr<NonInterpolableValue> non_interpolable_value) {
-    return base::WrapUnique(new PairwisePrimitiveInterpolation(
-        type, std::move(start), std::move(end),
-        std::move(non_interpolable_value)));
-  }
-
-  const InterpolationType& GetType() const { return type_; }
-
-  std::unique_ptr<TypedInterpolationValue> InitialValue() const {
-    return std::make_unique<TypedInterpolationValue>(type_, start_->Clone(),
-                                                     non_interpolable_value_);
-  }
-
- private:
   PairwisePrimitiveInterpolation(
       const InterpolationType& type,
       std::unique_ptr<InterpolableValue> start,
@@ -77,6 +57,16 @@
     DCHECK(end_);
   }
 
+  ~PairwisePrimitiveInterpolation() override = default;
+
+  const InterpolationType& GetType() const { return type_; }
+
+  std::unique_ptr<TypedInterpolationValue> InitialValue() const {
+    return std::make_unique<TypedInterpolationValue>(type_, start_->Clone(),
+                                                     non_interpolable_value_);
+  }
+
+ private:
   void InterpolateValue(
       double fraction,
       std::unique_ptr<TypedInterpolationValue>& result) const final {
@@ -103,22 +93,15 @@
 // behaviour eg. "auto" and "0px".
 class FlipPrimitiveInterpolation : public PrimitiveInterpolation {
  public:
-  ~FlipPrimitiveInterpolation() override = default;
-
-  static std::unique_ptr<FlipPrimitiveInterpolation> Create(
-      std::unique_ptr<TypedInterpolationValue> start,
-      std::unique_ptr<TypedInterpolationValue> end) {
-    return base::WrapUnique(
-        new FlipPrimitiveInterpolation(std::move(start), std::move(end)));
-  }
-
- private:
   FlipPrimitiveInterpolation(std::unique_ptr<TypedInterpolationValue> start,
                              std::unique_ptr<TypedInterpolationValue> end)
       : start_(std::move(start)),
         end_(std::move(end)),
         last_fraction_(std::numeric_limits<double>::quiet_NaN()) {}
 
+  ~FlipPrimitiveInterpolation() override = default;
+
+ private:
   void InterpolateValue(
       double fraction,
       std::unique_ptr<TypedInterpolationValue>& result) const final {
diff --git a/third_party/blink/renderer/core/animation/property_handle.cc b/third_party/blink/renderer/core/animation/property_handle.cc
index 7b39fe7a..66687e2 100644
--- a/third_party/blink/renderer/core/animation/property_handle.cc
+++ b/third_party/blink/renderer/core/animation/property_handle.cc
@@ -28,11 +28,11 @@
 unsigned PropertyHandle::GetHash() const {
   switch (handle_type_) {
     case kHandleCSSProperty:
-      return css_property_->PropertyID();
+      return static_cast<int>(css_property_->PropertyID());
     case kHandleCSSCustomProperty:
       return AtomicStringHash::GetHash(property_name_);
     case kHandlePresentationAttribute:
-      return -css_property_->PropertyID();
+      return -static_cast<int>(css_property_->PropertyID());
     case kHandleSVGAttribute:
       return QualifiedNameHash::GetHash(*svg_attribute_);
     default:
diff --git a/third_party/blink/renderer/core/animation/shadow_interpolation_functions.cc b/third_party/blink/renderer/core/animation/shadow_interpolation_functions.cc
index d995a8b..6ebdc71 100644
--- a/third_party/blink/renderer/core/animation/shadow_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/shadow_interpolation_functions.cc
@@ -69,8 +69,8 @@
 InterpolationValue ShadowInterpolationFunctions::ConvertShadowData(
     const ShadowData& shadow_data,
     double zoom) {
-  std::unique_ptr<InterpolableList> interpolable_list =
-      InterpolableList::Create(kShadowComponentIndexCount);
+  auto interpolable_list =
+      std::make_unique<InterpolableList>(kShadowComponentIndexCount);
   interpolable_list->Set(kShadowX,
                          LengthInterpolationFunctions::CreateInterpolablePixels(
                              shadow_data.X() / zoom));
@@ -105,8 +105,8 @@
       return nullptr;
   }
 
-  std::unique_ptr<InterpolableList> interpolable_list =
-      InterpolableList::Create(kShadowComponentIndexCount);
+  auto interpolable_list =
+      std::make_unique<InterpolableList>(kShadowComponentIndexCount);
   static_assert(kShadowX == 0, "Enum ordering check.");
   static_assert(kShadowY == 1, "Enum ordering check.");
   static_assert(kShadowBlur == 2, "Enum ordering check.");
diff --git a/third_party/blink/renderer/core/animation/size_interpolation_functions.cc b/third_party/blink/renderer/core/animation/size_interpolation_functions.cc
index c2de09a1..ae41144 100644
--- a/third_party/blink/renderer/core/animation/size_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/size_interpolation_functions.cc
@@ -61,7 +61,7 @@
 DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSSizeNonInterpolableValue);
 
 static InterpolationValue ConvertKeyword(CSSValueID keyword) {
-  return InterpolationValue(InterpolableList::Create(0),
+  return InterpolationValue(std::make_unique<InterpolableList>(0),
                             CSSSizeNonInterpolableValue::Create(keyword));
 }
 
diff --git a/third_party/blink/renderer/core/animation/string_keyframe.cc b/third_party/blink/renderer/core/animation/string_keyframe.cc
index d7d1a81..70c4ee0 100644
--- a/third_party/blink/renderer/core/animation/string_keyframe.cc
+++ b/third_party/blink/renderer/core/animation/string_keyframe.cc
@@ -83,7 +83,7 @@
     const CSSProperty& property = property_reference.Property();
     DCHECK(!property.IsShorthand())
         << "Web Animations: Encountered unexpanded shorthand CSS property ("
-        << property.PropertyID() << ").";
+        << static_cast<int>(property.PropertyID()) << ").";
     if (property.IDEquals(CSSPropertyVariable)) {
       properties.insert(PropertyHandle(
           To<CSSCustomPropertyDeclaration>(property_reference.Value())
diff --git a/third_party/blink/renderer/core/animation/svg_integer_optional_integer_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_integer_optional_integer_interpolation_type.cc
index 2f90d040..6e6df42d 100644
--- a/third_party/blink/renderer/core/animation/svg_integer_optional_integer_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_integer_optional_integer_interpolation_type.cc
@@ -14,7 +14,7 @@
 SVGIntegerOptionalIntegerInterpolationType::MaybeConvertNeutral(
     const InterpolationValue&,
     ConversionCheckers&) const {
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(2);
+  auto result = std::make_unique<InterpolableList>(2);
   result->Set(0, std::make_unique<InterpolableNumber>(0));
   result->Set(1, std::make_unique<InterpolableNumber>(0));
   return InterpolationValue(std::move(result));
@@ -28,7 +28,7 @@
 
   const SVGIntegerOptionalInteger& integer_optional_integer =
       ToSVGIntegerOptionalInteger(svg_value);
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(2);
+  auto result = std::make_unique<InterpolableList>(2);
   result->Set(0, std::make_unique<InterpolableNumber>(
                      integer_optional_integer.FirstInteger()->Value()));
   result->Set(1, std::make_unique<InterpolableNumber>(
diff --git a/third_party/blink/renderer/core/animation/svg_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_length_interpolation_type.cc
index 71c464f..3de83c0 100644
--- a/third_party/blink/renderer/core/animation/svg_length_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_length_interpolation_type.cc
@@ -16,8 +16,8 @@
 
 std::unique_ptr<InterpolableValue>
 SVGLengthInterpolationType::NeutralInterpolableValue() {
-  std::unique_ptr<InterpolableList> list_of_values =
-      InterpolableList::Create(CSSPrimitiveValue::kLengthUnitTypeCount);
+  auto list_of_values = std::make_unique<InterpolableList>(
+      CSSPrimitiveValue::kLengthUnitTypeCount);
   for (wtf_size_t i = 0; i < CSSPrimitiveValue::kLengthUnitTypeCount; ++i)
     list_of_values->Set(i, std::make_unique<InterpolableNumber>(0));
 
@@ -31,8 +31,8 @@
   CSSLengthArray length_array;
   primitive_value.AccumulateLengthArray(length_array);
 
-  std::unique_ptr<InterpolableList> list_of_values =
-      InterpolableList::Create(CSSPrimitiveValue::kLengthUnitTypeCount);
+  auto list_of_values = std::make_unique<InterpolableList>(
+      CSSPrimitiveValue::kLengthUnitTypeCount);
   for (wtf_size_t i = 0; i < CSSPrimitiveValue::kLengthUnitTypeCount; ++i) {
     list_of_values->Set(
         i, std::make_unique<InterpolableNumber>(length_array.values[i]));
diff --git a/third_party/blink/renderer/core/animation/svg_length_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_length_list_interpolation_type.cc
index 3acb6aa..7071b1c 100644
--- a/third_party/blink/renderer/core/animation/svg_length_list_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_length_list_interpolation_type.cc
@@ -23,8 +23,7 @@
   if (underlying_length == 0)
     return nullptr;
 
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(underlying_length);
+  auto result = std::make_unique<InterpolableList>(underlying_length);
   for (wtf_size_t i = 0; i < underlying_length; i++)
     result->Set(i, SVGLengthInterpolationType::NeutralInterpolableValue());
   return InterpolationValue(std::move(result));
@@ -36,8 +35,7 @@
     return nullptr;
 
   const SVGLengthList& length_list = ToSVGLengthList(svg_value);
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(length_list.length());
+  auto result = std::make_unique<InterpolableList>(length_list.length());
   for (wtf_size_t i = 0; i < length_list.length(); i++) {
     InterpolationValue component =
         SVGLengthInterpolationType::ConvertSVGLength(*length_list.at(i));
diff --git a/third_party/blink/renderer/core/animation/svg_number_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_number_list_interpolation_type.cc
index df46cfc..876a645 100644
--- a/third_party/blink/renderer/core/animation/svg_number_list_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_number_list_interpolation_type.cc
@@ -22,8 +22,7 @@
   if (underlying_length == 0)
     return nullptr;
 
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(underlying_length);
+  auto result = std::make_unique<InterpolableList>(underlying_length);
   for (wtf_size_t i = 0; i < underlying_length; i++)
     result->Set(i, std::make_unique<InterpolableNumber>(0));
   return InterpolationValue(std::move(result));
@@ -35,8 +34,7 @@
     return nullptr;
 
   const SVGNumberList& number_list = ToSVGNumberList(svg_value);
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(number_list.length());
+  auto result = std::make_unique<InterpolableList>(number_list.length());
   for (wtf_size_t i = 0; i < number_list.length(); i++) {
     result->Set(
         i, std::make_unique<InterpolableNumber>(number_list.at(i)->Value()));
@@ -61,8 +59,7 @@
   if (list.length() >= padded_length)
     return;
 
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(padded_length);
+  auto result = std::make_unique<InterpolableList>(padded_length);
   wtf_size_t i = 0;
   for (; i < list.length(); i++)
     result->Set(i, std::move(list.GetMutable(i)));
diff --git a/third_party/blink/renderer/core/animation/svg_number_optional_number_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_number_optional_number_interpolation_type.cc
index d201bb0..9a874ba 100644
--- a/third_party/blink/renderer/core/animation/svg_number_optional_number_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_number_optional_number_interpolation_type.cc
@@ -14,7 +14,7 @@
 SVGNumberOptionalNumberInterpolationType::MaybeConvertNeutral(
     const InterpolationValue&,
     ConversionCheckers&) const {
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(2);
+  auto result = std::make_unique<InterpolableList>(2);
   result->Set(0, std::make_unique<InterpolableNumber>(0));
   result->Set(1, std::make_unique<InterpolableNumber>(0));
   return InterpolationValue(std::move(result));
@@ -28,7 +28,7 @@
 
   const SVGNumberOptionalNumber& number_optional_number =
       ToSVGNumberOptionalNumber(svg_value);
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(2);
+  auto result = std::make_unique<InterpolableList>(2);
   result->Set(0, std::make_unique<InterpolableNumber>(
                      number_optional_number.FirstNumber()->Value()));
   result->Set(1, std::make_unique<InterpolableNumber>(
diff --git a/third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.cc b/third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.cc
index 12c231b1..2ca6d9e 100644
--- a/third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.cc
@@ -44,7 +44,7 @@
     PathCoordinates& coordinates) {
   coordinates.current_x = coordinates.initial_x;
   coordinates.current_y = coordinates.initial_y;
-  return InterpolableList::Create(0);
+  return std::make_unique<InterpolableList>(0);
 }
 
 PathSegmentData ConsumeInterpolableClosePath(const InterpolableValue&,
@@ -62,7 +62,7 @@
     const PathSegmentData& segment,
     PathCoordinates& coordinates) {
   bool is_absolute = IsAbsolutePathSegType(segment.command);
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(2);
+  auto result = std::make_unique<InterpolableList>(2);
   result->Set(0, ConsumeCoordinateAxis(segment.X(), is_absolute,
                                        coordinates.current_x));
   result->Set(1, ConsumeCoordinateAxis(segment.Y(), is_absolute,
@@ -105,7 +105,7 @@
     const PathSegmentData& segment,
     PathCoordinates& coordinates) {
   bool is_absolute = IsAbsolutePathSegType(segment.command);
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(6);
+  auto result = std::make_unique<InterpolableList>(6);
   result->Set(
       0, ConsumeControlAxis(segment.X1(), is_absolute, coordinates.current_x));
   result->Set(
@@ -147,7 +147,7 @@
     const PathSegmentData& segment,
     PathCoordinates& coordinates) {
   bool is_absolute = IsAbsolutePathSegType(segment.command);
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(4);
+  auto result = std::make_unique<InterpolableList>(4);
   result->Set(
       0, ConsumeControlAxis(segment.X1(), is_absolute, coordinates.current_x));
   result->Set(
@@ -181,7 +181,7 @@
 std::unique_ptr<InterpolableValue> ConsumeArc(const PathSegmentData& segment,
                                               PathCoordinates& coordinates) {
   bool is_absolute = IsAbsolutePathSegType(segment.command);
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(7);
+  auto result = std::make_unique<InterpolableList>(7);
   result->Set(0, ConsumeCoordinateAxis(segment.X(), is_absolute,
                                        coordinates.current_x));
   result->Set(1, ConsumeCoordinateAxis(segment.Y(), is_absolute,
@@ -256,7 +256,7 @@
     const PathSegmentData& segment,
     PathCoordinates& coordinates) {
   bool is_absolute = IsAbsolutePathSegType(segment.command);
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(4);
+  auto result = std::make_unique<InterpolableList>(4);
   result->Set(
       0, ConsumeControlAxis(segment.X2(), is_absolute, coordinates.current_x));
   result->Set(
diff --git a/third_party/blink/renderer/core/animation/svg_point_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_point_list_interpolation_type.cc
index 507141b..f0e25b02 100644
--- a/third_party/blink/renderer/core/animation/svg_point_list_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_point_list_interpolation_type.cc
@@ -23,8 +23,7 @@
   if (underlying_length == 0)
     return nullptr;
 
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(underlying_length);
+  auto result = std::make_unique<InterpolableList>(underlying_length);
   for (wtf_size_t i = 0; i < underlying_length; i++)
     result->Set(i, std::make_unique<InterpolableNumber>(0));
   return InterpolationValue(std::move(result));
@@ -36,8 +35,7 @@
     return nullptr;
 
   const SVGPointList& point_list = ToSVGPointList(svg_value);
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(point_list.length() * 2);
+  auto result = std::make_unique<InterpolableList>(point_list.length() * 2);
   for (wtf_size_t i = 0; i < point_list.length(); i++) {
     const SVGPoint& point = *point_list.at(i);
     result->Set(2 * i, std::make_unique<InterpolableNumber>(point.X()));
diff --git a/third_party/blink/renderer/core/animation/svg_rect_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_rect_interpolation_type.cc
index f56fb42..51f06ce 100644
--- a/third_party/blink/renderer/core/animation/svg_rect_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_rect_interpolation_type.cc
@@ -22,8 +22,7 @@
 InterpolationValue SVGRectInterpolationType::MaybeConvertNeutral(
     const InterpolationValue&,
     ConversionCheckers&) const {
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(kRectComponentIndexCount);
+  auto result = std::make_unique<InterpolableList>(kRectComponentIndexCount);
   for (wtf_size_t i = 0; i < kRectComponentIndexCount; i++)
     result->Set(i, std::make_unique<InterpolableNumber>(0));
   return InterpolationValue(std::move(result));
@@ -35,8 +34,7 @@
     return nullptr;
 
   const SVGRect& rect = ToSVGRect(svg_value);
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(kRectComponentIndexCount);
+  auto result = std::make_unique<InterpolableList>(kRectComponentIndexCount);
   result->Set(kRectX, std::make_unique<InterpolableNumber>(rect.X()));
   result->Set(kRectY, std::make_unique<InterpolableNumber>(rect.Y()));
   result->Set(kRectWidth, std::make_unique<InterpolableNumber>(rect.Width()));
diff --git a/third_party/blink/renderer/core/animation/svg_transform_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_transform_list_interpolation_type.cc
index 82ffec3..779b179 100644
--- a/third_party/blink/renderer/core/animation/svg_transform_list_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_transform_list_interpolation_type.cc
@@ -49,7 +49,7 @@
 std::unique_ptr<InterpolableValue> TranslateToInterpolableValue(
     SVGTransform* transform) {
   FloatPoint translate = transform->Translate();
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(2);
+  auto result = std::make_unique<InterpolableList>(2);
   result->Set(0, std::make_unique<InterpolableNumber>(translate.X()));
   result->Set(1, std::make_unique<InterpolableNumber>(translate.Y()));
   return std::move(result);
@@ -67,7 +67,7 @@
 std::unique_ptr<InterpolableValue> ScaleToInterpolableValue(
     SVGTransform* transform) {
   FloatSize scale = transform->Scale();
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(2);
+  auto result = std::make_unique<InterpolableList>(2);
   result->Set(0, std::make_unique<InterpolableNumber>(scale.Width()));
   result->Set(1, std::make_unique<InterpolableNumber>(scale.Height()));
   return std::move(result);
@@ -85,7 +85,7 @@
 std::unique_ptr<InterpolableValue> RotateToInterpolableValue(
     SVGTransform* transform) {
   FloatPoint rotation_center = transform->RotationCenter();
-  std::unique_ptr<InterpolableList> result = InterpolableList::Create(3);
+  auto result = std::make_unique<InterpolableList>(3);
   result->Set(0, std::make_unique<InterpolableNumber>(transform->Angle()));
   result->Set(1, std::make_unique<InterpolableNumber>(rotation_center.X()));
   result->Set(2, std::make_unique<InterpolableNumber>(rotation_center.Y()));
@@ -212,8 +212,7 @@
     return nullptr;
 
   const SVGTransformList& svg_list = ToSVGTransformList(svg_value);
-  std::unique_ptr<InterpolableList> result =
-      InterpolableList::Create(svg_list.length());
+  auto result = std::make_unique<InterpolableList>(svg_list.length());
 
   Vector<SVGTransformType> transform_types;
   for (wtf_size_t i = 0; i < svg_list.length(); i++) {
@@ -262,8 +261,7 @@
     interpolable_parts.push_back(std::move(value.interpolable_value));
   }
 
-  std::unique_ptr<InterpolableList> interpolable_list =
-      InterpolableList::Create(types.size());
+  auto interpolable_list = std::make_unique<InterpolableList>(types.size());
   wtf_size_t interpolable_list_index = 0;
   for (auto& part : interpolable_parts) {
     InterpolableList& list = ToInterpolableList(*part);
diff --git a/third_party/blink/renderer/core/animation/svg_value_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_value_interpolation_type.cc
index cb008dd..5792ea7 100644
--- a/third_party/blink/renderer/core/animation/svg_value_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_value_interpolation_type.cc
@@ -38,7 +38,7 @@
   SVGPropertyBase* referenced_value =
       const_cast<SVGPropertyBase*>(&value);  // Take ref.
   return InterpolationValue(
-      InterpolableList::Create(0),
+      std::make_unique<InterpolableList>(0),
       SVGValueNonInterpolableValue::Create(referenced_value));
 }
 
diff --git a/third_party/blink/renderer/core/core_initializer.cc b/third_party/blink/renderer/core/core_initializer.cc
index 4b2cc24..45a820c 100644
--- a/third_party/blink/renderer/core/core_initializer.cc
+++ b/third_party/blink/renderer/core/core_initializer.cc
@@ -32,7 +32,6 @@
 
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
 #include "third_party/blink/renderer/core/css/media_feature_names.h"
 #include "third_party/blink/renderer/core/css/media_query_evaluator.h"
@@ -147,7 +146,6 @@
   V8ThrowDOMException::Init();
 
   BindingSecurity::Init();
-  ScriptStreamerThread::Init();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc b/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
index ac94bcd..f8bc038 100644
--- a/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
+++ b/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
@@ -71,7 +71,7 @@
 String AbstractPropertySetCSSStyleDeclaration::getPropertyValue(
     const String& property_name) {
   CSSPropertyID property_id = cssPropertyID(property_name);
-  if (!property_id)
+  if (!isValidCSSPropertyID(property_id))
     return String();
   if (property_id == CSSPropertyVariable)
     return PropertySet().GetPropertyValue(AtomicString(property_name));
@@ -81,7 +81,7 @@
 String AbstractPropertySetCSSStyleDeclaration::getPropertyPriority(
     const String& property_name) {
   CSSPropertyID property_id = cssPropertyID(property_name);
-  if (!property_id)
+  if (!isValidCSSPropertyID(property_id))
     return String();
 
   bool important = false;
@@ -97,10 +97,11 @@
   CSSPropertyID property_id = cssPropertyID(property_name);
 
   // Custom properties don't have shorthands, so we can ignore them here.
-  if (!property_id || !CSSProperty::Get(property_id).IsLonghand())
+  if (!isValidCSSPropertyID(property_id) ||
+      !CSSProperty::Get(property_id).IsLonghand())
     return String();
   CSSPropertyID shorthand_id = PropertySet().GetPropertyShorthand(property_id);
-  if (!shorthand_id)
+  if (!isValidCSSPropertyID(shorthand_id))
     return String();
   return CSSProperty::Get(shorthand_id).GetPropertyNameString();
 }
@@ -110,7 +111,7 @@
   CSSPropertyID property_id = cssPropertyID(property_name);
 
   // Custom properties don't have shorthands, so we can ignore them here.
-  if (!property_id || property_id == CSSPropertyVariable)
+  if (property_id < firstCSSProperty)
     return false;
   return PropertySet().IsPropertyImplicit(property_id);
 }
@@ -122,7 +123,7 @@
     const String& priority,
     ExceptionState& exception_state) {
   CSSPropertyID property_id = unresolvedCSSPropertyID(property_name);
-  if (!property_id)
+  if (!isValidCSSPropertyID(property_id))
     return;
 
   bool important = EqualIgnoringASCIICase(priority, "important");
@@ -138,7 +139,7 @@
     const String& property_name,
     ExceptionState& exception_state) {
   CSSPropertyID property_id = cssPropertyID(property_name);
-  if (!property_id)
+  if (!isValidCSSPropertyID(property_id))
     return String();
 
   StyleAttributeMutationScope mutation_scope(this);
diff --git a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
index 87a139a4..b2ef659 100644
--- a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
+++ b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
@@ -449,7 +449,7 @@
 String CSSComputedStyleDeclaration::getPropertyValue(
     const String& property_name) {
   CSSPropertyID property_id = cssPropertyID(property_name);
-  if (!property_id)
+  if (!isValidCSSPropertyID(property_id))
     return String();
   if (property_id == CSSPropertyVariable) {
     const CSSValue* value = GetPropertyCSSValue(AtomicString(property_name));
diff --git a/third_party/blink/renderer/core/css/css_property_id_templates.h b/third_party/blink/renderer/core/css/css_property_id_templates.h
index ac0f2f50b..a510c18 100644
--- a/third_party/blink/renderer/core/css/css_property_id_templates.h
+++ b/third_party/blink/renderer/core/css/css_property_id_templates.h
@@ -11,10 +11,6 @@
 
 namespace WTF {
 template <>
-struct DefaultHash<blink::CSSPropertyID> {
-  typedef IntHash<unsigned> Hash;
-};
-template <>
 struct HashTraits<blink::CSSPropertyID>
     : GenericHashTraits<blink::CSSPropertyID> {
   static const bool kEmptyValueIsZero = true;
@@ -22,7 +18,7 @@
     slot = static_cast<blink::CSSPropertyID>(blink::numCSSPropertyIDs);
   }
   static bool IsDeletedValue(blink::CSSPropertyID value) {
-    return value == blink::numCSSPropertyIDs;
+    return static_cast<int>(value) == blink::numCSSPropertyIDs;
   }
 };
 }  // namespace WTF
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.cc b/third_party/blink/renderer/core/css/css_property_value_set.cc
index 324a8d4..430b35f 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set.cc
+++ b/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -127,8 +127,8 @@
                             const CSSValue&,
                             uint16_t id,
                             CSSPropertyID property_id) {
-  DCHECK_EQ(id, property_id);
-  bool result = metadata.Property().PropertyID() == id;
+  DCHECK_EQ(id, static_cast<uint16_t>(property_id));
+  bool result = static_cast<uint16_t>(metadata.Property().PropertyID()) == id;
 // Only enabled properties should be part of the style.
 #if DCHECK_IS_ON()
   DCHECK(!result ||
@@ -141,8 +141,8 @@
                             const CSSValue& value,
                             uint16_t id,
                             const AtomicString& custom_property_name) {
-  DCHECK_EQ(id, CSSPropertyVariable);
-  return metadata.Property().PropertyID() == id &&
+  DCHECK_EQ(id, static_cast<uint16_t>(CSSPropertyID::kVariable));
+  return static_cast<uint16_t>(metadata.Property().PropertyID()) == id &&
          To<CSSCustomPropertyDeclaration>(value).GetName() ==
              custom_property_name;
 }
diff --git a/third_party/blink/renderer/core/css/css_style_declaration.cc b/third_party/blink/renderer/core/css/css_style_declaration.cc
index d4c6148..de06ca8 100644
--- a/third_party/blink/renderer/core/css/css_style_declaration.cc
+++ b/third_party/blink/renderer/core/css/css_style_declaration.cc
@@ -141,7 +141,7 @@
     unresolved_property = CSSPropertyInvalid;
   map.insert(name, unresolved_property);
   DCHECK(
-      !unresolved_property ||
+      !isValidCSSPropertyID(unresolved_property) ||
       CSSProperty::Get(resolveCSSPropertyID(unresolved_property)).IsEnabled());
   return unresolved_property;
 }
@@ -153,7 +153,7 @@
   CSSPropertyID unresolved_property = CssPropertyInfo(name);
 
   // Do not handle non-property names.
-  if (!unresolved_property)
+  if (!isValidCSSPropertyID(unresolved_property))
     return String();
 
   return GetPropertyValueInternal(resolveCSSPropertyID(unresolved_property));
@@ -167,7 +167,7 @@
   if (!execution_context)
     return false;
   CSSPropertyID unresolved_property = CssPropertyInfo(name);
-  if (!unresolved_property)
+  if (!isValidCSSPropertyID(unresolved_property))
     return false;
   // We create the ExceptionState manually due to performance issues: adding
   // [RaisesException] to the IDL causes the bindings layer to expensively
@@ -192,7 +192,7 @@
   DEFINE_STATIC_LOCAL(PreAllocatedPropertyVector, property_names, ());
 
   if (property_names.IsEmpty()) {
-    for (int id = firstCSSProperty; id <= lastCSSProperty; ++id) {
+    for (int id = kIntFirstCSSProperty; id <= kIntLastCSSProperty; ++id) {
       CSSPropertyID property_id = static_cast<CSSPropertyID>(id);
       const CSSProperty& property_class =
           CSSProperty::Get(resolveCSSPropertyID(property_id));
@@ -213,7 +213,7 @@
 
 bool CSSStyleDeclaration::NamedPropertyQuery(const AtomicString& name,
                                              ExceptionState&) {
-  return CssPropertyInfo(name);
+  return isValidCSSPropertyID(CssPropertyInfo(name));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_fuzzer.cc b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_fuzzer.cc
index 7d1c0e3..004c9caf 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_fuzzer.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_fuzzer.cc
@@ -19,7 +19,7 @@
 
   const auto property_id =
       blink::convertToCSSPropertyID(provider.ConsumeIntegralInRange<int>(
-          blink::firstCSSProperty, blink::lastCSSProperty));
+          blink::kIntFirstCSSProperty, blink::kIntLastCSSProperty));
   const auto data_string = provider.ConsumeRemainingBytes();
 
   for (unsigned parser_mode = 0;
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
index fc35d1e..f0ff14ba 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -140,8 +140,6 @@
     const CSSPropertyValue& property = input[i];
     if (property.IsImportant() != important)
       continue;
-    const unsigned property_id_index = property.Id() - firstCSSProperty;
-
     if (property.Id() == CSSPropertyVariable) {
       const AtomicString& name =
           To<CSSCustomPropertyDeclaration>(property.Value())->GetName();
@@ -149,6 +147,7 @@
         continue;
       seen_custom_properties.insert(name);
     } else {
+      const unsigned property_id_index = GetCSSPropertyIDIndex(property.Id());
       if (seen_properties.test(property_id_index))
         continue;
       seen_properties.set(property_id_index);
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
index 8a57e98..189c4da2d 100644
--- a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
+++ b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
@@ -1744,7 +1744,7 @@
   int shorthand_index = 0;
   bool set_from_shorthand = false;
 
-  if (current_shorthand) {
+  if (isValidCSSPropertyID(current_shorthand)) {
     Vector<StylePropertyShorthand, 4> shorthands;
     getMatchingShorthandsForLonghand(resolved_property, &shorthands);
     set_from_shorthand = true;
diff --git a/third_party/blink/renderer/core/css/properties/longhands/clip_path_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/clip_path_custom.cc
index 01bc430..6fcb5f9 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/clip_path_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/clip_path_custom.cc
@@ -35,11 +35,11 @@
   if (ClipPathOperation* operation = style.ClipPath()) {
     if (operation->GetType() == ClipPathOperation::SHAPE) {
       return ValueForBasicShape(
-          style, ToShapeClipPathOperation(operation)->GetBasicShape());
+          style, To<ShapeClipPathOperation>(operation)->GetBasicShape());
     }
     if (operation->GetType() == ClipPathOperation::REFERENCE) {
       return cssvalue::CSSURIValue::Create(
-          ToReferenceClipPathOperation(operation)->Url());
+          To<ReferenceClipPathOperation>(operation)->Url());
     }
   }
   return CSSIdentifierValue::Create(CSSValueNone);
diff --git a/third_party/blink/renderer/core/css/resolver/css_property_priority.h b/third_party/blink/renderer/core/css/resolver/css_property_priority.h
index 0d90ca3..602c359 100644
--- a/third_party/blink/renderer/core/css/resolver/css_property_priority.h
+++ b/third_party/blink/renderer/core/css/resolver/css_property_priority.h
@@ -39,7 +39,7 @@
 template <>
 inline CSSPropertyID CSSPropertyPriorityData<kResolveVariables>::First() {
   static_assert(
-      CSSPropertyVariable == firstCSSProperty - 1,
+      static_cast<int>(CSSPropertyID::kVariable) == kIntFirstCSSProperty - 1,
       "CSSPropertyVariable should be directly before the first CSS property.");
   return CSSPropertyVariable;
 }
@@ -62,11 +62,13 @@
 inline CSSPropertyID
 CSSPropertyPriorityData<kAnimationPropertyPriority>::Last() {
   static_assert(
-      CSSPropertyTransitionTimingFunction == CSSPropertyAnimationDelay + 11,
+      static_cast<int>(CSSPropertyID::kTransitionTimingFunction) ==
+          static_cast<int>(CSSPropertyID::kAnimationDelay) + 11,
       "CSSPropertyTransitionTimingFunction should be the end of the high "
       "priority property range");
   static_assert(
-      CSSPropertyColor == CSSPropertyTransitionTimingFunction + 1,
+      static_cast<int>(CSSPropertyColor) ==
+          static_cast<int>(CSSPropertyTransitionTimingFunction) + 1,
       "CSSPropertyTransitionTimingFunction should be immediately before "
       "CSSPropertyColor");
   return CSSPropertyTransitionTimingFunction;
@@ -74,17 +76,21 @@
 
 template <>
 inline CSSPropertyID CSSPropertyPriorityData<kHighPropertyPriority>::First() {
-  static_assert(CSSPropertyColor == CSSPropertyTransitionTimingFunction + 1,
-                "CSSPropertyColor should be the first high priority property");
+  static_assert(
+      static_cast<int>(CSSPropertyID::kColor) ==
+          static_cast<int>(CSSPropertyID::kTransitionTimingFunction) + 1,
+      "CSSPropertyColor should be the first high priority property");
   return CSSPropertyColor;
 }
 
 template <>
 inline CSSPropertyID CSSPropertyPriorityData<kHighPropertyPriority>::Last() {
   static_assert(
-      CSSPropertyZoom == CSSPropertyColor + 22,
+      static_cast<int>(CSSPropertyID::kZoom) ==
+          static_cast<int>(CSSPropertyID::kColor) + 22,
       "CSSPropertyZoom should be the end of the high priority property range");
-  static_assert(CSSPropertyWritingMode == CSSPropertyZoom - 1,
+  static_assert(static_cast<int>(CSSPropertyID::kWritingMode) ==
+                    static_cast<int>(CSSPropertyID::kZoom) - 1,
                 "CSSPropertyWritingMode should be immediately before "
                 "CSSPropertyZoom");
   return CSSPropertyZoom;
@@ -93,7 +99,8 @@
 template <>
 inline CSSPropertyID CSSPropertyPriorityData<kLowPropertyPriority>::First() {
   static_assert(
-      CSSPropertyAlignContent == CSSPropertyZoom + 1,
+      static_cast<int>(CSSPropertyID::kAlignContent) ==
+          static_cast<int>(CSSPropertyID::kZoom) + 1,
       "CSSPropertyAlignContent should be the first low priority property");
   return CSSPropertyAlignContent;
 }
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder.cc b/third_party/blink/renderer/core/css/resolver/style_builder.cc
index 01010861..6127a05 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder.cc
@@ -86,7 +86,8 @@
   }
 
   DCHECK(!property.IsShorthand())
-      << "Shorthand property id = " << id << " wasn't expanded at parsing time";
+      << "Shorthand property id = " << static_cast<int>(id)
+      << " wasn't expanded at parsing time";
 
   bool is_inherit = state.ParentNode() && value.IsInheritedValue();
   bool is_initial = value.IsInitialValue() ||
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index 5420ffc..356a75e 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -1453,8 +1453,10 @@
   if (priority == kResolveVariables)
     return;
 
-  unsigned start_css_property = CSSPropertyPriorityData<priority>::First();
-  unsigned end_css_property = CSSPropertyPriorityData<priority>::Last();
+  unsigned start_css_property =
+      static_cast<unsigned>(CSSPropertyPriorityData<priority>::First());
+  unsigned end_css_property =
+      static_cast<unsigned>(CSSPropertyPriorityData<priority>::Last());
 
   for (unsigned i = start_css_property; i <= end_css_property; ++i) {
     CSSPropertyID property_id = static_cast<CSSPropertyID>(i);
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc
index 43eba69..86cb7a45 100644
--- a/third_party/blink/renderer/core/css/style_property_serializer.cc
+++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -65,7 +65,7 @@
     }
     if (!isCSSPropertyIDWithName(property.Id()))
       continue;
-    longhand_property_used_.set(property.Id() - firstCSSProperty);
+    longhand_property_used_.set(GetCSSPropertyIDIndex(property.Id()));
   }
 }
 
@@ -79,7 +79,7 @@
     const {
   if (!HasExpandedAllProperty())
     return property_set_->PropertyCount();
-  return lastCSSProperty - firstCSSProperty + 1;
+  return kIntLastCSSProperty - kIntFirstCSSProperty + 1;
 }
 
 StylePropertySerializer::PropertyValueForSerializer
@@ -90,7 +90,7 @@
         property_set_->PropertyAt(index));
 
   CSSPropertyID property_id =
-      static_cast<CSSPropertyID>(index + firstCSSProperty);
+      static_cast<CSSPropertyID>(index + kIntFirstCSSProperty);
   DCHECK(isCSSPropertyIDWithName(property_id));
   if (longhand_property_used_.test(index)) {
     int real_index = property_set_->FindPropertyIndex(property_id);
@@ -121,11 +121,11 @@
       return true;
     if (!isCSSPropertyIDWithName(property.Id()))
       return false;
-    return longhand_property_used_.test(property.Id() - firstCSSProperty);
+    return longhand_property_used_.test(GetCSSPropertyIDIndex(property.Id()));
   }
 
   CSSPropertyID property_id =
-      static_cast<CSSPropertyID>(index + firstCSSProperty);
+      static_cast<CSSPropertyID>(index + kIntFirstCSSProperty);
   DCHECK(isCSSPropertyIDWithName(property_id));
   const CSSProperty& property_class =
       CSSProperty::Get(resolveCSSPropertyID(property_id));
@@ -150,7 +150,7 @@
   CSSPropertyID property_id = property.PropertyID();
   if (!HasExpandedAllProperty())
     return property_set_->FindPropertyIndex(property_id);
-  return property_id - firstCSSProperty;
+  return GetCSSPropertyIDIndex(property_id);
 }
 
 const CSSValue*
@@ -245,7 +245,7 @@
       default:
         break;
     }
-    if (longhand_serialized.test(property_id - firstCSSProperty))
+    if (longhand_serialized.test(GetCSSPropertyIDIndex(property_id)))
       continue;
 
     Vector<StylePropertyShorthand, 4> shorthands;
@@ -258,7 +258,7 @@
         continue;
 
       CSSPropertyID shorthand_property = shorthand.id();
-      int shorthand_property_index = shorthand_property - firstCSSProperty;
+      int shorthand_property_index = GetCSSPropertyIDIndex(shorthand_property);
       // We already tried serializing as this shorthand
       if (shorthand_appeared.test(shorthand_property_index))
         continue;
@@ -266,8 +266,8 @@
       shorthand_appeared.set(shorthand_property_index);
       bool serialized_other_longhand = false;
       for (unsigned i = 0; i < shorthand.length(); i++) {
-        if (longhand_serialized.test(shorthand.properties()[i]->PropertyID() -
-                                     firstCSSProperty)) {
+        if (longhand_serialized.test(GetCSSPropertyIDIndex(
+                shorthand.properties()[i]->PropertyID()))) {
           serialized_other_longhand = true;
           break;
         }
@@ -284,8 +284,8 @@
                                     num_decls++));
       serialized_as_shorthand = true;
       for (unsigned i = 0; i < shorthand.length(); i++) {
-        longhand_serialized.set(shorthand.properties()[i]->PropertyID() -
-                                firstCSSProperty);
+        longhand_serialized.set(
+            GetCSSPropertyIDIndex(shorthand.properties()[i]->PropertyID()));
       }
       break;
     }
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index b8cbfde..a7372bf 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -6233,8 +6233,8 @@
   // For a main frame, get inherited feature policy from the opener if any.
   const FeaturePolicy::FeatureState* opener_feature_state = nullptr;
   if (frame_ && frame_->IsMainFrame() &&
-      !frame_->Client()->GetOpenerFeatureState().empty()) {
-    opener_feature_state = &frame_->Client()->GetOpenerFeatureState();
+      !frame_->OpenerFeatureState().empty()) {
+    opener_feature_state = &frame_->OpenerFeatureState();
   }
 
   InitializeFeaturePolicy(declared_policy, GetOwnerContainerPolicy(),
@@ -6735,8 +6735,13 @@
     return;
   }
 
-  if (!frame_)
+  if (!frame_) {
+    if (imports_controller_) {
+      imports_controller_->Master()->GetFrame()->Console().AddMessage(
+          console_message);
+    }
     return;
+  }
 
   if (console_message->Location()->IsUnknown()) {
     // TODO(dgozman): capture correct location at call places instead.
diff --git a/third_party/blink/renderer/core/dom/events/event_path.cc b/third_party/blink/renderer/core/dom/events/event_path.cc
index b465753..f199fc35 100644
--- a/third_party/blink/renderer/core/dom/events/event_path.cc
+++ b/third_party/blink/renderer/core/dom/events/event_path.cc
@@ -407,13 +407,13 @@
 #if DCHECK_IS_ON()
 void EventPath::CheckReachability(TreeScope& tree_scope,
                                   TouchList& touch_list) {
-  for (wtf_size_t i = 0; i < touch_list.length(); ++i)
+  for (wtf_size_t i = 0; i < touch_list.length(); ++i) {
     DCHECK(touch_list.item(i)
                ->target()
                ->ToNode()
                ->GetTreeScope()
-               .IsInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(
-                   tree_scope));
+               .IsInclusiveAncestorTreeScopeOf(tree_scope));
+  }
 }
 #endif
 
diff --git a/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h b/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h
index 18b7c455..fed4311 100644
--- a/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h
+++ b/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h
@@ -107,10 +107,8 @@
   // FIXME: Checks also for SVG elements.
   if (target.ToNode()->IsSVGElement())
     return;
-  DCHECK(target.ToNode()
-             ->GetTreeScope()
-             .IsInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(
-                 GetTreeScope()));
+  DCHECK(target.ToNode()->GetTreeScope().IsInclusiveAncestorTreeScopeOf(
+      GetTreeScope()));
 }
 #else
 inline void TreeScopeEventContext::CheckReachableNode(EventTarget&) {}
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index e17c071..c4a7b95b 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -2683,7 +2683,7 @@
     if (event.HasInterface(event_interface_names::kTextEvent)) {
       if (LocalFrame* frame = GetDocument().GetFrame()) {
         frame->GetEventHandler().DefaultTextInputEventHandler(
-            ToTextEvent(&event));
+            To<TextEvent>(&event));
       }
     }
   } else if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled() &&
diff --git a/third_party/blink/renderer/core/dom/tree_scope.cc b/third_party/blink/renderer/core/dom/tree_scope.cc
index 3f6c670..88898d2 100644
--- a/third_party/blink/renderer/core/dom/tree_scope.cc
+++ b/third_party/blink/renderer/core/dom/tree_scope.cc
@@ -82,8 +82,7 @@
   selection_ = nullptr;
 }
 
-bool TreeScope::IsInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(
-    const TreeScope& scope) const {
+bool TreeScope::IsInclusiveAncestorTreeScopeOf(const TreeScope& scope) const {
   for (const TreeScope* current = &scope; current;
        current = current->ParentTreeScope()) {
     if (current == this)
diff --git a/third_party/blink/renderer/core/dom/tree_scope.h b/third_party/blink/renderer/core/dom/tree_scope.h
index 19b85211..b4b192c98 100644
--- a/third_party/blink/renderer/core/dom/tree_scope.h
+++ b/third_party/blink/renderer/core/dom/tree_scope.h
@@ -64,8 +64,7 @@
 
   TreeScope* ParentTreeScope() const { return parent_tree_scope_; }
 
-  bool IsInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(
-      const TreeScope&) const;
+  bool IsInclusiveAncestorTreeScopeOf(const TreeScope&) const;
 
   Element* AdjustedFocusedElement() const;
   // Finds a retargeted element to the given argument, when the retargeted
diff --git a/third_party/blink/renderer/core/events/text_event.h b/third_party/blink/renderer/core/events/text_event.h
index 2ba8b94..8674390 100644
--- a/third_party/blink/renderer/core/events/text_event.h
+++ b/third_party/blink/renderer/core/events/text_event.h
@@ -103,11 +103,10 @@
          event.HasInterface(event_interface_names::kTextEvent);
 }
 
-DEFINE_TYPE_CASTS(TextEvent,
-                  Event,
-                  event,
-                  IsTextEvent(*event),
-                  IsTextEvent(event));
+template <>
+struct DowncastTraits<TextEvent> {
+  static bool AllowFrom(const Event& event) { return IsTextEvent(event); }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
index 8fdcedf..3b6fd1a 100644
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -1234,12 +1234,6 @@
   return web_frame_->UsePrintingLayout();
 }
 
-const FeaturePolicy::FeatureState& LocalFrameClientImpl::GetOpenerFeatureState()
-    const {
-  DCHECK(web_frame_->GetFrame()->IsMainFrame());
-  return web_frame_->OpenerFeatureState();
-}
-
 STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kFollow,
                    WebLocalFrameClient::CrossOriginRedirects::kFollow);
 STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kNavigate,
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
index 2f924f8..8a55e64 100644
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -322,8 +322,6 @@
 
   bool UsePrintingLayout() const override;
 
-  const FeaturePolicy::FeatureState& GetOpenerFeatureState() const override;
-
  private:
   struct DocumentInterfaceBrokerForwarderTraits {
     using Interface = mojom::blink::DocumentInterfaceBroker;
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
index 005e3df..49fee9b0 100644
--- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -249,9 +249,9 @@
     const FeaturePolicy::FeatureState& opener_feature_state) {
   feature_policy_header_ = parsed_header;
   if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
-    DCHECK(opener_feature_state.empty() || GetFrame()->IsMainFrame());
-    if (opener_feature_state_.empty()) {
-      opener_feature_state_ = opener_feature_state;
+    DCHECK(opener_feature_state.empty() || frame_->IsMainFrame());
+    if (frame_->OpenerFeatureState().empty()) {
+      frame_->SetOpenerFeatureState(opener_feature_state);
     }
   }
   ApplyReplicatedFeaturePolicyHeader();
@@ -267,9 +267,11 @@
   ParsedFeaturePolicy container_policy;
   if (GetFrame()->Owner())
     container_policy = GetFrame()->Owner()->ContainerPolicy();
+  const FeaturePolicy::FeatureState& opener_feature_state =
+      frame_->OpenerFeatureState();
   GetFrame()->GetSecurityContext()->InitializeFeaturePolicy(
       feature_policy_header_, container_policy, parent_feature_policy,
-      opener_feature_state_.empty() ? nullptr : &opener_feature_state_);
+      opener_feature_state.empty() ? nullptr : &opener_feature_state);
 }
 
 void WebRemoteFrameImpl::AddReplicatedContentSecurityPolicyHeader(
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
index c2aeec9c..5261407 100644
--- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
+++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
@@ -106,10 +106,6 @@
 
   WebRemoteFrameClient* Client() const { return client_; }
 
-  const FeaturePolicy::FeatureState& OpenerFeatureState() const {
-    return opener_feature_state_;
-  }
-
   static WebRemoteFrameImpl* FromFrame(RemoteFrame&);
 
   void Trace(blink::Visitor*);
@@ -132,10 +128,6 @@
   Member<RemoteFrameClientImpl> frame_client_;
   Member<RemoteFrame> frame_;
 
-  // Feature policy state inherited from an opener. It is always empty for child
-  // frames.
-  FeaturePolicy::FeatureState opener_feature_state_;
-
   ParsedFeaturePolicy feature_policy_header_;
 
   // Oilpan: WebRemoteFrameImpl must remain alive until close() is called.
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc
index 480f77a..4fbeb716 100644
--- a/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -649,12 +649,14 @@
 
 void Deprecation::Suppress(CSSPropertyID unresolved_property) {
   DCHECK(isCSSPropertyIDWithName(unresolved_property));
-  css_property_deprecation_bits_.QuickSet(unresolved_property);
+  css_property_deprecation_bits_.QuickSet(
+      static_cast<int>(unresolved_property));
 }
 
 bool Deprecation::IsSuppressed(CSSPropertyID unresolved_property) {
   DCHECK(isCSSPropertyIDWithName(unresolved_property));
-  return css_property_deprecation_bits_.QuickGet(unresolved_property);
+  return css_property_deprecation_bits_.QuickGet(
+      static_cast<int>(unresolved_property));
 }
 
 void Deprecation::SetReported(WebFeature feature) {
diff --git a/third_party/blink/renderer/core/frame/frame.h b/third_party/blink/renderer/core/frame/frame.h
index bd8bdcc..a777236 100644
--- a/third_party/blink/renderer/core/frame/frame.h
+++ b/third_party/blink/renderer/core/frame/frame.h
@@ -32,6 +32,7 @@
 #include "base/debug/stack_trace.h"
 #include "base/optional.h"
 #include "base/unguessable_token.h"
+#include "third_party/blink/public/common/feature_policy/feature_policy.h"
 #include "third_party/blink/public/common/frame/user_activation_state.h"
 #include "third_party/blink/public/common/frame/user_activation_update_source.h"
 #include "third_party/blink/public/web/web_frame_load_type.h"
@@ -228,6 +229,25 @@
     return navigation_rate_limiter_;
   }
 
+  // Called to get the opener's FeatureState if any. This works with disowned
+  // openers, i.e., even if WebFrame::Opener() is nullptr, there could be a
+  // non-empty feature state which is taken from the the original opener of the
+  // frame. This is similar to how sandbox flags are propagated to the opened
+  // new browsing contexts.
+  const FeaturePolicy::FeatureState& OpenerFeatureState() const {
+    return opener_feature_state_;
+  }
+
+  // Sets the opener's FeatureState for the main frame. Once a non-empty
+  // |opener_feature_state| is set, it can no longer be modified (due to the
+  // fact that the original opener which passed down the FeatureState cannot be
+  // modified either).
+  void SetOpenerFeatureState(const FeaturePolicy::FeatureState& state) {
+    DCHECK(state.empty() || IsMainFrame());
+    DCHECK(opener_feature_state_.empty());
+    opener_feature_state_ = state;
+  }
+
  protected:
   Frame(FrameClient*, Page&, FrameOwner*, WindowProxyManager*);
 
@@ -267,6 +287,10 @@
 
   NavigationRateLimiter navigation_rate_limiter_;
 
+  // Feature policy state inherited from an opener. It is always empty for child
+  // frames.
+  FeaturePolicy::FeatureState opener_feature_state_;
+
   // TODO(sashab): Investigate if this can be represented with m_lifecycle.
   bool is_loading_;
   base::UnguessableToken devtools_frame_token_;
diff --git a/third_party/blink/renderer/core/frame/frame_console.cc b/third_party/blink/renderer/core/frame/frame_console.cc
index baee3d2..6b76fe22 100644
--- a/third_party/blink/renderer/core/frame/frame_console.cc
+++ b/third_party/blink/renderer/core/frame/frame_console.cc
@@ -128,7 +128,6 @@
 
 void FrameConsole::Trace(blink::Visitor* visitor) {
   visitor->Trace(frame_);
-  ConsoleLoggerImplBase::Trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/frame_console.h b/third_party/blink/renderer/core/frame/frame_console.h
index 6555567..419f3018 100644
--- a/third_party/blink/renderer/core/frame/frame_console.h
+++ b/third_party/blink/renderer/core/frame/frame_console.h
@@ -31,7 +31,7 @@
 
 #include "third_party/blink/public/mojom/devtools/console_message.mojom-shared.h"
 #include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/loader/console_logger_impl_base.h"
+#include "third_party/blink/renderer/core/inspector/console_types.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -50,10 +50,7 @@
 // around ChromeClient calls and the way that Blink core/ can add messages to
 // the console.
 class CORE_EXPORT FrameConsole final
-    : public GarbageCollectedFinalized<FrameConsole>,
-      public ConsoleLoggerImplBase {
-  USING_GARBAGE_COLLECTED_MIXIN(FrameConsole);
-
+    : public GarbageCollectedFinalized<FrameConsole> {
  public:
   static FrameConsole* Create(LocalFrame& frame) {
     return MakeGarbageCollected<FrameConsole>(frame);
@@ -61,10 +58,6 @@
 
   explicit FrameConsole(LocalFrame&);
 
-  // ConsoleLoggerImplBase implementation.
-  void AddConsoleMessage(ConsoleMessage* message) override {
-    AddMessage(message);
-  }
   void AddMessage(ConsoleMessage*);
 
   bool AddMessageToStorage(ConsoleMessage*);
@@ -81,7 +74,7 @@
                       uint64_t request_identifier,
                       const ResourceError&);
 
-  void Trace(blink::Visitor*) override;
+  void Trace(blink::Visitor*);
 
  private:
   Member<LocalFrame> frame_;
diff --git a/third_party/blink/renderer/core/frame/link_highlights.cc b/third_party/blink/renderer/core/frame/link_highlights.cc
index 1ec0276..4679fe2 100644
--- a/third_party/blink/renderer/core/frame/link_highlights.cc
+++ b/third_party/blink/renderer/core/frame/link_highlights.cc
@@ -97,7 +97,7 @@
     cc::AnimationHost& animation_host) {
   animation_host_ = &animation_host;
   if (Platform::Current()->IsThreadedAnimationEnabled()) {
-    timeline_ = CompositorAnimationTimeline::Create();
+    timeline_ = std::make_unique<CompositorAnimationTimeline>();
     animation_host_->AddAnimationTimeline(timeline_->GetAnimationTimeline());
   }
 }
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index 22df61bd..c801d2a 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -505,13 +505,6 @@
   // Returns whether we are associated with a print context who suggests to use
   // printing layout.
   virtual bool UsePrintingLayout() const { return false; }
-
-  // Called to get the FeatureState inherited from an opener if any. This works
-  // with disowned openers, i.e., even if Frame::Opener() is nullptr, there
-  // could be a non-empty feature state which is taken from the the original
-  // opener of the frame. This is similar to how sandbox flags are propagated to
-  // the opened new browsing contexts.
-  virtual const FeaturePolicy::FeatureState& GetOpenerFeatureState() const = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index c2c4fb3..3ae0693 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -1612,12 +1612,12 @@
     WebLocalFrameClient* client,
     InterfaceRegistry* interface_registry,
     mojo::ScopedMessagePipeHandle document_interface_broker_handle,
-    WebRemoteFrame* old_web_frame,
+    WebFrame* previous_frame,
     WebSandboxFlags flags,
     ParsedFeaturePolicy container_policy) {
   return WebLocalFrameImpl::CreateProvisional(
       client, interface_registry, std::move(document_interface_broker_handle),
-      old_web_frame, flags, container_policy);
+      previous_frame, flags, container_policy);
 }
 
 WebLocalFrameImpl* WebLocalFrameImpl::Create(
@@ -1646,11 +1646,11 @@
       WebTreeScopeType::kDocument, client, interface_registry,
       std::move(document_interface_broker_handle));
   frame->SetOpener(opener);
-  if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled())
-    frame->opener_feature_state_ = opener_feature_state;
   Page& page = *static_cast<WebViewImpl*>(web_view)->GetPage();
   DCHECK(!page.MainFrame());
   frame->InitializeCoreFrame(page, nullptr, name);
+  if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled())
+    frame->GetFrame()->SetOpenerFeatureState(opener_feature_state);
   // Can't force sandbox flags until there's a core frame.
   frame->GetFrame()->Loader().ForceSandboxFlags(
       static_cast<SandboxFlags>(sandbox_flags));
@@ -1661,16 +1661,16 @@
     WebLocalFrameClient* client,
     blink::InterfaceRegistry* interface_registry,
     mojo::ScopedMessagePipeHandle document_interface_broker_handle,
-    WebRemoteFrame* old_web_frame,
+    WebFrame* previous_web_frame,
     WebSandboxFlags flags,
     ParsedFeaturePolicy container_policy) {
   DCHECK(client);
   WebLocalFrameImpl* web_frame = MakeGarbageCollected<WebLocalFrameImpl>(
-      old_web_frame, client, interface_registry,
+      previous_web_frame, client, interface_registry,
       std::move(document_interface_broker_handle));
-  Frame* old_frame = ToWebRemoteFrameImpl(old_web_frame)->GetFrame();
-  web_frame->SetParent(old_web_frame->Parent());
-  web_frame->SetOpener(old_web_frame->Opener());
+  Frame* previous_frame = ToCoreFrame(*previous_web_frame);
+  web_frame->SetParent(previous_web_frame->Parent());
+  web_frame->SetOpener(previous_web_frame->Opener());
   // Note: this *always* temporarily sets a frame owner, even for main frames!
   // When a core Frame is created with no owner, it attempts to set itself as
   // the main frame of the Page. However, this is a provisional frame, and may
@@ -1682,12 +1682,12 @@
   // unscriptable. Once the provisional frame gets properly attached and is
   // observable, it will have the real FrameOwner, and any subsequent real
   // documents will correctly inherit sandbox flags from the owner.
-  web_frame->InitializeCoreFrame(*old_frame->GetPage(),
+  web_frame->InitializeCoreFrame(*previous_frame->GetPage(),
                                  DummyFrameOwner::Create(),
-                                 old_frame->Tree().GetName());
+                                 previous_frame->Tree().GetName());
 
   LocalFrame* new_frame = web_frame->GetFrame();
-  new_frame->SetOwner(old_frame->Owner());
+  new_frame->SetOwner(previous_frame->Owner());
   if (auto* remote_frame_owner =
           DynamicTo<RemoteFrameOwner>(new_frame->Owner())) {
     remote_frame_owner->SetSandboxFlags(static_cast<SandboxFlags>(flags));
@@ -1699,8 +1699,7 @@
     new_frame->Loader().ForceSandboxFlags(static_cast<SandboxFlags>(flags));
     // If there is an opener (even disowned), the opener policies must be
     // inherited the same way as sandbox flag.
-    web_frame->opener_feature_state_ =
-        ToWebRemoteFrameImpl(old_web_frame)->OpenerFeatureState();
+    new_frame->SetOpenerFeatureState(previous_frame->OpenerFeatureState());
   }
 
   return web_frame;
@@ -1740,11 +1739,11 @@
 }
 
 WebLocalFrameImpl::WebLocalFrameImpl(
-    WebRemoteFrame* old_web_frame,
+    WebFrame* previous_web_frame,
     WebLocalFrameClient* client,
     blink::InterfaceRegistry* interface_registry,
     mojo::ScopedMessagePipeHandle document_interface_broker_handle)
-    : WebLocalFrameImpl(old_web_frame->InShadowTree()
+    : WebLocalFrameImpl(previous_web_frame->InShadowTree()
                             ? WebTreeScopeType::kShadow
                             : WebTreeScopeType::kDocument,
                         client,
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index abe78f09..84d256c 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -350,7 +350,7 @@
   static WebLocalFrameImpl* CreateProvisional(WebLocalFrameClient*,
                                               InterfaceRegistry*,
                                               mojo::ScopedMessagePipeHandle,
-                                              WebRemoteFrame*,
+                                              WebFrame*,
                                               WebSandboxFlags,
                                               ParsedFeaturePolicy);
 
@@ -358,7 +358,7 @@
                     WebLocalFrameClient*,
                     blink::InterfaceRegistry*,
                     mojo::ScopedMessagePipeHandle);
-  WebLocalFrameImpl(WebRemoteFrame*,
+  WebLocalFrameImpl(WebFrame*,
                     WebLocalFrameClient*,
                     blink::InterfaceRegistry*,
                     mojo::ScopedMessagePipeHandle);
@@ -439,10 +439,6 @@
   // Returns true if our print context suggests using printing layout.
   bool UsePrintingLayout() const;
 
-  const FeaturePolicy::FeatureState& OpenerFeatureState() const {
-    return opener_feature_state_;
-  }
-
   virtual void Trace(blink::Visitor*);
 
  private:
@@ -505,10 +501,6 @@
 
   WebSpellCheckPanelHostClient* spell_check_panel_host_client_;
 
-  // Feature policy state inherited from an opener. It is always empty for child
-  // frames.
-  FeaturePolicy::FeatureState opener_feature_state_;
-
   // Oilpan: WebLocalFrameImpl must remain alive until close() is called.
   // Accomplish that by keeping a self-referential Persistent<>. It is
   // cleared upon close().
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
index 26b1e5b..7e99900e 100644
--- a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -264,7 +264,7 @@
 bool TextFieldInputType::ShouldSubmitImplicitly(const Event& event) {
   return (event.type() == event_type_names::kTextInput &&
           event.HasInterface(event_interface_names::kTextEvent) &&
-          ToTextEvent(event).data() == "\n") ||
+          To<TextEvent>(event).data() == "\n") ||
          InputTypeView::ShouldSubmitImplicitly(event);
 }
 
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.cc b/third_party/blink/renderer/core/html/html_anchor_element.cc
index df357787..593c027 100644
--- a/third_party/blink/renderer/core/html/html_anchor_element.cc
+++ b/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -25,6 +25,8 @@
 #include "third_party/blink/renderer/core/html/html_anchor_element.h"
 
 #include "base/metrics/histogram_macros.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_prescient_networking.h"
 #include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -42,7 +44,6 @@
 #include "third_party/blink/renderer/core/layout/layout_box.h"
 #include "third_party/blink/renderer/core/loader/frame_load_request.h"
 #include "third_party/blink/renderer/core/loader/navigation_policy.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/core/loader/ping_loader.h"
 #include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
@@ -209,8 +210,12 @@
       if (GetDocument().IsDNSPrefetchEnabled()) {
         if (ProtocolIs(parsed_url, "http") || ProtocolIs(parsed_url, "https") ||
             parsed_url.StartsWith("//")) {
-          NetworkHintsInterfaceImpl().DnsPrefetchHost(
-              GetDocument().CompleteURL(parsed_url).Host());
+          WebPrescientNetworking* web_prescient_networking =
+              Platform::Current()->PrescientNetworking();
+          if (web_prescient_networking) {
+            web_prescient_networking->PrefetchDNS(
+                GetDocument().CompleteURL(parsed_url).Host());
+          }
         }
       }
     }
diff --git a/third_party/blink/renderer/core/html/html_link_element.cc b/third_party/blink/renderer/core/html/html_link_element.cc
index 98cf565..aae9f43b 100644
--- a/third_party/blink/renderer/core/html/html_link_element.cc
+++ b/third_party/blink/renderer/core/html/html_link_element.cc
@@ -27,6 +27,7 @@
 
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/public/platform/web_icon_sizes_parser.h"
+#include "third_party/blink/public/platform/web_prescient_networking.h"
 #include "third_party/blink/public/platform/web_size.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
 #include "third_party/blink/renderer/core/core_initializer.h"
@@ -42,7 +43,6 @@
 #include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/loader/link_loader.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
 #include "third_party/blink/renderer/platform/weborigin/security_policy.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -162,8 +162,7 @@
 }
 
 bool HTMLLinkElement::LoadLink(const LinkLoadParameters& params) {
-  return link_loader_->LoadLink(params, GetDocument(),
-                                NetworkHintsInterfaceImpl());
+  return link_loader_->LoadLink(params, GetDocument());
 }
 
 void HTMLLinkElement::LoadStylesheet(const LinkLoadParameters& params,
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc
index 98d1c8c2..5fb686f 100644
--- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc
+++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc
@@ -32,8 +32,7 @@
 }
 
 class MockResourcePreloader : public ResourcePreloader {
-  void Preload(std::unique_ptr<PreloadRequest>,
-               const NetworkHintsInterface&) override {}
+  void Preload(std::unique_ptr<PreloadRequest>) override {}
 };
 
 int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
index cfbc88c..929efa6 100644
--- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
+++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -200,8 +200,7 @@
   }
 
  protected:
-  void Preload(std::unique_ptr<PreloadRequest> preload_request,
-               const NetworkHintsInterface&) override {
+  void Preload(std::unique_ptr<PreloadRequest> preload_request) override {
     preload_request_ = std::move(preload_request);
   }
 
diff --git a/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc b/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc
index 074049f..69a9792 100644
--- a/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc
+++ b/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc
@@ -26,6 +26,8 @@
 #include "third_party/blink/renderer/core/html/parser/html_resource_preloader.h"
 
 #include <memory>
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_prescient_networking.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/deprecation.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
@@ -46,22 +48,23 @@
   visitor->Trace(document_);
 }
 
-static void PreconnectHost(
-    PreloadRequest* request,
-    const NetworkHintsInterface& network_hints_interface) {
+static void PreconnectHost(PreloadRequest* request) {
   DCHECK(request);
   DCHECK(request->IsPreconnect());
   KURL host(request->BaseURL(), request->ResourceURL());
   if (!host.IsValid() || !host.ProtocolIsInHTTPFamily())
     return;
-  network_hints_interface.PreconnectHost(host, request->CrossOrigin());
+  WebPrescientNetworking* web_prescient_networking =
+      Platform::Current()->PrescientNetworking();
+  if (web_prescient_networking) {
+    web_prescient_networking->Preconnect(
+        host, request->CrossOrigin() != kCrossOriginAttributeAnonymous);
+  }
 }
 
-void HTMLResourcePreloader::Preload(
-    std::unique_ptr<PreloadRequest> preload,
-    const NetworkHintsInterface& network_hints_interface) {
+void HTMLResourcePreloader::Preload(std::unique_ptr<PreloadRequest> preload) {
   if (preload->IsPreconnect()) {
-    PreconnectHost(preload.get(), network_hints_interface);
+    PreconnectHost(preload.get());
     return;
   }
   // TODO(yoichio): Should preload if document is imported.
diff --git a/third_party/blink/renderer/core/html/parser/html_resource_preloader.h b/third_party/blink/renderer/core/html/parser/html_resource_preloader.h
index 3dad651..de995b53 100644
--- a/third_party/blink/renderer/core/html/parser/html_resource_preloader.h
+++ b/third_party/blink/renderer/core/html/parser/html_resource_preloader.h
@@ -31,7 +31,6 @@
 #include "base/macros.h"
 #include "third_party/blink/renderer/core/html/parser/preload_request.h"
 #include "third_party/blink/renderer/core/html/parser/resource_preloader.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/wtf/text/text_position.h"
 #include "third_party/blink/renderer/platform/wtf/time.h"
@@ -53,8 +52,7 @@
   void Trace(Visitor*);
 
  protected:
-  void Preload(std::unique_ptr<PreloadRequest>,
-               const NetworkHintsInterface&) override;
+  void Preload(std::unique_ptr<PreloadRequest>) override;
 
  private:
   Member<Document> document_;
diff --git a/third_party/blink/renderer/core/html/parser/html_resource_preloader_test.cc b/third_party/blink/renderer/core/html/parser/html_resource_preloader_test.cc
index 66cffeb..bdab3f7 100644
--- a/third_party/blink/renderer/core/html/parser/html_resource_preloader_test.cc
+++ b/third_party/blink/renderer/core/html/parser/html_resource_preloader_test.cc
@@ -5,7 +5,9 @@
 #include "third_party/blink/renderer/core/html/parser/html_resource_preloader.h"
 
 #include <memory>
+#include <utility>
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/web_prescient_networking.h"
 #include "third_party/blink/renderer/core/html/parser/preload_request.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 
@@ -18,27 +20,40 @@
   bool is_https;
 };
 
-class PreloaderNetworkHintsMock : public NetworkHintsInterface {
+class PreloaderNetworkHintsMock : public WebPrescientNetworking {
  public:
   PreloaderNetworkHintsMock() : did_preconnect_(false) {}
 
-  void DnsPrefetchHost(const String& host) const override {}
-  void PreconnectHost(
-      const KURL& host,
-      const CrossOriginAttributeValue cross_origin) const override {
+  void PrefetchDNS(const WebString& hostname) override {}
+  void Preconnect(const WebURL& url, const bool allow_credentials) override {
     did_preconnect_ = true;
-    is_https_ = host.ProtocolIs("https");
-    is_cross_origin_ = (cross_origin == kCrossOriginAttributeAnonymous);
+    is_https_ = url.ProtocolIs("https");
+    allow_credentials_ = allow_credentials;
   }
 
   bool DidPreconnect() { return did_preconnect_; }
   bool IsHTTPS() { return is_https_; }
-  bool IsCrossOrigin() { return is_cross_origin_; }
+  bool AllowCredentials() { return allow_credentials_; }
 
  private:
   mutable bool did_preconnect_;
   mutable bool is_https_;
-  mutable bool is_cross_origin_;
+  mutable bool allow_credentials_;
+};
+
+class TestingPlatformSupportWithPreloaderNetworkHintsMock
+    : public TestingPlatformSupport {
+ public:
+  PreloaderNetworkHintsMock& GetMockPrescientNetworking() {
+    return mock_prescient_networking_;
+  }
+
+ private:
+  WebPrescientNetworking* PrescientNetworking() override {
+    return &mock_prescient_networking_;
+  }
+
+  PreloaderNetworkHintsMock mock_prescient_networking_;
 };
 
 class HTMLResourcePreloaderTest : public PageTestBase {
@@ -48,7 +63,6 @@
   void Test(HTMLResourcePreconnectTestCase test_case) {
     // TODO(yoav): Need a mock loader here to verify things are happenning
     // beyond preconnect.
-    PreloaderNetworkHintsMock network_hints;
     auto preload_request = PreloadRequest::CreateIfNeeded(
         String(), TextPosition(), test_case.url, KURL(test_case.base_url),
         ResourceType::kImage, network::mojom::ReferrerPolicy(),
@@ -60,11 +74,16 @@
       preload_request->SetCrossOrigin(kCrossOriginAttributeAnonymous);
     HTMLResourcePreloader* preloader =
         HTMLResourcePreloader::Create(GetDocument());
-    preloader->Preload(std::move(preload_request), network_hints);
-    ASSERT_TRUE(network_hints.DidPreconnect());
-    ASSERT_EQ(test_case.is_cors, network_hints.IsCrossOrigin());
-    ASSERT_EQ(test_case.is_https, network_hints.IsHTTPS());
+    preloader->Preload(std::move(preload_request));
+    ASSERT_TRUE(platform_->GetMockPrescientNetworking().DidPreconnect());
+    ASSERT_NE(test_case.is_cors,
+              platform_->GetMockPrescientNetworking().AllowCredentials());
+    ASSERT_EQ(test_case.is_https,
+              platform_->GetMockPrescientNetworking().IsHTTPS());
   }
+  ScopedTestingPlatformSupport<
+      TestingPlatformSupportWithPreloaderNetworkHintsMock>
+      platform_;
 };
 
 TEST_F(HTMLResourcePreloaderTest, testPreconnect) {
diff --git a/third_party/blink/renderer/core/html/parser/resource_preloader.cc b/third_party/blink/renderer/core/html/parser/resource_preloader.cc
index 5d51a47..9222271 100644
--- a/third_party/blink/renderer/core/html/parser/resource_preloader.cc
+++ b/third_party/blink/renderer/core/html/parser/resource_preloader.cc
@@ -3,18 +3,18 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/core/html/parser/resource_preloader.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
+
+#include <utility>
 
 namespace blink {
 
 void ResourcePreloader::TakeAndPreload(PreloadRequestStream& r) {
   PreloadRequestStream requests;
-  NetworkHintsInterfaceImpl network_hints_interface;
   requests.swap(r);
 
   for (PreloadRequestStream::iterator it = requests.begin();
        it != requests.end(); ++it)
-    Preload(std::move(*it), network_hints_interface);
+    Preload(std::move(*it));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/parser/resource_preloader.h b/third_party/blink/renderer/core/html/parser/resource_preloader.h
index ec5b9301..cbeb937 100644
--- a/third_party/blink/renderer/core/html/parser/resource_preloader.h
+++ b/third_party/blink/renderer/core/html/parser/resource_preloader.h
@@ -11,15 +11,12 @@
 
 namespace blink {
 
-class NetworkHintsInterface;
-
 class CORE_EXPORT ResourcePreloader {
  public:
   virtual void TakeAndPreload(PreloadRequestStream&);
 
  private:
-  virtual void Preload(std::unique_ptr<PreloadRequest>,
-                       const NetworkHintsInterface&) = 0;
+  virtual void Preload(std::unique_ptr<PreloadRequest>) = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
index 996a36b72..0d1a189 100644
--- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -1129,7 +1129,7 @@
   CSSComputedStyleDeclaration* computed_style_info =
       CSSComputedStyleDeclaration::Create(node, true);
   *style = protocol::Array<protocol::CSS::CSSComputedStyleProperty>::create();
-  for (int id = firstCSSProperty; id <= lastCSSProperty; ++id) {
+  for (int id = kIntFirstCSSProperty; id <= kIntLastCSSProperty; ++id) {
     CSSPropertyID property_id = static_cast<CSSPropertyID>(id);
     const CSSProperty& property_class =
         CSSProperty::Get(resolveCSSPropertyID(property_id));
@@ -2187,7 +2187,7 @@
     return Response::Error("Elements is pseudo");
 
   CSSPropertyID property = cssPropertyID(property_name);
-  if (!property)
+  if (!isValidCSSPropertyID(property))
     return Response::Error("Invalid property name");
 
   Document* owner_document = element->ownerDocument();
diff --git a/third_party/blink/renderer/core/layout/layout_scrollbar.h b/third_party/blink/renderer/core/layout/layout_scrollbar.h
index da7effa..26a8b47 100644
--- a/third_party/blink/renderer/core/layout/layout_scrollbar.h
+++ b/third_party/blink/renderer/core/layout/layout_scrollbar.h
@@ -29,6 +29,7 @@
 #include "third_party/blink/renderer/core/scroll/scrollbar.h"
 #include "third_party/blink/renderer/core/style/computed_style_constants.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 
 namespace blink {
@@ -104,11 +105,12 @@
   HashMap<unsigned, LayoutScrollbarPart*> parts_;
 };
 
-DEFINE_TYPE_CASTS(LayoutScrollbar,
-                  Scrollbar,
-                  scrollbar,
-                  scrollbar->IsCustomScrollbar(),
-                  scrollbar.IsCustomScrollbar());
+template <>
+struct DowncastTraits<LayoutScrollbar> {
+  static bool AllowFrom(const Scrollbar& scrollbar) {
+    return scrollbar.IsCustomScrollbar();
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/layout/layout_scrollbar_theme.cc b/third_party/blink/renderer/core/layout/layout_scrollbar_theme.cc
index 477c563..2870a4aa 100644
--- a/third_party/blink/renderer/core/layout/layout_scrollbar_theme.cc
+++ b/third_party/blink/renderer/core/layout/layout_scrollbar_theme.cc
@@ -69,19 +69,19 @@
 }
 
 int LayoutScrollbarTheme::MinimumThumbLength(const Scrollbar& scrollbar) {
-  return ToLayoutScrollbar(scrollbar).MinimumThumbLength();
+  return To<LayoutScrollbar>(scrollbar).MinimumThumbLength();
 }
 
 IntRect LayoutScrollbarTheme::BackButtonRect(const Scrollbar& scrollbar,
                                              ScrollbarPart part_type,
                                              bool) {
-  return ToLayoutScrollbar(scrollbar).ButtonRect(part_type);
+  return To<LayoutScrollbar>(scrollbar).ButtonRect(part_type);
 }
 
 IntRect LayoutScrollbarTheme::ForwardButtonRect(const Scrollbar& scrollbar,
                                                 ScrollbarPart part_type,
                                                 bool) {
-  return ToLayoutScrollbar(scrollbar).ButtonRect(part_type);
+  return To<LayoutScrollbar>(scrollbar).ButtonRect(part_type);
 }
 
 IntRect LayoutScrollbarTheme::TrackRect(const Scrollbar& scrollbar, bool) {
@@ -92,16 +92,17 @@
   int end_length;
   ButtonSizesAlongTrackAxis(scrollbar, start_length, end_length);
 
-  return ToLayoutScrollbar(scrollbar).TrackRect(start_length, end_length);
+  return To<LayoutScrollbar>(scrollbar).TrackRect(start_length, end_length);
 }
 
 IntRect LayoutScrollbarTheme::ConstrainTrackRectToTrackPieces(
     const Scrollbar& scrollbar,
     const IntRect& rect) {
-  IntRect back_rect = ToLayoutScrollbar(scrollbar).TrackPieceRectWithMargins(
+  IntRect back_rect = To<LayoutScrollbar>(scrollbar).TrackPieceRectWithMargins(
       kBackTrackPart, rect);
-  IntRect forward_rect = ToLayoutScrollbar(scrollbar).TrackPieceRectWithMargins(
-      kForwardTrackPart, rect);
+  IntRect forward_rect =
+      To<LayoutScrollbar>(scrollbar).TrackPieceRectWithMargins(
+          kForwardTrackPart, rect);
   IntRect result = rect;
   if (scrollbar.Orientation() == kHorizontalScrollbar) {
     result.SetX(back_rect.X());
@@ -130,14 +131,14 @@
 void LayoutScrollbarTheme::PaintScrollbarBackground(
     GraphicsContext& context,
     const Scrollbar& scrollbar) {
-  ScrollbarPainter(ToLayoutScrollbar(scrollbar))
+  ScrollbarPainter(To<LayoutScrollbar>(scrollbar))
       .PaintPart(context, kScrollbarBGPart, scrollbar.FrameRect());
 }
 
 void LayoutScrollbarTheme::PaintTrackBackground(GraphicsContext& context,
                                                 const Scrollbar& scrollbar,
                                                 const IntRect& rect) {
-  ScrollbarPainter(ToLayoutScrollbar(scrollbar))
+  ScrollbarPainter(To<LayoutScrollbar>(scrollbar))
       .PaintPart(context, kTrackBGPart, rect);
 }
 
@@ -145,20 +146,22 @@
                                            const Scrollbar& scrollbar,
                                            const IntRect& rect,
                                            ScrollbarPart part) {
-  ScrollbarPainter(ToLayoutScrollbar(scrollbar)).PaintPart(context, part, rect);
+  ScrollbarPainter(To<LayoutScrollbar>(scrollbar))
+      .PaintPart(context, part, rect);
 }
 
 void LayoutScrollbarTheme::PaintButton(GraphicsContext& context,
                                        const Scrollbar& scrollbar,
                                        const IntRect& rect,
                                        ScrollbarPart part) {
-  ScrollbarPainter(ToLayoutScrollbar(scrollbar)).PaintPart(context, part, rect);
+  ScrollbarPainter(To<LayoutScrollbar>(scrollbar))
+      .PaintPart(context, part, rect);
 }
 
 void LayoutScrollbarTheme::PaintThumb(GraphicsContext& context,
                                       const Scrollbar& scrollbar,
                                       const IntRect& rect) {
-  ScrollbarPainter(ToLayoutScrollbar(scrollbar))
+  ScrollbarPainter(To<LayoutScrollbar>(scrollbar))
       .PaintPart(context, kThumbPart, rect);
 }
 
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc
index 20b3958f..538602d 100644
--- a/third_party/blink/renderer/core/layout/scrollbars_test.cc
+++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -2307,13 +2307,13 @@
 
     ASSERT_TRUE(div_scrollable->HorizontalScrollbar());
     LayoutScrollbar* horizontal_scrollbar =
-        ToLayoutScrollbar(div_scrollable->HorizontalScrollbar());
+        To<LayoutScrollbar>(div_scrollable->HorizontalScrollbar());
     horizontal_track_ = horizontal_scrollbar->GetPart(kTrackBGPart);
     ASSERT_TRUE(horizontal_track_);
 
     ASSERT_TRUE(div_scrollable->VerticalScrollbar());
     LayoutScrollbar* vertical_scrollbar =
-        ToLayoutScrollbar(div_scrollable->VerticalScrollbar());
+        To<LayoutScrollbar>(div_scrollable->VerticalScrollbar());
     vertical_track_ = vertical_scrollbar->GetPart(kTrackBGPart);
     ASSERT_TRUE(vertical_track_);
   }
diff --git a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
index d6a7725..d49b7c5 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
@@ -425,7 +425,7 @@
     return true;
   if (clip_path_operation->GetType() == ClipPathOperation::SHAPE) {
     ShapeClipPathOperation& clip_path =
-        ToShapeClipPathOperation(*clip_path_operation);
+        To<ShapeClipPathOperation>(*clip_path_operation);
     return clip_path.GetPath(reference_box)
         .Contains(location.TransformedPoint());
   }
diff --git a/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc b/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc
index f99236e..e597f7c 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc
@@ -734,7 +734,7 @@
     DCHECK(style.ClipPath());
     DCHECK_EQ(style.ClipPath()->GetType(), ClipPathOperation::REFERENCE);
     const ReferenceClipPathOperation& clip_path_reference =
-        ToReferenceClipPathOperation(*style.ClipPath());
+        To<ReferenceClipPathOperation>(*style.ClipPath());
     AtomicString id = SVGURIReference::FragmentIdentifierFromIRIString(
         clip_path_reference.Url(), tree_scope);
     WriteIndent(ts, indent);
diff --git a/third_party/blink/renderer/core/layout/svg/svg_resources.cc b/third_party/blink/renderer/core/layout/svg/svg_resources.cc
index df89043..bcdbc74 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_resources.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_resources.cc
@@ -172,7 +172,7 @@
       ClipPathOperation* clip_path_operation = computed_style.ClipPath();
       if (clip_path_operation->GetType() == ClipPathOperation::REFERENCE) {
         const ReferenceClipPathOperation& clip_path_reference =
-            ToReferenceClipPathOperation(*clip_path_operation);
+            To<ReferenceClipPathOperation>(*clip_path_operation);
         EnsureResources(resources).SetClipper(
             CastResource<LayoutSVGResourceClipper>(
                 clip_path_reference.Resource()));
@@ -614,7 +614,7 @@
                                             const ComputedStyle& style) {
   const bool had_client = element.GetSVGResourceClient();
   if (auto* reference_clip =
-          ToReferenceClipPathOperationOrNull(style.ClipPath()))
+          DynamicTo<ReferenceClipPathOperation>(style.ClipPath()))
     reference_clip->AddClient(element.EnsureSVGResourceClient());
   if (style.HasFilter())
     style.Filter().AddClient(element.EnsureSVGResourceClient());
@@ -632,7 +632,7 @@
   if (!client)
     return;
   if (auto* old_reference_clip =
-          ToReferenceClipPathOperationOrNull(style->ClipPath()))
+          DynamicTo<ReferenceClipPathOperation>(style->ClipPath()))
     old_reference_clip->RemoveClient(*client);
   if (style->HasFilter())
     style->Filter().RemoveClient(*client);
diff --git a/third_party/blink/renderer/core/loader/BUILD.gn b/third_party/blink/renderer/core/loader/BUILD.gn
index 73af56e..d2328c5 100644
--- a/third_party/blink/renderer/core/loader/BUILD.gn
+++ b/third_party/blink/renderer/core/loader/BUILD.gn
@@ -87,8 +87,6 @@
     "navigation_policy.h",
     "navigation_scheduler.cc",
     "navigation_scheduler.h",
-    "network_hints_interface.cc",
-    "network_hints_interface.h",
     "ping_loader.cc",
     "ping_loader.h",
     "preload_helper.cc",
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
index 98625dc..fcaf048 100644
--- a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
+++ b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
@@ -273,8 +273,6 @@
   ResourceRequest resource_request(url);
   resource_request.SetRequestContext(mojom::RequestContextType::SCRIPT);
   resource_request.SetRequestorOrigin(GetSecurityOrigin());
-  resource_request.SetFetchCredentialsMode(
-      network::mojom::FetchCredentialsMode::kOmit);
 
   ResourceLoaderOptions options;
 
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index e956438..c7f04b33 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -36,7 +36,6 @@
 #include "services/metrics/public/cpp/ukm_recorder.h"
 #include "third_party/blink/public/common/origin_policy/origin_policy.h"
 #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
-#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/public/web/web_history_commit_type.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -65,7 +64,6 @@
 #include "third_party/blink/renderer/core/loader/idleness_detector.h"
 #include "third_party/blink/renderer/core/loader/interactive_detector.h"
 #include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/core/loader/preload_helper.h"
 #include "third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.h"
 #include "third_party/blink/renderer/core/loader/progress_tracker.h"
@@ -352,8 +350,7 @@
   PreloadHelper::LoadLinksFromHeader(
       GetResponse().HttpHeaderField(http_names::kLink),
       GetResponse().CurrentRequestUrl(), *frame_, frame_->GetDocument(),
-      NetworkHintsInterfaceImpl(), PreloadHelper::kOnlyLoadResources,
-      media_policy, viewport);
+      PreloadHelper::kOnlyLoadResources, media_policy, viewport);
 }
 
 void DocumentLoader::DidChangePerformanceTiming() {
@@ -629,7 +626,7 @@
     ArchiveResource* main_resource = nullptr;
     if (!frame_->IsMainFrame()) {
       // Only the top-frame can load MHTML.
-      frame_->Console().AddConsoleMessage(ConsoleMessage::Create(
+      frame_->Console().AddMessage(ConsoleMessage::Create(
           kJSMessageSource, mojom::ConsoleMessageLevel::kError,
           "Attempted to load a multipart archive into an subframe: " +
               url_.GetString()));
@@ -639,7 +636,7 @@
       if (archive_load_result_ != mojom::MHTMLLoadResult::kSuccess) {
         archive_.Clear();
         // Log if attempting to load an invalid archive resource.
-        frame_->Console().AddConsoleMessage(ConsoleMessage::Create(
+        frame_->Console().AddMessage(ConsoleMessage::Create(
             kJSMessageSource, mojom::ConsoleMessageLevel::kError,
             "Malformed multipart archive: " + url_.GetString()));
       } else {
@@ -1166,8 +1163,8 @@
   ParseAndPersistClientHints(response);
   PreloadHelper::LoadLinksFromHeader(
       response.HttpHeaderField(http_names::kLink), response.CurrentRequestUrl(),
-      *GetFrame(), nullptr, NetworkHintsInterfaceImpl(),
-      PreloadHelper::kDoNotLoadResources, PreloadHelper::kLoadAll, nullptr);
+      *GetFrame(), nullptr, PreloadHelper::kDoNotLoadResources,
+      PreloadHelper::kLoadAll, nullptr);
   if (!frame_->IsMainFrame() && response.HasMajorCertificateErrors()) {
     MixedContentChecker::HandleCertificateError(
         GetFrame(), response, mojom::RequestContextType::HYPERLINK);
diff --git a/third_party/blink/renderer/core/loader/empty_clients.cc b/third_party/blink/renderer/core/loader/empty_clients.cc
index 99621207..dd5f3e0 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.cc
+++ b/third_party/blink/renderer/core/loader/empty_clients.cc
@@ -195,12 +195,6 @@
   return nullptr;
 }
 
-const FeaturePolicy::FeatureState&
-EmptyLocalFrameClient::GetOpenerFeatureState() const {
-  DEFINE_STATIC_LOCAL(FeaturePolicy::FeatureState, g_empty_feature_state, ());
-  return g_empty_feature_state;
-}
-
 std::unique_ptr<WebServiceWorkerProvider>
 EmptyLocalFrameClient::CreateServiceWorkerProvider() {
   return nullptr;
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index fb3e622..2810703 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -411,8 +411,6 @@
 
   Frame* FindFrame(const AtomicString& name) const override;
 
-  const FeaturePolicy::FeatureState& GetOpenerFeatureState() const override;
-
  protected:
   // Not owned
   WebTextCheckClient* text_check_client_;
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
index 6f59499..e3ad178 100644
--- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc
+++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -41,7 +41,6 @@
 #include "third_party/blink/public/common/device_memory/approximated_device_memory.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h"
 #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
-#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_application_cache_host.h"
 #include "third_party/blink/public/platform/web_content_settings_client.h"
 #include "third_party/blink/public/platform/web_effective_connection_type.h"
@@ -80,7 +79,6 @@
 #include "third_party/blink/renderer/core/loader/interactive_detector.h"
 #include "third_party/blink/renderer/core/loader/loader_factory_for_frame.h"
 #include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/core/loader/ping_loader.h"
 #include "third_party/blink/renderer/core/loader/progress_tracker.h"
 #include "third_party/blink/renderer/core/loader/subresource_filter.h"
@@ -255,7 +253,7 @@
       MakeGarbageCollected<FrameFetchContext>(frame_or_imported_document),
       document->GetTaskRunner(blink::TaskType::kNetworking),
       MakeGarbageCollected<LoaderFactoryForFrame>(frame_or_imported_document),
-      frame.Console());
+      *document);
   init.frame_scheduler = frame.GetFrameScheduler();
   return MakeGarbageCollected<ResourceFetcher>(init);
 }
@@ -504,8 +502,7 @@
   PreloadHelper::LoadLinksFromHeader(
       response.HttpHeaderField(http_names::kLink), response.CurrentRequestUrl(),
       *GetFrame(), &frame_or_imported_document_->GetDocument(),
-      NetworkHintsInterfaceImpl(), resource_loading_policy,
-      PreloadHelper::kLoadAll, nullptr);
+      resource_loading_policy, PreloadHelper::kLoadAll, nullptr);
 
   DCHECK_EQ(network::mojom::RequestContextFrameType::kNone,
             request.GetFrameType());
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
index 28e2b93a..6393b35 100644
--- a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
+++ b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
@@ -264,8 +264,6 @@
       bool keepalive = false) {
     const KURL input_url("http://example.com/");
     ResourceRequest resource_request(input_url);
-    resource_request.SetFetchCredentialsMode(
-        network::mojom::FetchCredentialsMode::kOmit);
     resource_request.SetKeepalive(keepalive);
     resource_request.SetRequestorOrigin(document->Fetcher()
                                             ->GetProperties()
@@ -1110,8 +1108,6 @@
        LoadResourceFromMemoryCache) {
   ResourceRequest resource_request(url);
   resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
-  resource_request.SetFetchCredentialsMode(
-      network::mojom::FetchCredentialsMode::kOmit);
   Resource* resource = MockResource::Create(resource_request);
   EXPECT_CALL(
       *client,
@@ -1134,8 +1130,6 @@
        MemoryCacheCertificateError) {
   ResourceRequest resource_request(url);
   resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
-  resource_request.SetFetchCredentialsMode(
-      network::mojom::FetchCredentialsMode::kOmit);
   ResourceResponse response(url);
   response.SetHasMajorCertificateErrors(true);
   Resource* resource = MockResource::Create(resource_request);
@@ -1269,7 +1263,6 @@
 
 TEST_F(FrameFetchContextTest, DispatchDidReceiveResponseWhenDetached) {
   ResourceRequest request(KURL("https://www.example.com/"));
-  request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
   Resource* resource = MockResource::Create(request);
   ResourceResponse response;
 
@@ -1356,7 +1349,6 @@
 TEST_F(FrameFetchContextTest, PopulateResourceRequestWhenDetached) {
   const KURL url("https://www.example.com/");
   ResourceRequest request(url);
-  request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   ClientHintsPreferences client_hints_preferences;
   client_hints_preferences.SetShouldSendForTesting(
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 72f3286..5709c2f 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -80,7 +80,6 @@
 #include "third_party/blink/renderer/core/loader/frame_load_request.h"
 #include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
 #include "third_party/blink/renderer/core/loader/navigation_scheduler.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/core/loader/progress_tracker.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/core/page/create_window.h"
diff --git a/third_party/blink/renderer/core/loader/link_loader.cc b/third_party/blink/renderer/core/loader/link_loader.cc
index 786e2b91..0ae76cb7 100644
--- a/third_party/blink/renderer/core/loader/link_loader.cc
+++ b/third_party/blink/renderer/core/loader/link_loader.cc
@@ -51,7 +51,7 @@
 
 namespace blink {
 
-class NetworkHintsInterface;
+class WebPrescientNetworking;
 
 namespace {
 
@@ -169,10 +169,8 @@
   return finish_observer_ ? finish_observer_->GetResource() : nullptr;
 }
 
-bool LinkLoader::LoadLink(
-    const LinkLoadParameters& params,
-    Document& document,
-    const NetworkHintsInterface& network_hints_interface) {
+bool LinkLoader::LoadLink(const LinkLoadParameters& params,
+                          Document& document) {
   // If any loading process is in progress, abort it.
   Abort();
 
@@ -180,11 +178,9 @@
     return false;
 
   PreloadHelper::DnsPrefetchIfNeeded(params, &document, document.GetFrame(),
-                                     network_hints_interface,
                                      PreloadHelper::kLinkCalledFromMarkup);
 
   PreloadHelper::PreconnectIfNeeded(params, &document, document.GetFrame(),
-                                    network_hints_interface,
                                     PreloadHelper::kLinkCalledFromMarkup);
 
   Resource* resource = PreloadHelper::PreloadIfNeeded(
diff --git a/third_party/blink/renderer/core/loader/link_loader.h b/third_party/blink/renderer/core/loader/link_loader.h
index dc9f1eb7..10d0724 100644
--- a/third_party/blink/renderer/core/loader/link_loader.h
+++ b/third_party/blink/renderer/core/loader/link_loader.h
@@ -42,7 +42,6 @@
 
 class Document;
 class LinkLoaderClient;
-class NetworkHintsInterface;
 class PrerenderHandle;
 class Resource;
 class ResourceClient;
@@ -66,9 +65,7 @@
   void DidSendDOMContentLoadedForPrerender() override;
 
   void Abort();
-  bool LoadLink(const LinkLoadParameters&,
-                Document&,
-                const NetworkHintsInterface&);
+  bool LoadLink(const LinkLoadParameters&, Document&);
   void LoadStylesheet(const LinkLoadParameters&,
                       const AtomicString&,
                       const WTF::TextEncoding&,
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc
index 0549d74f3..31c0c11 100644
--- a/third_party/blink/renderer/core/loader/link_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -9,6 +9,7 @@
 #include "base/single_thread_task_runner.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_prescient_networking.h"
 #include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
@@ -17,12 +18,12 @@
 #include "third_party/blink/renderer/core/loader/document_loader.h"
 #include "third_party/blink/renderer/core/loader/link_loader_client.h"
 #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/core/testing/dummy_modulator.h"
 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
 #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
 #include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
 
 namespace blink {
@@ -63,32 +64,51 @@
   const bool should_load_;
 };
 
-class NetworkHintsMock : public NetworkHintsInterface {
+class NetworkHintsMock : public WebPrescientNetworking {
  public:
   NetworkHintsMock() = default;
 
-  void DnsPrefetchHost(const String& host) const override {
-    did_dns_prefetch_ = true;
+  void Reset() {
+    did_dns_prefetch_ = false;
+    did_preconnect_ = false;
+    is_https_ = false;
+    allow_credentials_ = false;
   }
 
-  void PreconnectHost(
-      const KURL& host,
-      const CrossOriginAttributeValue cross_origin) const override {
+  void PrefetchDNS(const WebString& hostname) override {
+    did_dns_prefetch_ = true;
+  }
+  void Preconnect(const WebURL& url, const bool allow_credentials) override {
     did_preconnect_ = true;
-    is_https_ = host.ProtocolIs("https");
-    is_cross_origin_ = (cross_origin == kCrossOriginAttributeAnonymous);
+    is_https_ = url.ProtocolIs("https");
+    allow_credentials_ = allow_credentials;
   }
 
   bool DidDnsPrefetch() { return did_dns_prefetch_; }
   bool DidPreconnect() { return did_preconnect_; }
   bool IsHTTPS() { return is_https_; }
-  bool IsCrossOrigin() { return is_cross_origin_; }
+  bool AllowCredentials() { return allow_credentials_; }
 
  private:
   mutable bool did_dns_prefetch_ = false;
   mutable bool did_preconnect_ = false;
   mutable bool is_https_ = false;
-  mutable bool is_cross_origin_ = false;
+  mutable bool allow_credentials_ = false;
+};
+
+class TestingPlatformSupportWithNetworkHintsMock
+    : public TestingPlatformSupport {
+ public:
+  NetworkHintsMock& GetMockPrescientNetworking() {
+    return mock_prescient_networking_;
+  }
+
+ private:
+  WebPrescientNetworking* PrescientNetworking() override {
+    return &mock_prescient_networking_;
+  }
+
+  NetworkHintsMock mock_prescient_networking_;
 };
 
 class LinkLoaderPreloadTestBase : public testing::Test {
@@ -121,8 +141,7 @@
         MockLinkLoaderClient::Create(expected.link_loader_should_load_value);
     LinkLoader* loader = LinkLoader::Create(loader_client.Get());
     url_test_helpers::RegisterMockedErrorURLLoad(params.href);
-    loader->LoadLink(params, dummy_page_holder_->GetDocument(),
-                     NetworkHintsMock());
+    loader->LoadLink(params, dummy_page_holder_->GetDocument());
     if (!expected.load_url.IsNull() &&
         expected.priority != ResourceLoadPriority::kUnresolved) {
       ASSERT_EQ(1, fetcher->CountPreloads());
@@ -524,8 +543,7 @@
       String() /* type */, String() /* as */, String() /* media */,
       test_case.nonce, test_case.integrity, String(), test_case.referrer_policy,
       href_url, String() /* image_srcset */, String() /* image_sizes */);
-  loader->LoadLink(params, dummy_page_holder->GetDocument(),
-                   NetworkHintsMock());
+  loader->LoadLink(params, dummy_page_holder->GetDocument());
   ASSERT_EQ(test_case.expecting_load, modulator->fetched());
 }
 
@@ -533,7 +551,13 @@
                          LinkLoaderModulePreloadTest,
                          testing::ValuesIn(kModulePreloadTestParams));
 
-TEST(LinkLoaderTest, Prefetch) {
+class LinkLoaderTest : public testing::Test {
+ protected:
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithNetworkHintsMock>
+      platform_;
+};
+
+TEST_F(LinkLoaderTest, Prefetch) {
   struct TestCase {
     const char* href;
     // TODO(yoav): Add support for type and media crbug.com/662687
@@ -571,8 +595,7 @@
         test_case.type, "", test_case.media, "", "", String(),
         test_case.referrer_policy, href_url, String() /* image_srcset */,
         String() /* image_sizes */);
-    loader->LoadLink(params, dummy_page_holder->GetDocument(),
-                     NetworkHintsMock());
+    loader->LoadLink(params, dummy_page_holder->GetDocument());
     ASSERT_TRUE(dummy_page_holder->GetDocument().Fetcher());
     Resource* resource = loader->GetResourceForTesting();
     if (test_case.expecting_load) {
@@ -593,7 +616,7 @@
   }
 }
 
-TEST(LinkLoaderTest, DNSPrefetch) {
+TEST_F(LinkLoaderTest, DNSPrefetch) {
   struct {
     const char* href;
     const bool should_load;
@@ -606,6 +629,7 @@
 
   // Test the cases with a single header
   for (const auto& test_case : cases) {
+    platform_->GetMockPrescientNetworking().Reset();
     std::unique_ptr<DummyPageHolder> dummy_page_holder =
         DummyPageHolder::Create(IntSize(500, 500));
     dummy_page_holder->GetDocument().GetSettings()->SetDNSPrefetchingEnabled(
@@ -614,19 +638,19 @@
         MockLinkLoaderClient::Create(test_case.should_load);
     LinkLoader* loader = LinkLoader::Create(loader_client.Get());
     KURL href_url = KURL(KURL(String("http://example.com")), test_case.href);
-    NetworkHintsMock network_hints;
     LinkLoadParameters params(
         LinkRelAttribute("dns-prefetch"), kCrossOriginAttributeNotSet, String(),
         String(), String(), String(), String(), String(),
         network::mojom::ReferrerPolicy::kDefault, href_url,
         String() /* image_srcset */, String() /* image_sizes */);
-    loader->LoadLink(params, dummy_page_holder->GetDocument(), network_hints);
-    EXPECT_FALSE(network_hints.DidPreconnect());
-    EXPECT_EQ(test_case.should_load, network_hints.DidDnsPrefetch());
+    loader->LoadLink(params, dummy_page_holder->GetDocument());
+    EXPECT_FALSE(platform_->GetMockPrescientNetworking().DidPreconnect());
+    EXPECT_EQ(test_case.should_load,
+              platform_->GetMockPrescientNetworking().DidDnsPrefetch());
   }
 }
 
-TEST(LinkLoaderTest, Preconnect) {
+TEST_F(LinkLoaderTest, Preconnect) {
   struct {
     const char* href;
     CrossOriginAttributeValue cross_origin;
@@ -644,26 +668,34 @@
 
   // Test the cases with a single header
   for (const auto& test_case : cases) {
+    platform_->GetMockPrescientNetworking().Reset();
     std::unique_ptr<DummyPageHolder> dummy_page_holder =
         DummyPageHolder::Create(IntSize(500, 500));
     Persistent<MockLinkLoaderClient> loader_client =
         MockLinkLoaderClient::Create(test_case.should_load);
     LinkLoader* loader = LinkLoader::Create(loader_client.Get());
     KURL href_url = KURL(KURL(String("http://example.com")), test_case.href);
-    NetworkHintsMock network_hints;
     LinkLoadParameters params(
         LinkRelAttribute("preconnect"), test_case.cross_origin, String(),
         String(), String(), String(), String(), String(),
         network::mojom::ReferrerPolicy::kDefault, href_url,
         String() /* image_srcset */, String() /* image_sizes */);
-    loader->LoadLink(params, dummy_page_holder->GetDocument(), network_hints);
-    EXPECT_EQ(test_case.should_load, network_hints.DidPreconnect());
-    EXPECT_EQ(test_case.is_https, network_hints.IsHTTPS());
-    EXPECT_EQ(test_case.is_cross_origin, network_hints.IsCrossOrigin());
+    loader->LoadLink(params, dummy_page_holder->GetDocument());
+    EXPECT_EQ(test_case.should_load,
+              platform_->GetMockPrescientNetworking().DidPreconnect());
+    EXPECT_EQ(test_case.is_https,
+              platform_->GetMockPrescientNetworking().IsHTTPS());
+    if (test_case.should_load) {
+      EXPECT_NE(test_case.is_cross_origin,
+                platform_->GetMockPrescientNetworking().AllowCredentials());
+    } else {
+      EXPECT_EQ(test_case.is_cross_origin,
+                platform_->GetMockPrescientNetworking().AllowCredentials());
+    }
   }
 }
 
-TEST(LinkLoaderTest, PreloadAndPrefetch) {
+TEST_F(LinkLoaderTest, PreloadAndPrefetch) {
   std::unique_ptr<DummyPageHolder> dummy_page_holder =
       DummyPageHolder::Create(IntSize(500, 500));
   ResourceFetcher* fetcher = dummy_page_holder->GetDocument().Fetcher();
@@ -679,8 +711,7 @@
       "application/javascript", "script", "", "", "", String(),
       network::mojom::ReferrerPolicy::kDefault, href_url,
       String() /* image_srcset */, String() /* image_sizes */);
-  loader->LoadLink(params, dummy_page_holder->GetDocument(),
-                   NetworkHintsMock());
+  loader->LoadLink(params, dummy_page_holder->GetDocument());
   ASSERT_EQ(1, fetcher->CountPreloads());
   Resource* resource = loader->GetResourceForTesting();
   ASSERT_NE(resource, nullptr);
diff --git a/third_party/blink/renderer/core/loader/network_hints_interface.cc b/third_party/blink/renderer/core/loader/network_hints_interface.cc
deleted file mode 100644
index 157c309..0000000
--- a/third_party/blink/renderer/core/loader/network_hints_interface.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2008 Collin Jackson  <collinj@webkit.org>
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
-
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_prescient_networking.h"
-
-namespace blink {
-
-void NetworkHintsInterfaceImpl::DnsPrefetchHost(const String& hostname) const {
-  if (WebPrescientNetworking* prescient_networking =
-          Platform::Current()->PrescientNetworking())
-    prescient_networking->PrefetchDNS(hostname);
-}
-
-void NetworkHintsInterfaceImpl::PreconnectHost(
-    const KURL& url,
-    const CrossOriginAttributeValue cross_origin) const {
-  if (WebPrescientNetworking* prescient_networking =
-          Platform::Current()->PrescientNetworking()) {
-    bool allow_credentials = (cross_origin != kCrossOriginAttributeAnonymous);
-    prescient_networking->Preconnect(url, allow_credentials);
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/loader/network_hints_interface.h b/third_party/blink/renderer/core/loader/network_hints_interface.h
deleted file mode 100644
index b6cdcc8..0000000
--- a/third_party/blink/renderer/core/loader/network_hints_interface.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_NETWORK_HINTS_INTERFACE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_NETWORK_HINTS_INTERFACE_H_
-
-#include "third_party/blink/renderer/platform/loader/fetch/cross_origin_attribute_value.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-
-namespace blink {
-
-class NetworkHintsInterface {
- public:
-  virtual void DnsPrefetchHost(const String&) const = 0;
-  virtual void PreconnectHost(const KURL&,
-                              const CrossOriginAttributeValue) const = 0;
-};
-
-class NetworkHintsInterfaceImpl : public NetworkHintsInterface {
- public:
-  void DnsPrefetchHost(const String& host) const override;
-
-  void PreconnectHost(
-      const KURL& host,
-      const CrossOriginAttributeValue cross_origin) const override;
-};
-
-}  // namespace blink
-
-#endif
diff --git a/third_party/blink/renderer/core/loader/preload_helper.cc b/third_party/blink/renderer/core/loader/preload_helper.cc
index 551311a..18f43fa 100644
--- a/third_party/blink/renderer/core/loader/preload_helper.cc
+++ b/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/core/loader/preload_helper.h"
 
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_prescient_networking.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/css/media_list.h"
 #include "third_party/blink/renderer/core/css/media_query_evaluator.h"
@@ -20,7 +22,6 @@
 #include "third_party/blink/renderer/core/loader/importance_attribute.h"
 #include "third_party/blink/renderer/core/loader/link_load_parameters.h"
 #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h"
 #include "third_party/blink/renderer/core/loader/resource/font_resource.h"
 #include "third_party/blink/renderer/core/loader/resource/image_resource.h"
@@ -102,7 +103,6 @@
     const LinkLoadParameters& params,
     Document* document,
     LocalFrame* frame,
-    const NetworkHintsInterface& network_hints_interface,
     LinkCaller caller) {
   if (params.rel.IsDNSPrefetch()) {
     UseCounter::Count(document, WebFeature::kLinkRelDnsPrefetch);
@@ -121,7 +121,11 @@
                 String("DNS prefetch triggered for " + params.href.Host())),
             document, frame);
       }
-      network_hints_interface.DnsPrefetchHost(params.href.Host());
+      WebPrescientNetworking* web_prescient_networking =
+          Platform::Current()->PrescientNetworking();
+      if (web_prescient_networking) {
+        web_prescient_networking->PrefetchDNS(params.href.Host());
+      }
     }
   }
 }
@@ -130,7 +134,6 @@
     const LinkLoadParameters& params,
     Document* document,
     LocalFrame* frame,
-    const NetworkHintsInterface& network_hints_interface,
     LinkCaller caller) {
   if (params.rel.IsPreconnect() && params.href.IsValid() &&
       params.href.ProtocolIsInHTTPFamily()) {
@@ -156,7 +159,12 @@
             document, frame);
       }
     }
-    network_hints_interface.PreconnectHost(params.href, params.cross_origin);
+    WebPrescientNetworking* web_prescient_networking =
+        Platform::Current()->PrescientNetworking();
+    if (web_prescient_networking) {
+      web_prescient_networking->Preconnect(
+          params.href, params.cross_origin != kCrossOriginAttributeAnonymous);
+    }
   }
 }
 
@@ -445,7 +453,6 @@
     const KURL& base_url,
     LocalFrame& frame,
     Document* document,
-    const NetworkHintsInterface& network_hints_interface,
     CanLoadResources can_load_resources,
     MediaPreloadPolicy media_policy,
     ViewportDescriptionWrapper* viewport_description_wrapper) {
@@ -466,11 +473,9 @@
     if (params.href == base_url)
       continue;
     if (can_load_resources != kOnlyLoadResources) {
-      DnsPrefetchIfNeeded(params, document, &frame, network_hints_interface,
-                          kLinkCalledFromHeader);
+      DnsPrefetchIfNeeded(params, document, &frame, kLinkCalledFromHeader);
 
-      PreconnectIfNeeded(params, document, &frame, network_hints_interface,
-                         kLinkCalledFromHeader);
+      PreconnectIfNeeded(params, document, &frame, kLinkCalledFromHeader);
     }
     if (can_load_resources != kDoNotLoadResources) {
       DCHECK(document);
diff --git a/third_party/blink/renderer/core/loader/preload_helper.h b/third_party/blink/renderer/core/loader/preload_helper.h
index d4a63ebb..1604bdb 100644
--- a/third_party/blink/renderer/core/loader/preload_helper.h
+++ b/third_party/blink/renderer/core/loader/preload_helper.h
@@ -12,7 +12,6 @@
 
 class Document;
 class LocalFrame;
-class NetworkHintsInterface;
 class SingleModuleClient;
 struct LinkLoadParameters;
 struct ViewportDescription;
@@ -39,7 +38,6 @@
                                   const KURL& base_url,
                                   LocalFrame&,
                                   Document*,  // can be nullptr
-                                  const NetworkHintsInterface&,
                                   CanLoadResources,
                                   MediaPreloadPolicy,
                                   ViewportDescriptionWrapper*);
@@ -56,12 +54,10 @@
   static void DnsPrefetchIfNeeded(const LinkLoadParameters&,
                                   Document*,
                                   LocalFrame*,
-                                  const NetworkHintsInterface&,
                                   LinkCaller);
   static void PreconnectIfNeeded(const LinkLoadParameters&,
                                  Document*,
                                  LocalFrame*,
-                                 const NetworkHintsInterface&,
                                  LinkCaller);
   static Resource* PrefetchIfNeeded(const LinkLoadParameters&, Document&);
   static Resource* PreloadIfNeeded(const LinkLoadParameters&,
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_test.cc b/third_party/blink/renderer/core/loader/resource/image_resource_test.cc
index 6bbc749a..7e230378 100644
--- a/third_party/blink/renderer/core/loader/resource/image_resource_test.cc
+++ b/third_party/blink/renderer/core/loader/resource/image_resource_test.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
 #include "third_party/blink/renderer/platform/graphics/image.h"
 #include "third_party/blink/renderer/platform/instance_counters.h"
+#include "third_party/blink/renderer/platform/loader/fetch/console_logger.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
@@ -373,8 +374,8 @@
   image_resource->SetIdentifier(CreateUniqueIdentifier());
   fetcher->StartLoad(image_resource);
 
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
   EXPECT_EQ(ResourceStatus::kPending, image_resource->GetStatus());
 
   // Send the multipart response. No image or data buffer is created. Note that
@@ -418,8 +419,8 @@
 
   // Add an observer to check an assertion error doesn't happen
   // (crbug.com/630983).
-  std::unique_ptr<MockImageResourceObserver> observer2 =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer2 =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
   EXPECT_EQ(0, observer2->ImageChangedCount());
   EXPECT_FALSE(observer2->ImageNotifyFinishedCalled());
 
@@ -503,8 +504,8 @@
   fetcher->StartLoad(image_resource);
   GetMemoryCache()->Add(image_resource);
 
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
   EXPECT_EQ(ResourceStatus::kPending, image_resource->GetStatus());
 
   // The load should still be alive, but a timer should be started to cancel the
@@ -583,8 +584,8 @@
   ImageResource* image_resource = ImageResource::CreateForTest(NullURL());
   image_resource->NotifyStartLoad();
 
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   // Send the image response.
   ResourceResponse resource_response(NullURL());
@@ -625,8 +626,8 @@
   ImageResource* image_resource = ImageResource::CreateForTest(NullURL());
   image_resource->NotifyStartLoad();
 
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   // Send the image response.
 
@@ -665,8 +666,8 @@
   ImageResource* image_resource = ImageResource::CreateForTest(test_url);
   image_resource->NotifyStartLoad();
 
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
   ResourceFetcher* fetcher = CreateFetcher();
 
   // Send the image response.
@@ -713,8 +714,8 @@
   ImageResource* image_resource = ImageResource::CreateForTest(test_url);
   image_resource->NotifyStartLoad();
 
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
   ResourceFetcher* fetcher = CreateFetcher();
 
   // Send the image response.
@@ -759,12 +760,11 @@
   ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
   ResourceRequest request(test_url);
   request.SetPreviewsState(WebURLRequest::kServerLoFiOn);
-  request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
   ImageResource* image_resource = ImageResource::Create(request);
   image_resource->NotifyStartLoad();
 
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
   ResourceFetcher* fetcher = CreateFetcher();
 
   // Send the image response, without any LoFi image response headers.
@@ -810,8 +810,7 @@
   ImageResource* image_resource = ImageResource::Fetch(fetch_params, fetcher);
   ImageResourceContent* content = image_resource->GetContent();
 
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(content);
+  auto observer = std::make_unique<MockImageResourceObserver>(content);
 
   // Send the image response.
   ResourceResponse resource_response(NullURL());
@@ -851,8 +850,8 @@
   ResourceFetcher* fetcher = CreateFetcher();
 
   ImageResource* image_resource = ImageResource::Fetch(fetch_params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   EXPECT_FALSE(image_resource->ErrorOccurred());
   EXPECT_EQ(IsClientPlaceholderForServerLoFiEnabled(),
@@ -883,8 +882,8 @@
   ResourceFetcher* fetcher = CreateFetcher();
 
   ImageResource* image_resource = ImageResource::Fetch(fetch_params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   // Send the image response.
   ResourceResponse resource_response(test_url);
@@ -935,8 +934,8 @@
   ImageResource* image_resource = ImageResource::Fetch(params, fetcher);
   EXPECT_EQ(FetchParameters::kAllowPlaceholder,
             params.GetImageRequestOptimization());
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   TestThatIsPlaceholderRequestAndServeResponse(test_url, image_resource,
                                                observer.get());
@@ -986,8 +985,8 @@
 TEST(ImageResourceTest, SVGImage) {
   KURL url("http://127.0.0.1:8000/foo");
   ImageResource* image_resource = ImageResource::CreateForTest(url);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage,
                   strlen(kSvgImage));
@@ -1003,8 +1002,8 @@
 TEST(ImageResourceTest, SVGImageWithSubresource) {
   KURL url("http://127.0.0.1:8000/foo");
   ImageResource* image_resource = ImageResource::CreateForTest(url);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ReceiveResponse(image_resource, url, "image/svg+xml",
                   kSvgImageWithSubresource, strlen(kSvgImageWithSubresource));
@@ -1025,8 +1024,8 @@
   EXPECT_EQ(100, image_resource->GetContent()->GetImage()->height());
 
   // A new client added here shouldn't notified of finish.
-  std::unique_ptr<MockImageResourceObserver> observer2 =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer2 =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
   EXPECT_EQ(1, observer2->ImageChangedCount());
   EXPECT_FALSE(observer2->ImageNotifyFinishedCalled());
 
@@ -1048,8 +1047,8 @@
 TEST(ImageResourceTest, SuccessfulRevalidationJpeg) {
   KURL url("http://127.0.0.1:8000/foo");
   ImageResource* image_resource = ImageResource::CreateForTest(url);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ReceiveResponse(image_resource, url, "image/jpeg",
                   reinterpret_cast<const char*>(kJpegImage),
@@ -1085,8 +1084,8 @@
 TEST(ImageResourceTest, SuccessfulRevalidationSvg) {
   KURL url("http://127.0.0.1:8000/foo");
   ImageResource* image_resource = ImageResource::CreateForTest(url);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage,
                   strlen(kSvgImage));
@@ -1118,8 +1117,8 @@
 TEST(ImageResourceTest, FailedRevalidationJpegToJpeg) {
   KURL url("http://127.0.0.1:8000/foo");
   ImageResource* image_resource = ImageResource::CreateForTest(url);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ReceiveResponse(image_resource, url, "image/jpeg",
                   reinterpret_cast<const char*>(kJpegImage),
@@ -1153,8 +1152,8 @@
 TEST(ImageResourceTest, FailedRevalidationJpegToSvg) {
   KURL url("http://127.0.0.1:8000/foo");
   ImageResource* image_resource = ImageResource::CreateForTest(url);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ReceiveResponse(image_resource, url, "image/jpeg",
                   reinterpret_cast<const char*>(kJpegImage),
@@ -1187,8 +1186,8 @@
 TEST(ImageResourceTest, FailedRevalidationSvgToJpeg) {
   KURL url("http://127.0.0.1:8000/foo");
   ImageResource* image_resource = ImageResource::CreateForTest(url);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage,
                   strlen(kSvgImage));
@@ -1221,8 +1220,8 @@
 TEST(ImageResourceTest, FailedRevalidationSvgToSvg) {
   KURL url("http://127.0.0.1:8000/foo");
   ImageResource* image_resource = ImageResource::CreateForTest(url);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage,
                   strlen(kSvgImage));
@@ -1288,8 +1287,8 @@
   ResourceFetcher* fetcher = CreateFetcher();
   FetchParameters params{ResourceRequest(test_url)};
   ImageResource* image_resource = ImageResource::Fetch(params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ResourceResponse resource_response(test_url);
   resource_response.SetMimeType("image/jpeg");
@@ -1316,8 +1315,8 @@
   ResourceFetcher* fetcher = CreateFetcher();
   FetchParameters params{ResourceRequest(test_url)};
   ImageResource* image_resource = ImageResource::Fetch(params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ResourceResponse resource_response(test_url);
   resource_response.SetMimeType("image/jpeg");
@@ -1351,8 +1350,8 @@
   FetchParameters params(resource_request);
   ResourceFetcher* fetcher = CreateFetcher();
   ImageResource* image_resource = ImageResource::Fetch(params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   ResourceResponse partial_response(test_url);
   partial_response.SetMimeType("image/jpeg");
@@ -1395,8 +1394,8 @@
   FetchParameters params{ResourceRequest(test_url)};
   ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
   EXPECT_EQ(FetchParameters::kNone, params.GetImageRequestOptimization());
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   TestThatIsNotPlaceholderRequestAndServeResponse(test_url, image_resource,
                                                   observer.get());
@@ -1456,8 +1455,8 @@
   ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
   EXPECT_EQ(FetchParameters::kAllowPlaceholder,
             params.GetImageRequestOptimization());
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   TestThatIsPlaceholderRequestAndServeResponse(test_url, image_resource,
                                                observer.get());
@@ -1475,8 +1474,8 @@
   EXPECT_EQ("bytes=0-2047",
             image_resource->GetResourceRequest().HttpHeaderField("range"));
   EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   const char kBadData[] = "notanimageresponse";
 
@@ -1519,8 +1518,8 @@
   EXPECT_EQ("bytes=0-2047",
             image_resource->GetResourceRequest().HttpHeaderField("range"));
   EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   const char kBadData[] = "notanimageresponse";
 
@@ -1582,8 +1581,8 @@
     EXPECT_EQ("bytes=0-2047",
               image_resource->GetResourceRequest().HttpHeaderField("range"));
     EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
-    std::unique_ptr<MockImageResourceObserver> observer =
-        MockImageResourceObserver::Create(image_resource->GetContent());
+    auto observer = std::make_unique<MockImageResourceObserver>(
+        image_resource->GetContent());
 
     // TODO(hiroshige): Make the range request header and partial content length
     // consistent. https://crbug.com/689760.
@@ -1633,19 +1632,19 @@
   placeholder_params.SetAllowImagePlaceholder();
   ImageResource* image_resource =
       ImageResource::Fetch(placeholder_params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   FetchParameters non_placeholder_params{ResourceRequest(test_url)};
   ImageResource* image_resource2 =
       ImageResource::Fetch(non_placeholder_params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer2 =
-      MockImageResourceObserver::Create(image_resource2->GetContent());
+  auto observer2 = std::make_unique<MockImageResourceObserver>(
+      image_resource2->GetContent());
 
   ImageResource* image_resource3 =
       ImageResource::Fetch(non_placeholder_params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer3 =
-      MockImageResourceObserver::Create(image_resource3->GetContent());
+  auto observer3 = std::make_unique<MockImageResourceObserver>(
+      image_resource3->GetContent());
 
   // |imageResource| remains a placeholder, while following non-placeholder
   // requests start non-placeholder loading with a separate ImageResource.
@@ -1683,8 +1682,8 @@
   placeholder_params.SetAllowImagePlaceholder();
   ImageResource* image_resource =
       ImageResource::Fetch(placeholder_params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   TestThatIsPlaceholderRequestAndServeResponse(test_url, image_resource,
                                                observer.get());
@@ -1692,13 +1691,13 @@
   FetchParameters non_placeholder_params{ResourceRequest(test_url)};
   ImageResource* image_resource2 =
       ImageResource::Fetch(non_placeholder_params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer2 =
-      MockImageResourceObserver::Create(image_resource2->GetContent());
+  auto observer2 = std::make_unique<MockImageResourceObserver>(
+      image_resource2->GetContent());
 
   ImageResource* image_resource3 =
       ImageResource::Fetch(non_placeholder_params, fetcher);
-  std::unique_ptr<MockImageResourceObserver> observer3 =
-      MockImageResourceObserver::Create(image_resource3->GetContent());
+  auto observer3 = std::make_unique<MockImageResourceObserver>(
+      image_resource3->GetContent());
 
   EXPECT_FALSE(observer2->ImageNotifyFinishedCalled());
   EXPECT_FALSE(observer3->ImageNotifyFinishedCalled());
@@ -1735,8 +1734,8 @@
     EXPECT_EQ("bytes=0-2047",
               image_resource->GetResourceRequest().HttpHeaderField("range"));
     EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
-    std::unique_ptr<MockImageResourceObserver> observer =
-        MockImageResourceObserver::Create(image_resource->GetContent());
+    auto observer = std::make_unique<MockImageResourceObserver>(
+        image_resource->GetContent());
 
     ResourceResponse resource_response(test_url);
     resource_response.SetMimeType("imapge/jpeg");
@@ -1796,8 +1795,8 @@
     EXPECT_EQ("bytes=0-2047",
               image_resource->GetResourceRequest().HttpHeaderField("range"));
     EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
-    std::unique_ptr<MockImageResourceObserver> observer =
-        MockImageResourceObserver::Create(image_resource->GetContent());
+    auto observer = std::make_unique<MockImageResourceObserver>(
+        image_resource->GetContent());
 
     ResourceResponse resource_response(test_url);
     resource_response.SetMimeType("image/jpeg");
@@ -1830,8 +1829,8 @@
     EXPECT_EQ("bytes=0-2047",
               image_resource->GetResourceRequest().HttpHeaderField("range"));
     EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
-    std::unique_ptr<MockImageResourceObserver> observer =
-        MockImageResourceObserver::Create(image_resource->GetContent());
+    auto observer = std::make_unique<MockImageResourceObserver>(
+        image_resource->GetContent());
 
     static const char kBadImageData[] = "bad image data";
 
@@ -1877,7 +1876,7 @@
   auto frame_scheduler = std::make_unique<scheduler::FakeFrameScheduler>();
   auto* scheduler = MakeGarbageCollected<ResourceLoadScheduler>(
       ResourceLoadScheduler::ThrottlingPolicy::kNormal, *properties,
-      frame_scheduler.get());
+      frame_scheduler.get(), *MakeGarbageCollected<NullConsoleLogger>());
   ImageResource* image_resource = ImageResource::CreateForTest(test_url);
 
   // Ensure that |image_resource| has a loader.
@@ -1887,8 +1886,8 @@
 
   image_resource->NotifyStartLoad();
 
-  std::unique_ptr<MockImageResourceObserver> observer =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+  auto observer =
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   // Send the image response.
   ResourceResponse resource_response(NullURL());
@@ -1964,7 +1963,7 @@
 TEST(ImageResourceTest, DeferredInvalidation) {
   ImageResource* image_resource = ImageResource::CreateForTest(NullURL());
   std::unique_ptr<MockImageResourceObserver> obs =
-      MockImageResourceObserver::Create(image_resource->GetContent());
+      std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
 
   // Image loaded.
   ReceiveResponse(image_resource, NullURL(), "image/jpeg",
diff --git a/third_party/blink/renderer/core/loader/resource/mock_image_resource_observer.h b/third_party/blink/renderer/core/loader/resource/mock_image_resource_observer.h
index c09230c..b2bde7aa 100644
--- a/third_party/blink/renderer/core/loader/resource/mock_image_resource_observer.h
+++ b/third_party/blink/renderer/core/loader/resource/mock_image_resource_observer.h
@@ -17,10 +17,7 @@
 
 class MockImageResourceObserver final : public ImageResourceObserver {
  public:
-  static std::unique_ptr<MockImageResourceObserver> Create(
-      ImageResourceContent* content) {
-    return base::WrapUnique(new MockImageResourceObserver(content));
-  }
+  explicit MockImageResourceObserver(ImageResourceContent*);
   ~MockImageResourceObserver() override;
 
   void RemoveAsObserver();
@@ -41,8 +38,6 @@
   CanDeferInvalidation Defer() const { return defer_; }
 
  private:
-  explicit MockImageResourceObserver(ImageResourceContent*);
-
   // ImageResourceObserver overrides.
   void ImageNotifyFinished(ImageResourceContent*) override;
   void ImageChanged(ImageResourceContent*, CanDeferInvalidation) override;
diff --git a/third_party/blink/renderer/core/page/chrome_client.cc b/third_party/blink/renderer/core/page/chrome_client.cc
index 3bdf7360..6c81bdb 100644
--- a/third_party/blink/renderer/core/page/chrome_client.cc
+++ b/third_party/blink/renderer/core/page/chrome_client.cc
@@ -22,6 +22,8 @@
 #include "third_party/blink/renderer/core/page/chrome_client.h"
 
 #include <algorithm>
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_prescient_networking.h"
 #include "third_party/blink/public/platform/web_screen_info.h"
 #include "third_party/blink/renderer/core/core_initializer.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -30,7 +32,6 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/layout/hit_test_result.h"
-#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/core/page/frame_tree.h"
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/core/page/scoped_page_pauser.h"
@@ -184,8 +185,11 @@
                                            const HitTestResult& result) {
   if (!result.GetScrollbar() && result.InnerNode() &&
       result.InnerNode()->GetDocument().IsDNSPrefetchEnabled()) {
-    NetworkHintsInterfaceImpl().DnsPrefetchHost(
-        result.AbsoluteLinkURL().Host());
+    WebPrescientNetworking* web_prescient_networking =
+        Platform::Current()->PrescientNetworking();
+    if (web_prescient_networking) {
+      web_prescient_networking->PrefetchDNS(result.AbsoluteLinkURL().Host());
+    }
   }
 
   ShowMouseOverURL(result);
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
index d97be5a..f80e468 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -738,8 +738,7 @@
   if (!Platform::Current()->IsThreadedAnimationEnabled())
     return;
 
-  std::unique_ptr<CompositorAnimationTimeline> timeline =
-      CompositorAnimationTimeline::Create();
+  auto timeline = std::make_unique<CompositorAnimationTimeline>();
   if (view && view->GetFrame().LocalFrameRoot() != page_->MainFrame()) {
     view->GetScrollingContext()->SetAnimationHost(&animation_host);
     view->GetScrollingContext()->SetAnimationTimeline(std::move(timeline));
diff --git a/third_party/blink/renderer/core/page/spatial_navigation.cc b/third_party/blink/renderer/core/page/spatial_navigation.cc
index 5da6a2b..693b504 100644
--- a/third_party/blink/renderer/core/page/spatial_navigation.cc
+++ b/third_party/blink/renderer/core/page/spatial_navigation.cc
@@ -275,14 +275,8 @@
       return false;
   }
 
-  // TODO(crbug.com/914775): Use UserScroll() instead. UserScroll() does a
-  // smooth, animated scroll which might make it easier for users to understand
-  // spatnav's moves. Another advantage of using ScrollableArea::UserScroll() is
-  // that it returns a ScrollResult so we don't need to call
-  // CanScrollInDirection(). Regular arrow-key scrolling (without
-  // --enable-spatial-navigation) already uses smooth scrolling by default.
-  container->GetLayoutBox()->GetScrollableArea()->ScrollBy(ScrollOffset(dx, dy),
-                                                           kUserScroll);
+  container->GetLayoutBox()->GetScrollableArea()->UserScroll(
+      kScrollByPixel, ScrollOffset(dx, dy));
   return true;
 }
 
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
index da2655d..4ef00f5 100644
--- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
+++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -392,8 +392,11 @@
       LayoutObject* layout_object = interest_element_->GetLayoutObject();
       DCHECK(layout_object);
 
+      auto params = WebScrollIntoViewParams();
+      if (page_->GetSettings().GetScrollAnimatorEnabled())
+        params.behavior = WebScrollIntoViewParams::kSmooth;
       layout_object->ScrollRectToVisible(
-          element->BoundingBoxForScrollIntoView(), WebScrollIntoViewParams());
+          element->BoundingBoxForScrollIntoView(), params);
     }
     return;
   }
diff --git a/third_party/blink/renderer/core/paint/clip_path_clipper.cc b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
index 6816f59..0cfc8b16 100644
--- a/third_party/blink/renderer/core/paint/clip_path_clipper.cc
+++ b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
@@ -82,7 +82,7 @@
   FloatRect reference_box = LocalReferenceBox(object);
   ClipPathOperation& clip_path = *object.StyleRef().ClipPath();
   if (clip_path.GetType() == ClipPathOperation::SHAPE) {
-    ShapeClipPathOperation& shape = ToShapeClipPathOperation(clip_path);
+    ShapeClipPathOperation& shape = To<ShapeClipPathOperation>(clip_path);
     if (!shape.IsValid())
       return base::nullopt;
     FloatRect bounding_box = shape.GetPath(reference_box).BoundingRect();
@@ -91,8 +91,8 @@
   }
 
   DCHECK_EQ(clip_path.GetType(), ClipPathOperation::REFERENCE);
-  LayoutSVGResourceClipper* clipper =
-      ResolveElementReference(object, ToReferenceClipPathOperation(clip_path));
+  LayoutSVGResourceClipper* clipper = ResolveElementReference(
+      object, To<ReferenceClipPathOperation>(clip_path));
   if (!clipper)
     return base::nullopt;
 
@@ -117,12 +117,12 @@
     const LayoutObject& search_scope,
     LayoutSVGResourceClipper*& resource_clipper) {
   if (clip_path.GetType() == ClipPathOperation::SHAPE) {
-    if (!ToShapeClipPathOperation(clip_path).IsValid())
+    if (!To<ShapeClipPathOperation>(clip_path).IsValid())
       return false;
   } else {
     DCHECK_EQ(clip_path.GetType(), ClipPathOperation::REFERENCE);
     resource_clipper = ResolveElementReference(
-        search_scope, ToReferenceClipPathOperation(clip_path));
+        search_scope, To<ReferenceClipPathOperation>(clip_path));
     if (!resource_clipper)
       return false;
     SECURITY_DCHECK(!resource_clipper->NeedsLayout());
@@ -249,7 +249,7 @@
   }
 
   DCHECK_EQ(clip_path.GetType(), ClipPathOperation::SHAPE);
-  auto& shape = ToShapeClipPathOperation(clip_path);
+  auto& shape = To<ShapeClipPathOperation>(clip_path);
   return base::Optional<Path>(shape.GetPath(reference_box));
 }
 
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl.cc b/third_party/blink/renderer/core/paint/link_highlight_impl.cc
index 60efeb5..efeb3fa 100644
--- a/third_party/blink/renderer/core/paint/link_highlight_impl.cc
+++ b/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -337,8 +337,7 @@
   constexpr auto kFadeDuration = TimeDelta::FromMilliseconds(100);
   constexpr auto kMinPreFadeDuration = TimeDelta::FromMilliseconds(100);
 
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
 
   const auto& timing_function = *CubicBezierTimingFunction::Preset(
       CubicBezierTimingFunction::EaseType::EASE);
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index a3667b5..87d943e 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -201,7 +201,7 @@
     if (style.HasFilter())
       style.Filter().RemoveClient(*rare_data_->resource_info);
     if (auto* reference_clip =
-            ToReferenceClipPathOperationOrNull(style.ClipPath()))
+            DynamicTo<ReferenceClipPathOperation>(style.ClipPath()))
       reference_clip->RemoveClient(*rare_data_->resource_info);
     rare_data_->resource_info->ClearLayer();
   }
@@ -2522,12 +2522,12 @@
   DCHECK(clip_path_operation);
   if (clip_path_operation->GetType() == ClipPathOperation::SHAPE) {
     ShapeClipPathOperation* clip_path =
-        ToShapeClipPathOperation(clip_path_operation);
+        To<ShapeClipPathOperation>(clip_path_operation);
     return !clip_path->GetPath(reference_box).Contains(point);
   }
   DCHECK_EQ(clip_path_operation->GetType(), ClipPathOperation::REFERENCE);
   SVGResource* resource =
-      ToReferenceClipPathOperation(*clip_path_operation).Resource();
+      To<ReferenceClipPathOperation>(*clip_path_operation).Resource();
   LayoutSVGResourceContainer* container =
       resource ? resource->ResourceContainer() : nullptr;
   if (!container || container->ResourceType() != kClipperResourceType)
@@ -3063,10 +3063,11 @@
   if (!new_clip && !old_clip)
     return;
   const bool had_resource_info = ResourceInfo();
-  if (auto* reference_clip = ToReferenceClipPathOperationOrNull(new_clip))
+  if (auto* reference_clip = DynamicTo<ReferenceClipPathOperation>(new_clip))
     reference_clip->AddClient(EnsureResourceInfo());
   if (had_resource_info) {
-    if (auto* old_reference_clip = ToReferenceClipPathOperationOrNull(old_clip))
+    if (auto* old_reference_clip =
+            DynamicTo<ReferenceClipPathOperation>(old_clip))
       old_reference_clip->RemoveClient(*ResourceInfo());
   }
 }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 519b1902..582c124 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -1419,7 +1419,7 @@
     if (needs_custom) {
       DCHECK(scrollbar->IsCustomScrollbar());
       // We have a custom scrollbar with a stale m_owner.
-      if (ToLayoutScrollbar(scrollbar)->StyleSource()->GetLayoutObject() !=
+      if (To<LayoutScrollbar>(scrollbar)->StyleSource()->GetLayoutObject() !=
           style_source) {
         return true;
       }
@@ -2749,7 +2749,7 @@
   ObjectPaintInvalidator(box).InvalidateDisplayItemClient(
       *scrollbar, PaintInvalidationReason::kScrollControl);
   if (scrollbar->IsCustomScrollbar()) {
-    ToLayoutScrollbar(scrollbar)
+    To<LayoutScrollbar>(scrollbar)
         ->InvalidateDisplayItemClientsOfScrollbarParts();
   }
 
diff --git a/third_party/blink/renderer/core/script/classic_pending_script.cc b/third_party/blink/renderer/core/script/classic_pending_script.cc
index c373f6d..6ae8918 100644
--- a/third_party/blink/renderer/core/script/classic_pending_script.cc
+++ b/third_party/blink/renderer/core/script/classic_pending_script.cc
@@ -342,7 +342,7 @@
   auto* fetcher = GetElement()->GetDocument().ContextDocument()->Fetcher();
   // If the MIME check fails, which is considered as load failure.
   if (!AllowedByNosniff::MimeTypeAsScript(
-          fetcher->Context(), fetcher->GetConsoleLogger(),
+          fetcher->Context(), &fetcher->GetConsoleLogger(),
           resource->GetResponse(), AllowedByNosniff::MimeTypeCheck::kLax,
           false)) {
     return nullptr;
diff --git a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
index f57de0a..f9eb19a 100644
--- a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
+++ b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
@@ -54,7 +54,7 @@
   start_time_ = 0.0;
   target_offset_ = offset;
   is_sequenced_scroll_ = is_sequenced_scroll;
-  animation_curve_ = CompositorScrollOffsetAnimationCurve::Create(
+  animation_curve_ = std::make_unique<CompositorScrollOffsetAnimationCurve>(
       CompositorOffsetFromBlinkOffset(target_offset_),
       CompositorScrollOffsetAnimationCurve::kScrollDurationDeltaBased);
 
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator.cc b/third_party/blink/renderer/core/scroll/scroll_animator.cc
index ad4fc61..fbdf7493 100644
--- a/third_party/blink/renderer/core/scroll/scroll_animator.cc
+++ b/third_party/blink/renderer/core/scroll/scroll_animator.cc
@@ -292,7 +292,7 @@
 
 void ScrollAnimator::CreateAnimationCurve() {
   DCHECK(!animation_curve_);
-  animation_curve_ = CompositorScrollOffsetAnimationCurve::Create(
+  animation_curve_ = std::make_unique<CompositorScrollOffsetAnimationCurve>(
       CompositorOffsetFromBlinkOffset(target_offset_),
       last_granularity_ == kScrollByPixel
           ? CompositorScrollOffsetAnimationCurve::kScrollDurationInverseDelta
@@ -420,7 +420,7 @@
   ScrollOffset target_value(scroll_offset_animation_curve->target_value().x(),
                             scroll_offset_animation_curve->target_value().y());
   if (WillAnimateToOffset(target_value)) {
-    animation_curve_ = CompositorScrollOffsetAnimationCurve::Create(
+    animation_curve_ = std::make_unique<CompositorScrollOffsetAnimationCurve>(
         scroll_offset_animation_curve);
     start_time_ = animation_start_time;
   }
diff --git a/third_party/blink/renderer/core/style/reference_clip_path_operation.cc b/third_party/blink/renderer/core/style/reference_clip_path_operation.cc
index b713e54f..a62ee9b 100644
--- a/third_party/blink/renderer/core/style/reference_clip_path_operation.cc
+++ b/third_party/blink/renderer/core/style/reference_clip_path_operation.cc
@@ -23,7 +23,7 @@
 bool ReferenceClipPathOperation::operator==(const ClipPathOperation& o) const {
   if (!IsSameType(o))
     return false;
-  const ReferenceClipPathOperation& other = ToReferenceClipPathOperation(o);
+  const ReferenceClipPathOperation& other = To<ReferenceClipPathOperation>(o);
   return resource_ == other.resource_ && url_ == other.url_;
 }
 
diff --git a/third_party/blink/renderer/core/style/reference_clip_path_operation.h b/third_party/blink/renderer/core/style/reference_clip_path_operation.h
index 6664baf7..83a12ff 100644
--- a/third_party/blink/renderer/core/style/reference_clip_path_operation.h
+++ b/third_party/blink/renderer/core/style/reference_clip_path_operation.h
@@ -35,7 +35,7 @@
 #include "third_party/blink/renderer/core/style/clip_path_operation.h"
 #include "third_party/blink/renderer/core/svg/svg_resource.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
-
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 namespace blink {
 
 class SVGResourceClient;
@@ -65,11 +65,12 @@
   AtomicString url_;
 };
 
-DEFINE_TYPE_CASTS(ReferenceClipPathOperation,
-                  ClipPathOperation,
-                  op,
-                  op->GetType() == ClipPathOperation::REFERENCE,
-                  op.GetType() == ClipPathOperation::REFERENCE);
+template <>
+struct DowncastTraits<ReferenceClipPathOperation> {
+  static bool AllowFrom(const ClipPathOperation& op) {
+    return op.GetType() == ClipPathOperation::REFERENCE;
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/style/shape_clip_path_operation.h b/third_party/blink/renderer/core/style/shape_clip_path_operation.h
index bb7b6a76..03d4c447 100644
--- a/third_party/blink/renderer/core/style/shape_clip_path_operation.h
+++ b/third_party/blink/renderer/core/style/shape_clip_path_operation.h
@@ -63,17 +63,18 @@
   scoped_refptr<BasicShape> shape_;
 };
 
-DEFINE_TYPE_CASTS(ShapeClipPathOperation,
-                  ClipPathOperation,
-                  op,
-                  op->GetType() == ClipPathOperation::SHAPE,
-                  op.GetType() == ClipPathOperation::SHAPE);
+template <>
+struct DowncastTraits<ShapeClipPathOperation> {
+  static bool AllowFrom(const ClipPathOperation& op) {
+    return op.GetType() == ClipPathOperation::SHAPE;
+  }
+};
 
 inline bool ShapeClipPathOperation::operator==(
     const ClipPathOperation& o) const {
   if (!IsSameType(o))
     return false;
-  BasicShape* other_shape = ToShapeClipPathOperation(o).shape_.get();
+  BasicShape* other_shape = To<ShapeClipPathOperation>(o).shape_.get();
   if (!shape_.get() || !other_shape)
     return static_cast<bool>(shape_.get()) == static_cast<bool>(other_shape);
   return *shape_ == *other_shape;
diff --git a/third_party/blink/renderer/core/svg/properties/svg_animated_property.h b/third_party/blink/renderer/core/svg/properties/svg_animated_property.h
index cd8948b..74c0613 100644
--- a/third_party/blink/renderer/core/svg/properties/svg_animated_property.h
+++ b/third_party/blink/renderer/core/svg/properties/svg_animated_property.h
@@ -102,7 +102,7 @@
   static_assert(kNumberOfAnimatedPropertyTypes <= (1u << 5),
                 "enough bits for AnimatedPropertyType (type_)");
   static constexpr int kCssPropertyBits = 9;
-  static_assert((1u << kCssPropertyBits) - 1 >= lastCSSProperty,
+  static_assert((1u << kCssPropertyBits) - 1 >= kIntLastCSSProperty,
                 "enough bits for CSS property ids");
 
   const unsigned type_ : 5;
diff --git a/third_party/blink/renderer/core/svg/svg_element.cc b/third_party/blink/renderer/core/svg/svg_element.cc
index 98977d27..accd742b 100644
--- a/third_party/blink/renderer/core/svg/svg_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_element.cc
@@ -505,7 +505,7 @@
     };
     for (size_t i = 0; i < base::size(attr_names); i++) {
       CSSPropertyID property_id = cssPropertyID(attr_names[i]->LocalName());
-      DCHECK_GT(property_id, 0);
+      DCHECK_GT(property_id, CSSPropertyID::kInvalid);
       property_name_to_id_map->Set(attr_names[i]->LocalName().Impl(),
                                    property_id);
     }
@@ -815,7 +815,7 @@
 bool SVGElement::IsPresentationAttribute(const QualifiedName& name) const {
   if (const SVGAnimatedPropertyBase* property = PropertyFromAttribute(name))
     return property->HasPresentationAttributeMapping();
-  return CssPropertyIdForSVGAttributeName(name) > 0;
+  return CssPropertyIdForSVGAttributeName(name) > CSSPropertyID::kInvalid;
 }
 
 bool SVGElement::IsPresentationAttributeWithSVGDOM(
@@ -829,7 +829,7 @@
     const AtomicString& value,
     MutableCSSPropertyValueSet* style) {
   CSSPropertyID property_id = CssPropertyIdForSVGAttributeName(name);
-  if (property_id > 0)
+  if (property_id > CSSPropertyID::kInvalid)
     AddPropertyToPresentationAttributeStyle(style, property_id, value);
 }
 
@@ -962,7 +962,7 @@
 void SVGElement::SvgAttributeChanged(const QualifiedName& attr_name) {
   CSSPropertyID prop_id =
       SVGElement::CssPropertyIdForSVGAttributeName(attr_name);
-  if (prop_id > 0) {
+  if (prop_id > CSSPropertyID::kInvalid) {
     InvalidateInstances();
     return;
   }
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 9066e86..91eb76d 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -3311,7 +3311,7 @@
 
 Vector<String> Internals::getCSSPropertyLonghands() const {
   Vector<String> result;
-  for (int id = firstCSSProperty; id <= lastCSSProperty; ++id) {
+  for (int id = kIntFirstCSSProperty; id <= kIntLastCSSProperty; ++id) {
     CSSPropertyID property = static_cast<CSSPropertyID>(id);
     const CSSProperty& property_class = CSSProperty::Get(property);
     if (property_class.IsLonghand()) {
@@ -3323,7 +3323,7 @@
 
 Vector<String> Internals::getCSSPropertyShorthands() const {
   Vector<String> result;
-  for (int id = firstCSSProperty; id <= lastCSSProperty; ++id) {
+  for (int id = kIntFirstCSSProperty; id <= kIntLastCSSProperty; ++id) {
     CSSPropertyID property = static_cast<CSSPropertyID>(id);
     const CSSProperty& property_class = CSSProperty::Get(property);
     if (property_class.IsShorthand()) {
diff --git a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
index 44ac6c42..6e58425 100644
--- a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
+++ b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
@@ -178,7 +178,7 @@
   }
   if (!AllowedByNosniff::MimeTypeAsScript(
           fetch_client_settings_object_fetcher_->Context(),
-          fetch_client_settings_object_fetcher_->GetConsoleLogger(), response,
+          &fetch_client_settings_object_fetcher_->GetConsoleLogger(), response,
           fetch_client_settings_object_fetcher_->GetProperties()
               .GetFetchClientSettingsObject()
               .MimeTypeCheckForClassicWorkerScript(),
@@ -190,8 +190,8 @@
   if (is_top_level_script_) {
     String error = CheckSameOriginEnforcement(url_, response);
     if (!error.IsNull()) {
-      fetch_client_settings_object_fetcher_->GetConsoleLogger()
-          ->AddErrorMessage(ConsoleLogger::Source::kSecurity, error);
+      fetch_client_settings_object_fetcher_->GetConsoleLogger().AddErrorMessage(
+          ConsoleLogger::Source::kSecurity, error);
       NotifyError();
       return;
     }
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
index 66e44e3..3bf51fea 100644
--- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
+++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -1647,7 +1647,7 @@
   // the chunk has been processed.
   long bytes_processed = xmlByteConsumed(Context());
   if (bytes_processed == -1 ||
-      static_cast<unsigned long>(bytes_processed) != chunk_as_utf8.length()) {
+      static_cast<wtf_size_t>(bytes_processed) != chunk_as_utf8.length()) {
     // FIXME: I don't believe we can hit this case without also having seen
     // an error or a null byte. If we hit this DCHECK, we've found a test
     // case which demonstrates the need for this code.
diff --git a/third_party/blink/renderer/core/xml/xpath_expression_node.h b/third_party/blink/renderer/core/xml/xpath_expression_node.h
index 1c2162d..3f3f6ea 100644
--- a/third_party/blink/renderer/core/xml/xpath_expression_node.h
+++ b/third_party/blink/renderer/core/xml/xpath_expression_node.h
@@ -46,8 +46,8 @@
   explicit EvaluationContext(Node&);
 
   Member<Node> node;
-  unsigned long size;
-  unsigned long position;
+  wtf_size_t size;
+  wtf_size_t position;
   HashMap<String, String> variable_bindings;
 
   bool had_type_conversion_error;
diff --git a/third_party/blink/renderer/core/xml/xpath_value.h b/third_party/blink/renderer/core/xml/xpath_value.h
index b1361ae2..ff23f413 100644
--- a/third_party/blink/renderer/core/xml/xpath_value.h
+++ b/third_party/blink/renderer/core/xml/xpath_value.h
@@ -75,8 +75,7 @@
   enum Type { kNodeSetValue, kBooleanValue, kNumberValue, kStringValue };
 
   Value(unsigned value) : type_(kNumberValue), bool_(false), number_(value) {}
-  Value(unsigned long value)
-      : type_(kNumberValue), bool_(false), number_(value) {}
+  Value(uint64_t value) : type_(kNumberValue), bool_(false), number_(value) {}
   Value(double value) : type_(kNumberValue), bool_(false), number_(value) {}
 
   Value(const char* value)
diff --git a/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js b/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js
index eda95dc..7b8fe6b 100644
--- a/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js
+++ b/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js
@@ -1305,7 +1305,7 @@
     this._bfs(nodesToVisit, nodesToVisitLength, distances, filter);
 
     // BFS for objects not reached from user roots.
-    distances[this.rootNode().ordinal()] = HeapSnapshotModel.baseSystemDistance;
+    distances[this.rootNode().ordinal()] = nodesToVisitLength > 0 ? HeapSnapshotModel.baseSystemDistance : 0;
     nodesToVisit[0] = this.rootNode().nodeIndex;
     nodesToVisitLength = 1;
     this._bfs(nodesToVisit, nodesToVisitLength, distances, filter);
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
index 3cec6eb53..ced4a04 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -273,12 +273,6 @@
   LinkedHashSet<String> font_lru_list_;
 };
 
-DEFINE_TYPE_CASTS(CanvasRenderingContext2D,
-                  CanvasRenderingContext,
-                  context,
-                  context->Is2d() && context->Host(),
-                  context.Is2d() && context.Host());
-
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_RENDERING_CONTEXT_2D_H_
diff --git a/third_party/blink/renderer/modules/installation/installation_service_impl.cc b/third_party/blink/renderer/modules/installation/installation_service_impl.cc
index 021fd4f84..16a4189 100644
--- a/third_party/blink/renderer/modules/installation/installation_service_impl.cc
+++ b/third_party/blink/renderer/modules/installation/installation_service_impl.cc
@@ -21,8 +21,10 @@
 void InstallationServiceImpl::Create(
     LocalFrame* frame,
     mojom::blink::InstallationServiceRequest request) {
+  // See https://bit.ly/2S0zRAS for task types.
   mojo::MakeStrongBinding(std::make_unique<InstallationServiceImpl>(*frame),
-                          std::move(request));
+                          std::move(request),
+                          frame->GetTaskRunner(TaskType::kMiscPlatformAPI));
 }
 
 void InstallationServiceImpl::OnInstall() {
diff --git a/third_party/blink/renderer/modules/manifest/BUILD.gn b/third_party/blink/renderer/modules/manifest/BUILD.gn
index 74c8b78..383bf5b 100644
--- a/third_party/blink/renderer/modules/manifest/BUILD.gn
+++ b/third_party/blink/renderer/modules/manifest/BUILD.gn
@@ -8,5 +8,7 @@
   sources = [
     "image_resource_type_converters.cc",
     "image_resource_type_converters.h",
+    "manifest_uma_util.cc",
+    "manifest_uma_util.h",
   ]
 }
diff --git a/third_party/blink/renderer/modules/manifest/manifest_uma_util.cc b/third_party/blink/renderer/modules/manifest/manifest_uma_util.cc
new file mode 100644
index 0000000..f615a094
--- /dev/null
+++ b/third_party/blink/renderer/modules/manifest/manifest_uma_util.cc
@@ -0,0 +1,83 @@
+// 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 "third_party/blink/renderer/modules/manifest/manifest_uma_util.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/public/common/manifest/manifest.h"
+
+namespace blink {
+
+namespace {
+
+static const char kUMANameParseSuccess[] = "Manifest.ParseSuccess";
+static const char kUMANameFetchResult[] = "Manifest.FetchResult";
+
+// Enum for UMA purposes, make sure you update histograms.xml if you add new
+// result types. Never delete or reorder an entry; only add new entries
+// immediately before MANIFEST_FETCH_RESULT_TYPE_COUNT.
+enum ManifestFetchResultType {
+  MANIFEST_FETCH_SUCCESS = 0,
+  MANIFEST_FETCH_ERROR_EMPTY_URL = 1,
+  MANIFEST_FETCH_ERROR_UNSPECIFIED = 2,
+  MANIFEST_FETCH_ERROR_FROM_UNIQUE_ORIGIN = 3,
+
+  // Must stay at the end.
+  MANIFEST_FETCH_RESULT_TYPE_COUNT
+};
+
+}  // anonymous namespace
+
+void ManifestUmaUtil::ParseSucceeded(const Manifest& manifest) {
+  UMA_HISTOGRAM_BOOLEAN(kUMANameParseSuccess, true);
+  UMA_HISTOGRAM_BOOLEAN("Manifest.IsEmpty", manifest.IsEmpty());
+  if (manifest.IsEmpty())
+    return;
+
+  UMA_HISTOGRAM_BOOLEAN("Manifest.HasProperty.name", !manifest.name.is_null());
+  UMA_HISTOGRAM_BOOLEAN("Manifest.HasProperty.short_name",
+                        !manifest.short_name.is_null());
+  UMA_HISTOGRAM_BOOLEAN("Manifest.HasProperty.start_url",
+                        !manifest.start_url.is_empty());
+  UMA_HISTOGRAM_BOOLEAN("Manifest.HasProperty.display",
+                        manifest.display != kWebDisplayModeUndefined);
+  UMA_HISTOGRAM_BOOLEAN(
+      "Manifest.HasProperty.orientation",
+      manifest.orientation != kWebScreenOrientationLockDefault);
+  UMA_HISTOGRAM_BOOLEAN("Manifest.HasProperty.icons", !manifest.icons.empty());
+  UMA_HISTOGRAM_BOOLEAN("Manifest.HasProperty.share_target",
+                        manifest.share_target.has_value());
+  UMA_HISTOGRAM_BOOLEAN("Manifest.HasProperty.gcm_sender_id",
+                        !manifest.gcm_sender_id.is_null());
+}
+
+void ManifestUmaUtil::ParseFailed() {
+  UMA_HISTOGRAM_BOOLEAN(kUMANameParseSuccess, false);
+}
+
+void ManifestUmaUtil::FetchSucceeded() {
+  UMA_HISTOGRAM_ENUMERATION(kUMANameFetchResult, MANIFEST_FETCH_SUCCESS,
+                            MANIFEST_FETCH_RESULT_TYPE_COUNT);
+}
+
+void ManifestUmaUtil::FetchFailed(FetchFailureReason reason) {
+  ManifestFetchResultType fetch_result_type = MANIFEST_FETCH_RESULT_TYPE_COUNT;
+  switch (reason) {
+    case FETCH_EMPTY_URL:
+      fetch_result_type = MANIFEST_FETCH_ERROR_EMPTY_URL;
+      break;
+    case FETCH_FROM_UNIQUE_ORIGIN:
+      fetch_result_type = MANIFEST_FETCH_ERROR_FROM_UNIQUE_ORIGIN;
+      break;
+    case FETCH_UNSPECIFIED_REASON:
+      fetch_result_type = MANIFEST_FETCH_ERROR_UNSPECIFIED;
+      break;
+  }
+  DCHECK_NE(fetch_result_type, MANIFEST_FETCH_RESULT_TYPE_COUNT);
+
+  UMA_HISTOGRAM_ENUMERATION(kUMANameFetchResult, fetch_result_type,
+                            MANIFEST_FETCH_RESULT_TYPE_COUNT);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/manifest/manifest_uma_util.h b/third_party/blink/renderer/modules/manifest/manifest_uma_util.h
new file mode 100644
index 0000000..ba5738f
--- /dev/null
+++ b/third_party/blink/renderer/modules/manifest/manifest_uma_util.h
@@ -0,0 +1,38 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_UMA_UTIL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_UMA_UTIL_H_
+
+namespace blink {
+
+struct Manifest;
+
+class ManifestUmaUtil {
+ public:
+  enum FetchFailureReason {
+    FETCH_EMPTY_URL = 0,
+    FETCH_FROM_UNIQUE_ORIGIN,
+    FETCH_UNSPECIFIED_REASON
+  };
+
+  // Record that the Manifest was successfully parsed. If it is an empty
+  // Manifest, it will recorded as so and nothing will happen. Otherwise, the
+  // presence of each properties will be recorded.
+  static void ParseSucceeded(const Manifest& manifest);
+
+  // Record that the Manifest parsing failed.
+  static void ParseFailed();
+
+  // Record that the Manifest fetching succeeded.
+  static void FetchSucceeded();
+
+  // Record that the Manifest fetching failed and takes the |reason| why it
+  // failed.
+  static void FetchFailed(FetchFailureReason reason);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_UMA_UTIL_H_
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node.cc b/third_party/blink/renderer/modules/webaudio/audio_node.cc
index f54c330..4669a78 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_node.cc
@@ -239,7 +239,7 @@
   } else {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
-        ExceptionMessages::IndexOutsideRange<unsigned long>(
+        ExceptionMessages::IndexOutsideRange<uint32_t>(
             "channel count", channel_count, 1,
             ExceptionMessages::kInclusiveBound,
             BaseAudioContext::MaxNumberOfChannels(),
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
index 6c39d17..fde16e7 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
@@ -284,7 +284,7 @@
           channel_count > BaseAudioContext::MaxNumberOfChannels()) {
         exception_state.ThrowDOMException(
             DOMExceptionCode::kNotSupportedError,
-            ExceptionMessages::IndexOutsideRange<unsigned long>(
+            ExceptionMessages::IndexOutsideRange<uint32_t>(
                 "channel count", channel_count, 1,
                 ExceptionMessages::kInclusiveBound,
                 BaseAudioContext::MaxNumberOfChannels(),
diff --git a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
index 6575815..b9ccd47b 100644
--- a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
@@ -156,7 +156,7 @@
   } else {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
-        ExceptionMessages::IndexOutsideRange<unsigned long>(
+        ExceptionMessages::IndexOutsideRange<uint32_t>(
             "channelCount", channel_count, 1,
             ExceptionMessages::kInclusiveBound, 2,
             ExceptionMessages::kInclusiveBound));
diff --git a/third_party/blink/renderer/modules/webaudio/panner_node.cc b/third_party/blink/renderer/modules/webaudio/panner_node.cc
index 8db4322..d475965b 100644
--- a/third_party/blink/renderer/modules/webaudio/panner_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/panner_node.cc
@@ -608,7 +608,7 @@
   } else {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
-        ExceptionMessages::IndexOutsideRange<unsigned long>(
+        ExceptionMessages::IndexOutsideRange<uint32_t>(
             "channelCount", channel_count, 1,
             ExceptionMessages::kInclusiveBound, 2,
             ExceptionMessages::kInclusiveBound));
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc
index 1449ddb..376f84f 100644
--- a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc
@@ -105,7 +105,7 @@
     return;
   }
 
-  unsigned long old_channel_count = this->ChannelCount();
+  uint32_t old_channel_count = this->ChannelCount();
   AudioHandler::SetChannelCount(channel_count, exception_state);
 
   // Stop, re-create and start the destination to apply the new channel count.
diff --git a/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc b/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc
index f49c4d5..15de041 100644
--- a/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc
@@ -105,7 +105,7 @@
   } else {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
-        ExceptionMessages::IndexOutsideRange<unsigned long>(
+        ExceptionMessages::IndexOutsideRange<uint32_t>(
             "channelCount", channel_count, 1,
             ExceptionMessages::kInclusiveBound, 2,
             ExceptionMessages::kInclusiveBound));
diff --git a/third_party/blink/renderer/modules/webdatabase/web_database_impl.h b/third_party/blink/renderer/modules/webdatabase/web_database_impl.h
index 838e067..23c5b91 100644
--- a/third_party/blink/renderer/modules/webdatabase/web_database_impl.h
+++ b/third_party/blink/renderer/modules/webdatabase/web_database_impl.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#include "third_party/blink/public/platform/modules/webdatabase/web_database.mojom-blink.h"
+#include "third_party/blink/public/mojom/webdatabase/web_database.mojom-blink.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index f07db7c..bc1fb4e6 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -2432,7 +2432,7 @@
   // If the deleted was bound to the the current maximum index, trace backwards
   // to find the new max texture index.
   if (one_plus_max_non_default_texture_unit_ ==
-      static_cast<unsigned long>(max_bound_texture_index + 1)) {
+      static_cast<wtf_size_t>(max_bound_texture_index + 1)) {
     FindNewMaxNonDefaultTextureUnit();
   }
 }
diff --git a/third_party/blink/renderer/platform/animation/animated_layers_test.cc b/third_party/blink/renderer/platform/animation/animated_layers_test.cc
index 907951ba..e5408e49 100644
--- a/third_party/blink/renderer/platform/animation/animated_layers_test.cc
+++ b/third_party/blink/renderer/platform/animation/animated_layers_test.cc
@@ -62,8 +62,7 @@
   EXPECT_FALSE(
       mutator->HasTickingKeyframeModelForTesting(cc_layer->element_id()));
 
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(
       CompositorFloatKeyframe(0.0, 0.0,
                               *CubicBezierTimingFunction::Preset(
@@ -73,8 +72,7 @@
           *curve, compositor_target_property::OPACITY, 0, 0));
   int keyframe_model_id = float_keyframe_model->Id();
 
-  std::unique_ptr<CompositorAnimationTimeline> compositor_timeline =
-      CompositorAnimationTimeline::Create();
+  auto compositor_timeline = std::make_unique<CompositorAnimationTimeline>();
   AnimationForTesting animation;
 
   cc::AnimationHost* host = layers_.animation_host();
diff --git a/third_party/blink/renderer/platform/animation/compositor_animation_test.cc b/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
index 32ed3418..e0cef4b6 100644
--- a/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
+++ b/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
@@ -60,8 +60,7 @@
       CompositorAnimation::Create();
   cc::SingleKeyframeEffectAnimation* cc_animation = animation->CcAnimation();
 
-  std::unique_ptr<CompositorAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   std::unique_ptr<CompositorKeyframeModel> keyframe_model =
       CompositorKeyframeModel::Create(
           *curve, compositor_target_property::TRANSFORM, 1, 0);
@@ -91,8 +90,7 @@
   scoped_refptr<cc::SingleKeyframeEffectAnimation> cc_animation =
       animation->CcAnimation();
 
-  std::unique_ptr<CompositorAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   std::unique_ptr<CompositorKeyframeModel> keyframe_model =
       CompositorKeyframeModel::Create(
           *curve, compositor_target_property::OPACITY, 1, 0);
@@ -117,8 +115,7 @@
 
 TEST_F(CompositorAnimationTest,
        CompositorAnimationDeletionDetachesFromCCTimeline) {
-  std::unique_ptr<CompositorAnimationTimeline> timeline =
-      CompositorAnimationTimeline::Create();
+  auto timeline = std::make_unique<CompositorAnimationTimeline>();
   std::unique_ptr<CompositorAnimationTestClient> client(
       new CompositorAnimationTestClient);
 
diff --git a/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h b/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h
index 7dc275bc..d38525d 100644
--- a/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h
+++ b/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h
@@ -23,10 +23,7 @@
   USING_FAST_MALLOC(CompositorAnimationTimeline);
 
  public:
-  static std::unique_ptr<CompositorAnimationTimeline> Create() {
-    return base::WrapUnique(new CompositorAnimationTimeline());
-  }
-
+  CompositorAnimationTimeline();
   ~CompositorAnimationTimeline();
 
   cc::AnimationTimeline* GetAnimationTimeline() const;
@@ -35,8 +32,6 @@
   void AnimationDestroyed(const CompositorAnimationClient&);
 
  private:
-  CompositorAnimationTimeline();
-
   scoped_refptr<cc::AnimationTimeline> animation_timeline_;
 
   DISALLOW_COPY_AND_ASSIGN(CompositorAnimationTimeline);
diff --git a/third_party/blink/renderer/platform/animation/compositor_animation_timeline_test.cc b/third_party/blink/renderer/platform/animation/compositor_animation_timeline_test.cc
index 9e1724d..2823a9b6 100644
--- a/third_party/blink/renderer/platform/animation/compositor_animation_timeline_test.cc
+++ b/third_party/blink/renderer/platform/animation/compositor_animation_timeline_test.cc
@@ -17,8 +17,7 @@
 
 TEST_F(CompositorAnimationTimelineTest,
        CompositorTimelineDeletionDetachesFromAnimationHost) {
-  std::unique_ptr<CompositorAnimationTimeline> timeline =
-      CompositorAnimationTimeline::Create();
+  auto timeline = std::make_unique<CompositorAnimationTimeline>();
 
   scoped_refptr<cc::AnimationTimeline> cc_timeline =
       timeline->GetAnimationTimeline();
diff --git a/third_party/blink/renderer/platform/animation/compositor_filter_animation_curve.h b/third_party/blink/renderer/platform/animation/compositor_filter_animation_curve.h
index ac2d4d2f..7ed4a5c 100644
--- a/third_party/blink/renderer/platform/animation/compositor_filter_animation_curve.h
+++ b/third_party/blink/renderer/platform/animation/compositor_filter_animation_curve.h
@@ -28,9 +28,7 @@
 class PLATFORM_EXPORT CompositorFilterAnimationCurve
     : public CompositorAnimationCurve {
  public:
-  static std::unique_ptr<CompositorFilterAnimationCurve> Create() {
-    return base::WrapUnique(new CompositorFilterAnimationCurve());
-  }
+  CompositorFilterAnimationCurve();
   ~CompositorFilterAnimationCurve() override;
 
   void AddKeyframe(const CompositorFilterKeyframe&);
@@ -41,8 +39,6 @@
   std::unique_ptr<cc::AnimationCurve> CloneToAnimationCurve() const override;
 
  private:
-  CompositorFilterAnimationCurve();
-
   std::unique_ptr<cc::KeyframedFilterAnimationCurve> curve_;
 
   DISALLOW_COPY_AND_ASSIGN(CompositorFilterAnimationCurve);
diff --git a/third_party/blink/renderer/platform/animation/compositor_float_animation_curve.h b/third_party/blink/renderer/platform/animation/compositor_float_animation_curve.h
index 050b078..56d80126 100644
--- a/third_party/blink/renderer/platform/animation/compositor_float_animation_curve.h
+++ b/third_party/blink/renderer/platform/animation/compositor_float_animation_curve.h
@@ -30,10 +30,7 @@
 class PLATFORM_EXPORT CompositorFloatAnimationCurve
     : public CompositorAnimationCurve {
  public:
-  static std::unique_ptr<CompositorFloatAnimationCurve> Create() {
-    return base::WrapUnique(new CompositorFloatAnimationCurve());
-  }
-
+  CompositorFloatAnimationCurve();
   ~CompositorFloatAnimationCurve() override;
 
   void AddKeyframe(const CompositorFloatKeyframe&);
@@ -53,7 +50,6 @@
   scoped_refptr<TimingFunction> GetTimingFunctionForTesting() const;
 
  private:
-  CompositorFloatAnimationCurve();
   CompositorFloatAnimationCurve(
       std::unique_ptr<cc::KeyframedFloatAnimationCurve>);
 
diff --git a/third_party/blink/renderer/platform/animation/compositor_float_animation_curve_test.cc b/third_party/blink/renderer/platform/animation/compositor_float_animation_curve_test.cc
index ac990edc..92f932a 100644
--- a/third_party/blink/renderer/platform/animation/compositor_float_animation_curve_test.cc
+++ b/third_party/blink/renderer/platform/animation/compositor_float_animation_curve_test.cc
@@ -17,8 +17,7 @@
 
 // Tests that a float animation with one keyframe works as expected.
 TEST(WebFloatAnimationCurveTest, OneFloatKeyframe) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(
       CompositorFloatKeyframe(0, 2, *LinearTimingFunction::Shared()));
   EXPECT_FLOAT_EQ(2, curve->GetValue(-1));
@@ -30,8 +29,7 @@
 
 // Tests that a float animation with two keyframes works as expected.
 TEST(WebFloatAnimationCurveTest, TwoFloatKeyframe) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(
       CompositorFloatKeyframe(0, 2, *LinearTimingFunction::Shared()));
   curve->AddKeyframe(
@@ -45,8 +43,7 @@
 
 // Tests that a float animation with three keyframes works as expected.
 TEST(WebFloatAnimationCurveTest, ThreeFloatKeyframe) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(
       CompositorFloatKeyframe(0, 2, *LinearTimingFunction::Shared()));
   curve->AddKeyframe(
@@ -64,8 +61,7 @@
 
 // Tests that a float animation with multiple keys at a given time works sanely.
 TEST(WebFloatAnimationCurveTest, RepeatedFloatKeyTimes) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(
       CompositorFloatKeyframe(0, 4, *LinearTimingFunction::Shared()));
   curve->AddKeyframe(
@@ -90,8 +86,7 @@
 
 // Tests that the keyframes may be added out of order.
 TEST(WebFloatAnimationCurveTest, UnsortedKeyframes) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(
       CompositorFloatKeyframe(2, 8, *LinearTimingFunction::Shared()));
   curve->AddKeyframe(
@@ -110,8 +105,7 @@
 
 // Tests that a cubic bezier timing function works as expected.
 TEST(WebFloatAnimationCurveTest, CubicBezierTimingFunction) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   scoped_refptr<CubicBezierTimingFunction> cubic =
       CubicBezierTimingFunction::Create(0.25, 0, 0.75, 1);
   curve->AddKeyframe(CompositorFloatKeyframe(0, 0, *cubic));
@@ -129,8 +123,7 @@
 
 // Tests that an ease timing function works as expected.
 TEST(WebFloatAnimationCurveTest, EaseTimingFunction) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(
       CompositorFloatKeyframe(0, 0,
                               *CubicBezierTimingFunction::Preset(
@@ -149,8 +142,7 @@
 
 // Tests using a linear timing function.
 TEST(WebFloatAnimationCurveTest, LinearTimingFunction) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(
       CompositorFloatKeyframe(0, 0, *LinearTimingFunction::Shared()));
   curve->AddKeyframe(
@@ -164,8 +156,7 @@
 
 // Tests that an ease in timing function works as expected.
 TEST(WebFloatAnimationCurveTest, EaseInTimingFunction) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(CompositorFloatKeyframe(
       0, 0,
       *CubicBezierTimingFunction::Preset(
@@ -184,8 +175,7 @@
 
 // Tests that an ease in timing function works as expected.
 TEST(WebFloatAnimationCurveTest, EaseOutTimingFunction) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(CompositorFloatKeyframe(
       0, 0,
       *CubicBezierTimingFunction::Preset(
@@ -204,8 +194,7 @@
 
 // Tests that an ease in timing function works as expected.
 TEST(WebFloatAnimationCurveTest, EaseInOutTimingFunction) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(CompositorFloatKeyframe(
       0, 0,
       *CubicBezierTimingFunction::Preset(
@@ -224,8 +213,7 @@
 
 // Tests that an ease in timing function works as expected.
 TEST(WebFloatAnimationCurveTest, CustomBezierTimingFunction) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   double x1 = 0.3;
   double y1 = 0.2;
   double x2 = 0.8;
@@ -246,8 +234,7 @@
 
 // Tests that the default timing function is indeed ease.
 TEST(WebFloatAnimationCurveTest, DefaultTimingFunction) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   curve->AddKeyframe(
       CompositorFloatKeyframe(0, 0,
                               *CubicBezierTimingFunction::Preset(
diff --git a/third_party/blink/renderer/platform/animation/compositor_keyframe_model_test.cc b/third_party/blink/renderer/platform/animation/compositor_keyframe_model_test.cc
index a7b63b46..1f5b28e6 100644
--- a/third_party/blink/renderer/platform/animation/compositor_keyframe_model_test.cc
+++ b/third_party/blink/renderer/platform/animation/compositor_keyframe_model_test.cc
@@ -10,8 +10,7 @@
 namespace blink {
 
 TEST(WebCompositorAnimationTest, DefaultSettings) {
-  std::unique_ptr<CompositorAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   std::unique_ptr<CompositorKeyframeModel> keyframe_model =
       CompositorKeyframeModel::Create(
           *curve, compositor_target_property::OPACITY, 1, 0);
@@ -25,8 +24,7 @@
 }
 
 TEST(WebCompositorAnimationTest, ModifiedSettings) {
-  std::unique_ptr<CompositorFloatAnimationCurve> curve =
-      CompositorFloatAnimationCurve::Create();
+  auto curve = std::make_unique<CompositorFloatAnimationCurve>();
   std::unique_ptr<CompositorKeyframeModel> keyframe_model =
       CompositorKeyframeModel::Create(
           *curve, compositor_target_property::OPACITY, 1, 0);
diff --git a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
index f1a8031..4ed3a5a 100644
--- a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
+++ b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
@@ -29,17 +29,9 @@
     kScrollDurationInverseDelta
   };
 
-  static std::unique_ptr<CompositorScrollOffsetAnimationCurve> Create(
-      FloatPoint target_value,
-      CompositorScrollOffsetAnimationCurve::ScrollDurationBehavior
-          duration_behavior) {
-    return base::WrapUnique(new CompositorScrollOffsetAnimationCurve(
-        target_value, duration_behavior));
-  }
-  static std::unique_ptr<CompositorScrollOffsetAnimationCurve> Create(
-      cc::ScrollOffsetAnimationCurve* curve) {
-    return base::WrapUnique(new CompositorScrollOffsetAnimationCurve(curve));
-  }
+  CompositorScrollOffsetAnimationCurve(FloatPoint, ScrollDurationBehavior);
+  explicit CompositorScrollOffsetAnimationCurve(
+      cc::ScrollOffsetAnimationCurve*);
 
   ~CompositorScrollOffsetAnimationCurve() override;
 
@@ -54,9 +46,6 @@
   std::unique_ptr<cc::AnimationCurve> CloneToAnimationCurve() const override;
 
  private:
-  CompositorScrollOffsetAnimationCurve(FloatPoint, ScrollDurationBehavior);
-  CompositorScrollOffsetAnimationCurve(cc::ScrollOffsetAnimationCurve*);
-
   std::unique_ptr<cc::ScrollOffsetAnimationCurve> curve_;
 
   DISALLOW_COPY_AND_ASSIGN(CompositorScrollOffsetAnimationCurve);
diff --git a/third_party/blink/renderer/platform/animation/compositor_transform_animation_curve.h b/third_party/blink/renderer/platform/animation/compositor_transform_animation_curve.h
index 4e6d616b..b6f872ce 100644
--- a/third_party/blink/renderer/platform/animation/compositor_transform_animation_curve.h
+++ b/third_party/blink/renderer/platform/animation/compositor_transform_animation_curve.h
@@ -28,10 +28,7 @@
 class PLATFORM_EXPORT CompositorTransformAnimationCurve
     : public CompositorAnimationCurve {
  public:
-  static std::unique_ptr<CompositorTransformAnimationCurve> Create() {
-    return base::WrapUnique(new CompositorTransformAnimationCurve());
-  }
-
+  CompositorTransformAnimationCurve();
   ~CompositorTransformAnimationCurve() override;
 
   void AddKeyframe(const CompositorTransformKeyframe&);
@@ -42,8 +39,6 @@
   std::unique_ptr<cc::AnimationCurve> CloneToAnimationCurve() const override;
 
  private:
-  CompositorTransformAnimationCurve();
-
   std::unique_ptr<cc::KeyframedTransformAnimationCurve> curve_;
 
   DISALLOW_COPY_AND_ASSIGN(CompositorTransformAnimationCurve);
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
index 126b127..3c6db11 100644
--- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
+++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -600,10 +600,6 @@
   RuntimeEnabledFeatures::SetAutomationControlledEnabled(enable);
 }
 
-void WebRuntimeFeatures::EnableScheduledScriptStreaming(bool enable) {
-  RuntimeEnabledFeatures::SetScheduledScriptStreamingEnabled(enable);
-}
-
 void WebRuntimeFeatures::EnableScriptStreamingOnPreload(bool enable) {
   RuntimeEnabledFeatures::SetScriptStreamingOnPreloadEnabled(enable);
 }
@@ -657,4 +653,8 @@
   RuntimeEnabledFeatures::SetHTMLImportsOnlyChromeEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnableSignedExchangeSubresourcePrefetch(bool enable) {
+  RuntimeEnabledFeatures::SetSignedExchangeSubresourcePrefetchEnabled(enable);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
index 3f8d7e09..89cfad3 100644
--- a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
+++ b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
@@ -256,7 +256,7 @@
 bool PNGImageDecoder::SetSize(unsigned width, unsigned height) {
   DCHECK(!IsDecodedSizeAvailable());
   // Protect against large PNGs. See http://bugzil.la/251381 for more details.
-  const unsigned long kMaxPNGSize = 1000000UL;
+  const uint32_t kMaxPNGSize = 1000000;
   return (width <= kMaxPNGSize) && (height <= kMaxPNGSize) &&
          ImageDecoder::SetSize(width, height);
 }
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
index 65f9d46..c6ac9750 100644
--- a/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
@@ -73,8 +73,6 @@
   MockResource* ResourceFromResourceRequest(ResourceRequest request) {
     if (request.Url().IsNull())
       request.SetURL(KURL(kResourceURL));
-    request.SetFetchCredentialsMode(
-        network::mojom::FetchCredentialsMode::kOmit);
     MockResource* resource = MockResource::Create(request);
     ResourceResponse response(KURL{kResourceURL});
     response.SetMimeType("text/html");
@@ -419,7 +417,6 @@
 
   ResourceRequest request(redirect_url);
   request.SetRequestorOrigin(GetSecurityOrigin());
-  request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
   MockResource* first_resource = MockResource::Create(request);
 
   ResourceResponse stale301_response(redirect_url);
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
index 114d19cb..79ae10c 100644
--- a/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
@@ -89,11 +89,7 @@
     }
     static FakeResource* Create(const KURL& url, ResourceType type) {
       ResourceRequest request(url);
-      request.SetFetchCredentialsMode(
-          network::mojom::FetchCredentialsMode::kOmit);
-
       ResourceLoaderOptions options;
-
       return MakeGarbageCollected<FakeResource>(request, type, options);
     }
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index fd8f5d0..046ce7e6 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -396,6 +396,41 @@
   return mojom::RequestContextType::SUBRESOURCE;
 }
 
+class ResourceFetcher::DetachableConsoleLogger final
+    : public GarbageCollectedFinalized<DetachableConsoleLogger>,
+      public ConsoleLogger {
+  USING_GARBAGE_COLLECTED_MIXIN(DetachableConsoleLogger);
+
+ public:
+  DetachableConsoleLogger(ConsoleLogger& logger) : logger_(logger) {}
+
+  void Detach() { logger_ = nullptr; }
+
+  // ConsoleLogger implementation.
+  void AddInfoMessage(Source source, const String& message) override {
+    if (logger_) {
+      logger_->AddInfoMessage(source, message);
+    }
+  }
+  void AddWarningMessage(Source source, const String& message) override {
+    if (logger_) {
+      logger_->AddWarningMessage(source, message);
+    }
+  }
+  void AddErrorMessage(Source source, const String& message) override {
+    if (logger_) {
+      logger_->AddErrorMessage(source, message);
+    }
+  }
+  void Trace(Visitor* visitor) override {
+    visitor->Trace(logger_);
+    ConsoleLogger::Trace(visitor);
+  }
+
+ private:
+  Member<ConsoleLogger> logger_;
+};
+
 // A delegating ResourceFetcherProperties subclass which can be from the
 // original ResourceFetcherProperties.
 class ResourceFetcher::DetachableProperties final
@@ -479,12 +514,14 @@
           *MakeGarbageCollected<DetachableProperties>(*init.properties)),
       context_(init.context),
       task_runner_(init.task_runner),
-      console_logger_(init.console_logger),
+      console_logger_(
+          MakeGarbageCollected<DetachableConsoleLogger>(*init.console_logger)),
       loader_factory_(init.loader_factory),
       scheduler_(MakeGarbageCollected<ResourceLoadScheduler>(
           init.initial_throttling_policy,
           *properties_,
-          init.frame_scheduler)),
+          init.frame_scheduler,
+          *console_logger_)),
       archive_(init.archive),
       resource_timing_report_timer_(
           task_runner_,
@@ -494,7 +531,6 @@
       images_enabled_(true),
       allow_stale_resources_(false),
       image_fetched_(false) {
-  DCHECK(console_logger_);
   stale_while_revalidate_enabled_ =
       RuntimeEnabledFeatures::StaleWhileRevalidateEnabledByRuntimeFlag();
   InstanceCounters::IncrementCounter(InstanceCounters::kResourceFetcherCounter);
@@ -1605,7 +1641,7 @@
     properties_->Detach();
   }
 
-  console_logger_ = MakeGarbageCollected<NullConsoleLogger>();
+  console_logger_->Detach();
   loader_factory_ = nullptr;
 
   // Make sure the only requests still going are keepalive requests.
@@ -1628,6 +1664,10 @@
   }
 }
 
+ConsoleLogger& ResourceFetcher::GetConsoleLogger() {
+  return *console_logger_;
+}
+
 int ResourceFetcher::BlockingRequestCount() const {
   return loaders_.size();
 }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
index 6145c62..9ef5541a 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -154,7 +154,7 @@
 
   FetchContext& Context() const;
   void ClearContext();
-  ConsoleLogger* GetConsoleLogger() { return console_logger_; }
+  ConsoleLogger& GetConsoleLogger();
 
   int BlockingRequestCount() const;
   int NonblockingRequestCount() const;
@@ -237,6 +237,7 @@
 
  private:
   friend class ResourceCacheValidationSuppressor;
+  class DetachableConsoleLogger;
   class DetachableProperties;
   enum class StopFetchingTarget {
     kExcludingKeepaliveLoaders,
@@ -343,7 +344,7 @@
   Member<DetachableProperties> properties_;
   Member<FetchContext> context_;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  Member<ConsoleLogger> console_logger_;
+  const Member<DetachableConsoleLogger> console_logger_;
   Member<LoaderFactory> loader_factory_;
   const Member<ResourceLoadScheduler> scheduler_;
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
index 6d1e7e8..9e6d89f5 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -369,7 +369,6 @@
   auto* fetcher = CreateFetcher();
   ResourceRequest request(KURL("data:text/html,foo"));
   request.SetRequestContext(mojom::RequestContextType::VIDEO);
-  request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
   ResourceLoaderOptions options;
   options.data_buffering_policy = kDoNotBufferData;
   options.initiator_info.name = fetch_initiator_type_names::kInternal;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
index 0d97155..f321066e 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
@@ -349,11 +349,13 @@
 ResourceLoadScheduler::ResourceLoadScheduler(
     ThrottlingPolicy initial_throttling_policy,
     const ResourceFetcherProperties& resource_fetcher_properties,
-    FrameScheduler* frame_scheduler)
+    FrameScheduler* frame_scheduler,
+    ConsoleLogger& console_logger)
     : resource_fetcher_properties_(resource_fetcher_properties),
       policy_(initial_throttling_policy),
       outstanding_limit_for_throttled_frame_scheduler_(
-          GetOutstandingThrottledLimit(*resource_fetcher_properties_)) {
+          GetOutstandingThrottledLimit(*resource_fetcher_properties_)),
+      console_logger_(console_logger) {
   traffic_monitor_ = std::make_unique<ResourceLoadScheduler::TrafficMonitor>(
       resource_fetcher_properties);
 
@@ -378,6 +380,7 @@
 void ResourceLoadScheduler::Trace(blink::Visitor* visitor) {
   visitor->Trace(pending_request_map_);
   visitor->Trace(resource_fetcher_properties_);
+  visitor->Trace(console_logger_);
 }
 
 void ResourceLoadScheduler::LoosenThrottlingPolicy() {
@@ -739,16 +742,7 @@
     // last 1 minutes, or there is no pending requests in the inactive queue.
     return;
   }
-  ConsoleLogger* logger = nullptr;
-  for (const auto& client : pending_requests_[target_option]) {
-    auto client_it = pending_request_map_.find(client.client_id);
-    if (pending_request_map_.end() == client_it)
-      continue;
-    logger = client_it->value->client->GetConsoleLogger();
-  }
-  DCHECK(logger);
-
-  logger->AddInfoMessage(
+  console_logger_->AddInfoMessage(
       ConsoleLogger::Source::kOther,
       "Some resource load requests were throttled while the tab was in "
       "background, and no request was sent from the queue in the last 1 "
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
index 050ef933..dd8ca10 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
@@ -28,10 +28,6 @@
   // Called when the request is granted to run.
   virtual void Run() = 0;
 
-  // Called to obtain a ConsoleLogger instance.
-  // TODO(yhirano): Remove this once https://crbug.com/855189 is fixed.
-  virtual ConsoleLogger* GetConsoleLogger() = 0;
-
   void Trace(blink::Visitor* visitor) override {}
 };
 
@@ -152,7 +148,8 @@
 
   ResourceLoadScheduler(ThrottlingPolicy initial_throttling_poilcy,
                         const ResourceFetcherProperties&,
-                        FrameScheduler*);
+                        FrameScheduler*,
+                        ConsoleLogger& console_logger);
   ~ResourceLoadScheduler() override;
 
   void Trace(blink::Visitor*);
@@ -342,6 +339,8 @@
   std::unique_ptr<FrameScheduler::LifecycleObserverHandle>
       scheduler_observer_handle_;
 
+  const Member<ConsoleLogger> console_logger_;
+
   DISALLOW_COPY_AND_ASSIGN(ResourceLoadScheduler);
 };
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc
index 88e7858..b7d95af 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc
@@ -51,11 +51,6 @@
     was_run_ = true;
   }
   bool WasRun() { return was_run_; }
-  ConsoleLogger* GetConsoleLogger() override {
-    was_console_logger_obtained_ = true;
-    return console_logger_;
-  }
-  bool WasConsoleLoggerObtained() { return was_console_logger_obtained_; }
 
   void Trace(blink::Visitor* visitor) override {
     ResourceLoadSchedulerClient::Trace(visitor);
@@ -67,24 +62,47 @@
       MakeGarbageCollected<NullConsoleLogger>();
   MockClientDelegate* delegate_;
   bool was_run_ = false;
-  bool was_console_logger_obtained_ = false;
 };
 
 class ResourceLoadSchedulerTest : public testing::Test {
  public:
+  class MockConsoleLogger final
+      : public GarbageCollectedFinalized<MockConsoleLogger>,
+        public ConsoleLogger {
+    USING_GARBAGE_COLLECTED_MIXIN(MockConsoleLogger);
+
+   public:
+    void AddInfoMessage(Source source, const String& message) override {
+      has_message_ = true;
+    }
+    void AddWarningMessage(Source source, const String& message) override {
+      has_message_ = true;
+    }
+    void AddErrorMessage(Source source, const String& message) override {
+      has_message_ = true;
+    }
+
+    bool HasMessage() const { return has_message_; }
+
+   private:
+    bool has_message_ = false;
+  };
+
   using ThrottleOption = ResourceLoadScheduler::ThrottleOption;
   void SetUp() override {
     DCHECK(RuntimeEnabledFeatures::ResourceLoadSchedulerEnabled());
     auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
     properties->SetShouldBlockLoadingSubResource(true);
     auto frame_scheduler = std::make_unique<scheduler::FakeFrameScheduler>();
+    console_logger_ = MakeGarbageCollected<MockConsoleLogger>();
     scheduler_ = MakeGarbageCollected<ResourceLoadScheduler>(
         ResourceLoadScheduler::ThrottlingPolicy::kTight, *properties,
-        frame_scheduler.get());
+        frame_scheduler.get(), *console_logger_);
     Scheduler()->SetOutstandingLimitForTesting(1);
   }
   void TearDown() override { Scheduler()->Shutdown(); }
 
+  MockConsoleLogger* GetConsoleLogger() { return console_logger_; }
   ResourceLoadScheduler* Scheduler() { return scheduler_; }
 
   bool Release(ResourceLoadScheduler::ClientId client) {
@@ -99,6 +117,7 @@
   }
 
  private:
+  Persistent<MockConsoleLogger> console_logger_;
   Persistent<ResourceLoadScheduler> scheduler_;
 };
 
@@ -655,8 +674,7 @@
   mock_clock.Advance(WTF::TimeDelta::FromSeconds(50));
   Scheduler()->OnLifecycleStateChanged(
       scheduler::SchedulingLifecycleState::kNotThrottled);
-  EXPECT_FALSE(client1->WasConsoleLoggerObtained());
-  EXPECT_FALSE(client2->WasConsoleLoggerObtained());
+  EXPECT_FALSE(GetConsoleLogger()->HasMessage());
   Scheduler()->OnLifecycleStateChanged(
       scheduler::SchedulingLifecycleState::kThrottled);
 
@@ -665,8 +683,7 @@
   mock_clock.Advance(WTF::TimeDelta::FromSeconds(15));
   Scheduler()->OnLifecycleStateChanged(
       scheduler::SchedulingLifecycleState::kNotThrottled);
-  EXPECT_FALSE(client1->WasConsoleLoggerObtained());
-  EXPECT_TRUE(client2->WasConsoleLoggerObtained());
+  EXPECT_TRUE(GetConsoleLogger()->HasMessage());
   EXPECT_TRUE(Release(id2));
 }
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
index 8bc6a4c1..f055cb38 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -493,10 +493,6 @@
   StartWith(resource_->GetResourceRequest());
 }
 
-ConsoleLogger* ResourceLoader::GetConsoleLogger() {
-  return fetcher_->GetConsoleLogger();
-}
-
 void ResourceLoader::DidReceiveData(base::span<const char> data) {
   DidReceiveData(data.data(), data.size());
 }
@@ -1204,7 +1200,7 @@
     return;
   }
   if (error.CorsErrorStatus()) {
-    GetConsoleLogger()->AddErrorMessage(
+    fetcher_->GetConsoleLogger().AddErrorMessage(
         ConsoleLogger::Source::kScript,
         cors::GetErrorString(
             *error.CorsErrorStatus(), resource_->GetResourceRequest().Url(),
@@ -1422,7 +1418,7 @@
   String mime_type = response.HttpContentType();
   if (request_context == mojom::RequestContextType::STYLE &&
       !MIMETypeRegistry::IsSupportedStyleSheetMIMEType(mime_type)) {
-    GetConsoleLogger()->AddErrorMessage(
+    fetcher_->GetConsoleLogger().AddErrorMessage(
         ConsoleLogger::Source::kSecurity,
         "Refused to apply style from '" +
             response.CurrentRequestUrl().ElidedString() +
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
index a90893bd..d13de58 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
@@ -50,7 +50,6 @@
 
 namespace blink {
 
-class ConsoleLogger;
 class FetchContext;
 class ResourceError;
 class ResourceFetcher;
@@ -167,7 +166,6 @@
 
   // ResourceLoadSchedulerClient.
   void Run() override;
-  ConsoleLogger* GetConsoleLogger() override;
 
   // ResponseBodyLoaderClient implementation.
   void DidReceiveData(base::span<const char> data) override;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 1cfd24f..da8e5c6 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -510,6 +510,7 @@
     },
     {
       name: "FastFlatTreeTraversal",
+      status: "stable",
     },
     {
       name: "FastMobileScrolling",
@@ -1227,9 +1228,6 @@
     {
       name: "RTCUnifiedPlanByDefault",
     },
-    {
-      name: "ScheduledScriptStreaming",
-    },
     // WebSpeech API with both speech recognition and synthesis functionality
     // is not fully enabled on all platforms.
     {
@@ -1316,6 +1314,9 @@
       status: "experimental",
     },
     {
+      name: "SignedExchangeSubresourcePrefetch",
+    },
+    {
       name: "SkipAd",
       depends_on: ["MediaSession"],
       origin_trial_feature_name: "SkipAd",
diff --git a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
index 2d57044..1576919 100644
--- a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
@@ -35,7 +35,6 @@
     case WebThreadType::kHRTFDatabaseLoaderThread:
     case WebThreadType::kOfflineAudioRenderThread:
     case WebThreadType::kReverbConvolutionBackgroundThread:
-    case WebThreadType::kScriptStreamerThread:
     case WebThreadType::kSharedWorkerThread:
     case WebThreadType::kUnspecifiedWorkerThread:
     case WebThreadType::kWebAudioThread:
diff --git a/third_party/blink/renderer/platform/web_thread_type.cc b/third_party/blink/renderer/platform/web_thread_type.cc
index fd20b80..2c17a78 100644
--- a/third_party/blink/renderer/platform/web_thread_type.cc
+++ b/third_party/blink/renderer/platform/web_thread_type.cc
@@ -33,8 +33,6 @@
       return "Database thread";
     case WebThreadType::kWebAudioThread:
       return "WebAudio thread";
-    case WebThreadType::kScriptStreamerThread:
-      return "ScriptStreamer thread";
     case WebThreadType::kOfflineAudioRenderThread:
       return "OfflineAudioRender thread";
     case WebThreadType::kReverbConvolutionBackgroundThread:
diff --git a/third_party/blink/renderer/platform/wtf/math_extras_test.cc b/third_party/blink/renderer/platform/wtf/math_extras_test.cc
index 64f2b9c..bb0be6a3 100644
--- a/third_party/blink/renderer/platform/wtf/math_extras_test.cc
+++ b/third_party/blink/renderer/platform/wtf/math_extras_test.cc
@@ -179,12 +179,12 @@
             clampTo<uint64_t>(-overflow_ull));
 }
 
-TEST(MathExtrasTest, clampToUnsignedUnsignedLong) {
-  if (sizeof(unsigned long) == sizeof(unsigned))
+TEST(MathExtrasTest, clampToUnsignedUint32) {
+  if (sizeof(uint32_t) == sizeof(unsigned))
     return;
 
-  unsigned long max_unsigned = std::numeric_limits<unsigned>::max();
-  unsigned long overflow_unsigned = max_unsigned + 1;
+  uint32_t max_unsigned = std::numeric_limits<unsigned>::max();
+  uint32_t overflow_unsigned = max_unsigned + 1;
 
   EXPECT_GT(overflow_unsigned, max_unsigned);
 
@@ -194,7 +194,7 @@
   EXPECT_EQ(0u, clampTo<unsigned>(-1));
 }
 
-TEST(MathExtrasTest, clampToUnsignedUnsignedLongLong) {
+TEST(MathExtrasTest, clampToUnsignedUint64) {
   uint64_t max_unsigned = std::numeric_limits<unsigned>::max();
   uint64_t overflow_unsigned = max_unsigned + 1;
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 1f52c67..239399aa 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3023,6 +3023,18 @@
 crbug.com/939181 virtual/not-site-per-process/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Failure Timeout ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html [ Failure ]
+crbug.com/626703 [ Mac10.11 ] external/wpt/shape-detection/detection-security-test.html [ Timeout ]
+crbug.com/626703 external/wpt/svg/text/reftests/text-text-anchor-001.svg [ Failure ]
+crbug.com/626703 [ Mac10.11 ] external/wpt/shape-detection/shapedetection-cross-origin.sub.html [ Timeout ]
+crbug.com/626703 external/wpt/svg/text/reftests/text-text-anchor-201.svg [ Failure ]
+crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3q.html [ Failure ]
+crbug.com/626703 external/wpt/svg/text/reftests/text-text-anchor-202.svg [ Failure ]
+crbug.com/626703 external/wpt/svg/text/reftests/text-text-anchor-102.svg [ Failure ]
+crbug.com/626703 external/wpt/svg/text/reftests/text-text-anchor-002.svg [ Failure ]
+crbug.com/626703 external/wpt/svg/text/reftests/text-text-anchor-203.svg [ Failure ]
+crbug.com/626703 [ Retina ] external/wpt/speech-api/idlharness.window.html [ Failure Timeout ]
+crbug.com/626703 external/wpt/svg/text/reftests/text-text-anchor-003.svg [ Failure ]
 crbug.com/626703 [ Retina ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStreamTrack-id.https.html [ Timeout ]
 crbug.com/626703 [ Retina ] virtual/layout_ng/external/wpt/css/CSS2/abspos/abspos-containing-block-initial-009e.xht [ Timeout ]
 crbug.com/626703 [ Retina ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStream-add-audio-track.https.html [ Timeout ]
@@ -6089,6 +6101,9 @@
 crbug.com/931533 media/video-played-collapse.html [ Pass Failure ]
 crbug.com/931533 virtual/video-surface-layer/media/video-played-collapse.html [ Pass Failure ]
 
+crbug.com/940797 external/wpt/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html [ Pass Failure ]
+crbug.com/940797 virtual/sxg-with-network-service/external/wpt/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html [ Pass Failure ]
+
 # Flaky failures due to <object> resources not always appearing in the timeline.
 crbug.com/941482 external/wpt/resource-timing/nested-context-navigations.html [ Pass Failure ]
 
@@ -6111,7 +6126,7 @@
 crbug.com/942517 [ Linux ] virtual/binary-for-inspector-protocol/http/tests/inspector-protocol/network/interception-multiclient.js [ Failure ]
 
 # Trooper 2019-03-19
-crbug.com/941482 [ Win ] virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations.html [ Pass Failure ]
+crbug.com/941482 [ Win7 ] virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations.html [ Failure Pass ]
 crbug.com/943390 [ Win ] http/tests/security/mixedContent/empty-url-plugin-in-frame.html [ Pass Failure ]
 crbug.com/943390 [ Win ] virtual/outofblink-cors/http/tests/security/mixedContent/empty-url-plugin-in-frame.html [ Pass Failure ]
 crbug.com/943388 [ Win ] http/tests/devtools/network/network-recording-after-reload-with-screenshots-enabled.js [ Pass Failure ]
@@ -6122,9 +6137,11 @@
 crbug.com/938592 virtual/gpu/fast/canvas/fillrect_gradient.html [ Pass Failure Timeout ]
 #
 # Trooper 2019-03-19
-crbug.com/836242 [ Mac ] external/wpt/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html [ Pass Failure ]
+crbug.com/941565 external/wpt/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html [ Pass Failure ]
 
 # Sheriff 2019-03-20
-crbug.com/943907 [ Mac10.10 Mac10.11 ] fast/forms/validation-bubble-appearance-escape.html [ Pass Failure ]
-crbug.com/943907 [ Mac10.10 Mac10.11 ] fast/forms/validation-bubble-device-emulation-change.html [ Pass Failure ]
-crbug.com/943907 [ Mac10.10 Mac10.11 ] fast/forms/validation-bubble-device-emulation.html [ Pass Failure ]
+crbug.com/732103 [ Mac10.11 ] http/tests/shapedetection/shapedetection-cross-origin.html [ Timeout Pass ]
+crbug.com/943969 [ Win ] inspector-protocol/animation/animation-pause-infinite.js [ Pass Failure ]
+crbug.com/943969 [ Mac10.10 Mac10.11 ] inspector-protocol/animation/animation-pause-infinite.js [ Pass Failure ]
+crbug.com/943969 [ Win ] inspector-protocol/css/css-get-media-queries.js [ Pass Failure ]
+crbug.com/943969 [ Mac10.10 Mac10.11 ] inspector-protocol/css/css-get-media-queries.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-01.html b/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-01.html
index a6d8bba3..c3eadb0 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-01.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-01.html
@@ -41,19 +41,17 @@
 });
 
 async_test(t => {
-  window.addEventListener("load", () => {
-    t.step(() => {
-      // Animation begins once we append the DOM node to the document.
-      var boxNode = document.createElement('div');
-      boxNode.id = 'box';
-      boxNode.className = 'animate';
-      document.body.appendChild(boxNode);
+  window.addEventListener("load", t.step_func(() => {
+    // Animation begins once we append the DOM node to the document.
+    var boxNode = document.createElement('div');
+    boxNode.id = 'box';
+    boxNode.className = 'animate';
+    document.body.appendChild(boxNode);
 
-      document.addEventListener('webkitAnimationIteration', () => {
-        assert_true (startEventReceived && endEventReceived);
-        t.done();
-      });
-    });
-  });
+    document.addEventListener('webkitAnimationIteration', t.step_func_done(() => {
+      assert_true(startEventReceived);
+      assert_true(endEventReceived);
+    }));
+  }));
 }, "Tests that prefixed animation events are correctly fired");
 </script>
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-02.html b/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-02.html
index b601c1f..3027e83 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-02.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-02.html
@@ -55,18 +55,17 @@
 });
 
 async_test(t => {
-  window.addEventListener("load", () => {
-    t.step(() => {
-      // Animation begins once we append the DOM node to the document.
-      var boxNode = document.createElement('div');
-      boxNode.id = 'box';
-      boxNode.className = 'animate';
-      document.body.appendChild(boxNode);
-      document.addEventListener('animationiteration', () => {
-        assert_true(startEventReceived && endEventReceived && prefixedEventReceived == 0);
-        t.done();
-      });
-    });
-  });
+  window.addEventListener("load", t.step_func(() => {
+    // Animation begins once we append the DOM node to the document.
+    var boxNode = document.createElement('div');
+    boxNode.id = 'box';
+    boxNode.className = 'animate';
+    document.body.appendChild(boxNode);
+    document.addEventListener('animationiteration', t.step_func_done(() => {
+      assert_true(startEventReceived);
+      assert_true(endEventReceived);
+      assert_equals(prefixedEventReceived, 0);
+    }));
+  }));
 }, "Tests that unprefixed animation events are correctly fired when listeners are on both versions");
 </script>
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-03.html b/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-03.html
index bafaef8c..4659e28 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-03.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-03.html
@@ -42,15 +42,13 @@
 }
 
 async_test(t => {
-  window.addEventListener("load", () => {
+  window.addEventListener("load", t.step_func(() => {
     const box = document.getElementById('box');
-    box.addEventListener("animationiteration", () => {
-      t.step(() => {
-        assert_true(startEventReceived && endEventReceived);
-        t.done();
-      });
-    });
-  });
+    box.addEventListener("animationiteration", t.step_func_done(() => {
+      assert_true(startEventReceived);
+      assert_true(endEventReceived);
+    }));
+  }));
 }, "Prefixed animation events should be fired with html event listeners");
 </script>
 <div id="box" onwebkitanimationstart="recordAnimationStart();"
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-04.html b/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-04.html
index 724cd8d..bfbb64f 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-04.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-events-prefixed-04.html
@@ -6,33 +6,22 @@
 var webkitAnimationStartReceived = false;
 var webkitAnimationIterationReceived = false;
 
-document.addEventListener('animationstart', () => {
-  assert_unreached("animationstart event listener should not have been called");
-});
-
 document.addEventListener('webkitAnimationStart', () => {
   webkitAnimationStartReceived = true;
 });
 
-document.addEventListener('animationiteration', () => {
-  assert_unreached("animationiteration event listener should not have been called");
-});
-
 document.addEventListener('webkitAnimationIteration', () => {
   webkitAnimationIterationReceived = true;
 });
 
-document.addEventListener('animationend', () => {
-    assert_unreached("animationend event listener should not have been called");
-});
-
 async_test(t => {
-  document.addEventListener('webkitAnimationEnd', () => {
-    t.step(() => {
-      assert_true(webkitAnimationIterationReceived && webkitAnimationIterationReceived);
-      t.done();
-    });
-  });
+  document.addEventListener('animationstart', t.unreached_func('animationstart event listener should not have been called'));
+  document.addEventListener('animationiteration', t.unreached_func('animationiteration event listener should not have been called'));
+  document.addEventListener('animationend', t.unreached_func('animationend event listener should not have been called'));
+  document.addEventListener('webkitAnimationEnd', t.step_func_done(() => {
+    assert_true(webkitAnimationStartReceived);
+    assert_true(webkitAnimationIterationReceived);
+  }));
 
   var custom = document.createEvent('CustomEvent');
   custom.initCustomEvent('webkitAnimationStart', true, true, null);
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-01.html b/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-01.html
index b71336c..97c6ec3c 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-01.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-01.html
@@ -41,18 +41,16 @@
 });
 
 async_test(t => {
-  window.addEventListener("load", () => {
-    t.step(() => {
-      // Animation begins once we append the DOM node to the document.
-      var boxNode = document.createElement('div');
-      boxNode.id = 'box';
-      boxNode.className = 'animate';
-      document.body.appendChild(boxNode);
-      document.addEventListener('animationiteration', () => {
-        assert_true(startEventReceived && endEventReceived);
-        t.done();
-      });
-    });
-  });
+  window.addEventListener("load", t.step_func(() => {
+    // Animation begins once we append the DOM node to the document.
+    var boxNode = document.createElement('div');
+    boxNode.id = 'box';
+    boxNode.className = 'animate';
+    document.body.appendChild(boxNode);
+    document.addEventListener('animationiteration', t.step_func_done(() => {
+      assert_true(startEventReceived);
+      assert_true(endEventReceived);
+    }));
+  }));
 }, "Tests that unprefixed animation events are correctly fired");
 </script>
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-02.html b/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-02.html
index cacbaae..2dcab14 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-02.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-02.html
@@ -41,15 +41,13 @@
 }
 
 async_test(t => {
-  window.addEventListener("load", () => {
+  window.addEventListener("load", t.step_func(() => {
     const box = document.getElementById('box');
-    box.addEventListener("animationiteration", () => {
-      t.step(() => {
-        assert_true(startEventReceived && endEventReceived);
-        t.done();
-      });
-    });
-  });
+    box.addEventListener("animationiteration", t.step_func_done(() => {
+      assert_true(startEventReceived);
+      assert_true(endEventReceived);
+    }));
+  }));
 }, "Tests that unprefixed animation events are correctly fired when using html event listeners");
 </script>
 <div id="box" onanimationstart="recordAnimationStart();" onanimationend="recordAnimationEnd();" class="animate"></div>
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-03.html b/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-03.html
index f5b18f0..506e74d 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-03.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-03.html
@@ -46,15 +46,14 @@
 }
 
 async_test(t => {
-  window.addEventListener("load", () => {
+  window.addEventListener("load", t.step_func(() => {
     const box = document.getElementById('box');
-    box.addEventListener("animationiteration", () => {
-      t.step(() => {
-        assert_true(startEventReceived && endEventReceived && prefixedEventReceived == 0);
-        t.done();
-      });
-    });
-  });
+    box.addEventListener("animationiteration", t.step_func_done(() => {
+      assert_true(startEventReceived);
+      assert_true(endEventReceived);
+      assert_equals(prefixedEventReceived, 0);
+    }));
+  }));
 }, "Tests that unprefixed animation events are correctly fired when using html event listeners (only unprefixed should be fired)");
 </script>
 <div id="box" onwebkitanimationstart="recordPrefixedEvent();" onwebkitanimationend="recordPrefixedEvent();" onwebkitanimationiteration="recordPrefixedEvent();" onanimationstart="recordAnimationStart();" onanimationend="recordAnimationEnd();" class="animate"></div>
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-04.html b/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-04.html
index 389ee7b6..b3299e0 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-04.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-events-unprefixed-04.html
@@ -10,29 +10,19 @@
   animationStartReceived = true;
 });
 
-document.addEventListener('webkitAnimationStart', () => {
-  assert_unreached("webkitAnimationStart event listener should not have been called");
-});
-
 document.addEventListener('animationiteration', () => {
   animationIterationReceived = true;
 });
 
-document.addEventListener('webkitAnimationIteration', () => {
-  assert_unreached("webkitAnimationIteration event listener should not have been called");
-});
-
-document.addEventListener('webkitAnimationEnd', function(e) {
-  assert_unreached("webkitAnimationEnd event listener should not have been called");
-});
-
 async_test(t => {
-  document.addEventListener('animationend', () => {
-    t.step(() => {
-      assert_true(animationStartReceived && animationIterationReceived);
-      t.done();
-    });
-  });
+  document.addEventListener('webkitAnimationStart', t.unreached_func('webkitAnimationStart event listener should not have been called'));
+  document.addEventListener('webkitAnimationIteration', t.unreached_func('webkitAnimationIteration event listener should not have been called'));
+  document.addEventListener('webkitAnimationEnd', t.unreached_func('webkitAnimationEnd event listener should not have been called'));
+
+  document.addEventListener('animationend', t.step_func_done(() => {
+    assert_true(animationStartReceived);
+    assert_true(animationIterationReceived);
+  }));
 
   var custom = document.createEvent('CustomEvent');
   custom.initCustomEvent('animationstart', true, true, null);
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-shorthand-prefixed.html b/third_party/blink/web_tests/animations/prefixed/animation-shorthand-prefixed.html
index b9adae70..9e00778c 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-shorthand-prefixed.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-shorthand-prefixed.html
@@ -74,18 +74,13 @@
     for (var i=0; i < kProperties.length; i++) {
       var computedValue = elStyle[kProperties[i]];
       var expectedValue = curItem.values[i];
-      assert_true(computedValue == expectedValue);
+      assert_equals(computedValue, expectedValue);
     }
   });
 }
 
 async_test(t => {
-  window.addEventListener("load", () => {
-    t.step(() => {
-      start();
-      t.done();
-    });
-  });
+  window.addEventListener("load", t.step_func_done(start));
 }, "Test animation shorthand property prefixed");
 </script>
 <div id="a" class="box"></div>
diff --git a/third_party/blink/web_tests/animations/prefixed/animation-shorthand-unprefixed.html b/third_party/blink/web_tests/animations/prefixed/animation-shorthand-unprefixed.html
index 5e496bd..62f9a3f 100644
--- a/third_party/blink/web_tests/animations/prefixed/animation-shorthand-unprefixed.html
+++ b/third_party/blink/web_tests/animations/prefixed/animation-shorthand-unprefixed.html
@@ -74,18 +74,13 @@
     for (var i=0; i < kProperties.length; i++) {
       var computedValue = elStyle[kProperties[i]];
       var expectedValue = curItem.values[i];
-      assert_true(computedValue == expectedValue);
+      assert_equals(computedValue, expectedValue);
     }
   });
 }
 
 async_test(t => {
-  window.addEventListener("load", () => {
-    t.step(() => {
-      start();
-      t.done();
-    });
-  });
+  window.addEventListener("load", t.step_func_done(start));
 }, "Test animation shorthand property unprefixed");
 </script>
 <div id="a" class="box"></div>
diff --git a/third_party/blink/web_tests/animations/prefixed/keyframes-cssom-prefixed-02.html b/third_party/blink/web_tests/animations/prefixed/keyframes-cssom-prefixed-02.html
index 80dcac1..868d112e 100644
--- a/third_party/blink/web_tests/animations/prefixed/keyframes-cssom-prefixed-02.html
+++ b/third_party/blink/web_tests/animations/prefixed/keyframes-cssom-prefixed-02.html
@@ -19,46 +19,43 @@
 <script src="../../resources/testharnessreport.js"></script>
 <script>
 async_test(t => {
-  window.addEventListener("load", () => {
-    t.step(() => {
-      var testContainer = document.createElement("div");
-      document.body.appendChild(testContainer);
+  window.addEventListener("load", t.step_func_done(() => {
+    var testContainer = document.createElement("div");
+    document.body.appendChild(testContainer);
 
-      testContainer.innerHTML = '<div style="width:500px;height:500px"><div id="test">hello</div></div>';
+    testContainer.innerHTML = '<div style="width:500px;height:500px"><div id="test">hello</div></div>';
 
-      e = document.getElementById('test');
-      var lastSheet = document.styleSheets[document.styleSheets.length - 1];
-      lastSheet.insertRule("@-webkit-keyframes anim { from { left: 200px; } to { left: 300px;} }", lastSheet.cssRules.length);
+    e = document.getElementById('test');
+    var lastSheet = document.styleSheets[document.styleSheets.length - 1];
+    lastSheet.insertRule("@-webkit-keyframes anim { from { left: 200px; } to { left: 300px;} }", lastSheet.cssRules.length);
 
-      var keyframeRule = lastSheet.cssRules[lastSheet.cssRules.length - 1];
-      assert_equals(keyframeRule.toString(), "[object CSSKeyframesRule]");
-      assert_equals(keyframeRule.type, 7);
-      assert_equals(keyframeRule.name, "anim");
-      assert_equals(keyframeRule.findRule('from').cssText, "0% { left: 200px; }");
-      assert_equals(keyframeRule.findRule('to').cssText, "100% { left: 300px; }");
-      keyframeRule.deleteRule("from");
-      assert_equals(keyframeRule.findRule('from'), null);
-      keyframeRule.appendRule("from { left: 200px; }");
-      assert_equals(keyframeRule.findRule('from').cssText, "0% { left: 200px; }");
-      assert_equals(keyframeRule.cssRules[0].toString(), "[object CSSKeyframeRule]");
-      assert_equals(keyframeRule.cssRules[0].cssText, "100% { left: 300px; }");
-      assert_equals(keyframeRule.cssRules[0].keyText, "100%");
-      assert_equals(keyframeRule.cssRules[0].style.cssText, "left: 300px;");
-      assert_equals(keyframeRule.cssRules[1].toString(), "[object CSSKeyframeRule]");
-      assert_equals(keyframeRule.cssRules[1].cssText, "0% { left: 200px; }");
-      assert_equals(keyframeRule.cssRules[1].keyText, "0%");
-      assert_equals(keyframeRule.cssRules[1].style.cssText, "left: 200px;");
+    var keyframeRule = lastSheet.cssRules[lastSheet.cssRules.length - 1];
+    assert_equals(keyframeRule.toString(), "[object CSSKeyframesRule]");
+    assert_equals(keyframeRule.type, 7);
+    assert_equals(keyframeRule.name, "anim");
+    assert_equals(keyframeRule.findRule('from').cssText, "0% { left: 200px; }");
+    assert_equals(keyframeRule.findRule('to').cssText, "100% { left: 300px; }");
+    keyframeRule.deleteRule("from");
+    assert_equals(keyframeRule.findRule('from'), null);
+    keyframeRule.appendRule("from { left: 200px; }");
+    assert_equals(keyframeRule.findRule('from').cssText, "0% { left: 200px; }");
+    assert_equals(keyframeRule.cssRules[0].toString(), "[object CSSKeyframeRule]");
+    assert_equals(keyframeRule.cssRules[0].cssText, "100% { left: 300px; }");
+    assert_equals(keyframeRule.cssRules[0].keyText, "100%");
+    assert_equals(keyframeRule.cssRules[0].style.cssText, "left: 300px;");
+    assert_equals(keyframeRule.cssRules[1].toString(), "[object CSSKeyframeRule]");
+    assert_equals(keyframeRule.cssRules[1].cssText, "0% { left: 200px; }");
+    assert_equals(keyframeRule.cssRules[1].keyText, "0%");
+    assert_equals(keyframeRule.cssRules[1].style.cssText, "left: 200px;");
 
-      try {
-        new CSSKeyframesRule().name;
-      } catch (e) {
-        assert_equals(e.message, "Illegal constructor");
-      }
+    try {
+      new CSSKeyframesRule().name;
+    } catch (e) {
+      assert_equals(e.message, "Illegal constructor");
+    }
 
-      document.body.removeChild(testContainer);
-      t.done();
-    });
-  });
+    document.body.removeChild(testContainer);
+  }));
 }, "Test the CSSOM of @-webkit-keyframes");
 </script>
 </body>
diff --git a/third_party/blink/web_tests/animations/prefixed/keyframes-cssom-unprefixed-02.html b/third_party/blink/web_tests/animations/prefixed/keyframes-cssom-unprefixed-02.html
index 3546b580..13cee2a 100644
--- a/third_party/blink/web_tests/animations/prefixed/keyframes-cssom-unprefixed-02.html
+++ b/third_party/blink/web_tests/animations/prefixed/keyframes-cssom-unprefixed-02.html
@@ -17,45 +17,42 @@
 <script src="../../resources/testharnessreport.js"></script>
 <script>
 async_test(t => {
-  window.addEventListener("load", () => {
-    t.step(() => {
-      var testContainer = document.createElement("div");
-      document.body.appendChild(testContainer);
+  window.addEventListener("load", t.step_func_done(() => {
+    var testContainer = document.createElement("div");
+    document.body.appendChild(testContainer);
 
-      testContainer.innerHTML = '<div style="width:500px;height:500px"><div id="test">hello</div></div>';
+    testContainer.innerHTML = '<div style="width:500px;height:500px"><div id="test">hello</div></div>';
 
-      e = document.getElementById('test');
-      var lastSheet = document.styleSheets[document.styleSheets.length - 1];
-      lastSheet.insertRule("@keyframes anim { from { left: 200px; } to { left: 300px;} }", lastSheet.cssRules.length);
+    e = document.getElementById('test');
+    var lastSheet = document.styleSheets[document.styleSheets.length - 1];
+    lastSheet.insertRule("@keyframes anim { from { left: 200px; } to { left: 300px;} }", lastSheet.cssRules.length);
 
-      var keyframeRule = lastSheet.cssRules[lastSheet.cssRules.length - 1];
-      assert_equals(keyframeRule.toString(), "[object CSSKeyframesRule]");
-      assert_equals(keyframeRule.type, 7);
-      assert_equals(keyframeRule.name, "anim");
-      assert_equals(keyframeRule.findRule('from').cssText, "0% { left: 200px; }");
-      assert_equals(keyframeRule.findRule('to').cssText, "100% { left: 300px; }");
-      keyframeRule.deleteRule("from");
-      assert_equals(keyframeRule.findRule('from'), null);
-      keyframeRule.appendRule("from { left: 200px; }");
-      assert_equals(keyframeRule.findRule('from').cssText, "0% { left: 200px; }");
-      assert_equals(keyframeRule.cssRules[0].toString(), "[object CSSKeyframeRule]");
-      assert_equals(keyframeRule.cssRules[0].cssText, "100% { left: 300px; }");
-      assert_equals(keyframeRule.cssRules[0].keyText, "100%");
-      assert_equals(keyframeRule.cssRules[0].style.cssText, "left: 300px;");
-      assert_equals(keyframeRule.cssRules[1].toString(), "[object CSSKeyframeRule]");
-      assert_equals(keyframeRule.cssRules[1].cssText, "0% { left: 200px; }");
-      assert_equals(keyframeRule.cssRules[1].keyText, "0%");
-      assert_equals(keyframeRule.cssRules[1].style.cssText, "left: 200px;");
+    var keyframeRule = lastSheet.cssRules[lastSheet.cssRules.length - 1];
+    assert_equals(keyframeRule.toString(), "[object CSSKeyframesRule]");
+    assert_equals(keyframeRule.type, 7);
+    assert_equals(keyframeRule.name, "anim");
+    assert_equals(keyframeRule.findRule('from').cssText, "0% { left: 200px; }");
+    assert_equals(keyframeRule.findRule('to').cssText, "100% { left: 300px; }");
+    keyframeRule.deleteRule("from");
+    assert_equals(keyframeRule.findRule('from'), null);
+    keyframeRule.appendRule("from { left: 200px; }");
+    assert_equals(keyframeRule.findRule('from').cssText, "0% { left: 200px; }");
+    assert_equals(keyframeRule.cssRules[0].toString(), "[object CSSKeyframeRule]");
+    assert_equals(keyframeRule.cssRules[0].cssText, "100% { left: 300px; }");
+    assert_equals(keyframeRule.cssRules[0].keyText, "100%");
+    assert_equals(keyframeRule.cssRules[0].style.cssText, "left: 300px;");
+    assert_equals(keyframeRule.cssRules[1].toString(), "[object CSSKeyframeRule]");
+    assert_equals(keyframeRule.cssRules[1].cssText, "0% { left: 200px; }");
+    assert_equals(keyframeRule.cssRules[1].keyText, "0%");
+    assert_equals(keyframeRule.cssRules[1].style.cssText, "left: 200px;");
 
-      try {
-        new CSSKeyframesRule().name;
-      } catch (e) {
-        assert_equals(e.message, "Illegal constructor");
-      }
+    try {
+      new CSSKeyframesRule().name;
+    } catch (e) {
+      assert_equals(e.message, "Illegal constructor");
+    }
 
-      document.body.removeChild(testContainer);
-      t.done();
-    });
-  });
+    document.body.removeChild(testContainer);
+  }));
 }, "Test the CSSOM of @keyframes");
 </script>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index fc66b28..e2c35e4e 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -145,12 +145,6 @@
      {}
     ]
    ],
-   "clipboard-apis/async-write-duplicate-mime-type-manual.https.html": [
-    [
-     "/clipboard-apis/async-write-duplicate-mime-type-manual.https.html",
-     {}
-    ]
-   ],
    "clipboard-apis/async-write-image-read-image-manual.https.html": [
     [
      "/clipboard-apis/async-write-image-read-image-manual.https.html",
@@ -4423,42 +4417,6 @@
      {}
     ]
    ],
-   "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-locationbar-manual.html": [
-    [
-     "/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-locationbar-manual.html",
-     {}
-    ]
-   ],
-   "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-menubar-manual.html": [
-    [
-     "/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-menubar-manual.html",
-     {}
-    ]
-   ],
-   "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-personalbar-manual.html": [
-    [
-     "/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-personalbar-manual.html",
-     {}
-    ]
-   ],
-   "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-scrollbars-manual.html": [
-    [
-     "/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-scrollbars-manual.html",
-     {}
-    ]
-   ],
-   "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-statusbar-manual.html": [
-    [
-     "/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-statusbar-manual.html",
-     {}
-    ]
-   ],
-   "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-toolbar-manual.html": [
-    [
-     "/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-toolbar-manual.html",
-     {}
-    ]
-   ],
    "html/browsers/windows/noreferrer-cross-origin-close-manual.sub.html": [
     [
      "/html/browsers/windows/noreferrer-cross-origin-close-manual.sub.html",
@@ -5923,12 +5881,6 @@
      {}
     ]
    ],
-   "pointerevents/pointerevent_pointercancel_touch-manual.html": [
-    [
-     "/pointerevents/pointerevent_pointercancel_touch-manual.html",
-     {}
-    ]
-   ],
    "pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html": [
     [
      "/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html",
@@ -7005,6 +6957,18 @@
      {}
     ]
    ],
+   "animation-worklet/worklet-animation-with-non-ascii-name.https.html": [
+    [
+     "/animation-worklet/worklet-animation-with-non-ascii-name.https.html",
+     [
+      [
+       "/animation-worklet/worklet-animation-with-non-ascii-name-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html": [
     [
      "/animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html",
@@ -106761,6 +106725,30 @@
      {}
     ]
    ],
+   "html/rendering/non-replaced-elements/tables/table-border-3q.html": [
+    [
+     "/html/rendering/non-replaced-elements/tables/table-border-3q.html",
+     [
+      [
+       "/html/rendering/non-replaced-elements/tables/table-border-3-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "html/rendering/non-replaced-elements/tables/table-border-3s.html": [
+    [
+     "/html/rendering/non-replaced-elements/tables/table-border-3s.html",
+     [
+      [
+       "/html/rendering/non-replaced-elements/tables/table-border-3-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "html/rendering/non-replaced-elements/tables/table-cell-width-s.html": [
     [
      "/html/rendering/non-replaced-elements/tables/table-cell-width-s.html",
@@ -110809,6 +110797,54 @@
      {}
     ]
    ],
+   "svg/struct/reftests/use-svg-dimensions-override-001.svg": [
+    [
+     "/svg/struct/reftests/use-svg-dimensions-override-001.svg",
+     [
+      [
+       "/svg/struct/reftests/reference/green-100x100.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/struct/reftests/use-svg-dimensions-override-002.svg": [
+    [
+     "/svg/struct/reftests/use-svg-dimensions-override-002.svg",
+     [
+      [
+       "/svg/struct/reftests/reference/green-100x100.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/struct/reftests/use-symbol-dimensions-override-001.svg": [
+    [
+     "/svg/struct/reftests/use-symbol-dimensions-override-001.svg",
+     [
+      [
+       "/svg/struct/reftests/reference/green-100x100.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/struct/reftests/use-symbol-dimensions-override-002.svg": [
+    [
+     "/svg/struct/reftests/use-symbol-dimensions-override-002.svg",
+     [
+      [
+       "/svg/struct/reftests/reference/green-100x100.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "svg/styling/render/transform-box.svg": [
     [
      "/svg/styling/render/transform-box.svg",
@@ -111025,6 +111061,90 @@
      {}
     ]
    ],
+   "svg/text/reftests/text-text-anchor-001.svg": [
+    [
+     "/svg/text/reftests/text-text-anchor-001.svg",
+     [
+      [
+       "/svg/text/reftests/text-text-anchor-001-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-002.svg": [
+    [
+     "/svg/text/reftests/text-text-anchor-002.svg",
+     [
+      [
+       "/svg/text/reftests/text-text-anchor-002-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-003.svg": [
+    [
+     "/svg/text/reftests/text-text-anchor-003.svg",
+     [
+      [
+       "/svg/text/reftests/text-text-anchor-003-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-102.svg": [
+    [
+     "/svg/text/reftests/text-text-anchor-102.svg",
+     [
+      [
+       "/svg/text/reftests/text-text-anchor-102-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-201.svg": [
+    [
+     "/svg/text/reftests/text-text-anchor-201.svg",
+     [
+      [
+       "/svg/text/reftests/text-text-anchor-201-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-202.svg": [
+    [
+     "/svg/text/reftests/text-text-anchor-202.svg",
+     [
+      [
+       "/svg/text/reftests/text-text-anchor-202-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-203.svg": [
+    [
+     "/svg/text/reftests/text-text-anchor-203.svg",
+     [
+      [
+       "/svg/text/reftests/text-text-anchor-003-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "svg/text/reftests/textpath-shape-001.svg": [
     [
      "/svg/text/reftests/textpath-shape-001.svg",
@@ -116544,6 +116664,16 @@
      {}
     ]
    ],
+   "IndexedDB/idbcursor-request.any-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "IndexedDB/idbcursor-request.any.worker-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "IndexedDB/idbobjectstore_createIndex15-autoincrement-expected.txt": [
     [
      {}
@@ -116554,6 +116684,26 @@
      {}
     ]
    ],
+   "IndexedDB/idlharness.any-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "IndexedDB/idlharness.any.serviceworker-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "IndexedDB/idlharness.any.sharedworker-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "IndexedDB/idlharness.any.worker-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "IndexedDB/interleaved-cursors-common.js": [
     [
      {}
@@ -118169,6 +118319,11 @@
      {}
     ]
    ],
+   "animation-worklet/worklet-animation-with-non-ascii-name-ref.html": [
+    [
+     {}
+    ]
+   ],
    "animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden-ref.html": [
     [
      {}
@@ -118699,6 +118854,11 @@
      {}
     ]
    ],
+   "clipboard-apis/async-interfaces.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "clipboard-apis/resources/greenbox.png": [
     [
      {}
@@ -158589,11 +158749,6 @@
      {}
     ]
    ],
-   "custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "custom-elements/perform-microtask-checkpoint-before-construction-expected.txt": [
     [
      {}
@@ -165419,11 +165574,6 @@
      {}
     ]
    ],
-   "html/browsers/history/the-location-interface/reload_document_open_write-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/browsers/history/the-location-interface/reload_document_write-1.html": [
     [
      {}
@@ -171229,6 +171379,11 @@
      {}
     ]
    ],
+   "html/rendering/non-replaced-elements/tables/table-border-3-ref.html": [
+    [
+     {}
+    ]
+   ],
    "html/rendering/non-replaced-elements/tables/table-cell-width-ref.html": [
     [
      {}
@@ -176729,11 +176884,6 @@
      {}
     ]
    ],
-   "interfaces/ResizeObserver.idl": [
-    [
-     {}
-    ]
-   ],
    "interfaces/SRI.idl": [
     [
      {}
@@ -177204,6 +177354,11 @@
      {}
     ]
    ],
+   "interfaces/resize-observer.idl": [
+    [
+     {}
+    ]
+   ],
    "interfaces/resource-timing.idl": [
     [
      {}
@@ -180744,6 +180899,16 @@
      {}
     ]
    ],
+   "pointerevents/resources/pointerevent_mouse_pointercapture-iframe.html": [
+    [
+     {}
+    ]
+   ],
+   "pointerevents/resources/pointerevent_mouse_pointercapture_inactivate_pointer-iframe.html": [
+    [
+     {}
+    ]
+   ],
    "pointerevents/resources/pointerevent_pointerId_scope-iframe.html": [
     [
      {}
@@ -184724,6 +184889,26 @@
      {}
     ]
    ],
+   "resources/chromium/mock-barcodedetection.js": [
+    [
+     {}
+    ]
+   ],
+   "resources/chromium/mock-barcodedetection.js.headers": [
+    [
+     {}
+    ]
+   ],
+   "resources/chromium/mock-facedetection.js": [
+    [
+     {}
+    ]
+   ],
+   "resources/chromium/mock-facedetection.js.headers": [
+    [
+     {}
+    ]
+   ],
    "resources/chromium/mock-imagecapture.js": [
     [
      {}
@@ -188299,11 +188484,26 @@
      {}
     ]
    ],
+   "shape-detection/README.md": [
+    [
+     {}
+    ]
+   ],
    "shape-detection/idlharness.any-expected.txt": [
     [
      {}
     ]
    ],
+   "shape-detection/idlharness.any.worker-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "shape-detection/resources/shapedetection-helpers.js": [
+    [
+     {}
+    ]
+   ],
    "signed-exchange/META.yml": [
     [
      {}
@@ -188604,6 +188804,11 @@
      {}
     ]
    ],
+   "speech-api/SpeechSynthesisEvent-constructor-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "speech-api/SpeechSynthesisUtterance-basics.https-expected.txt": [
     [
      {}
@@ -189699,6 +189904,11 @@
      {}
     ]
    ],
+   "svg/struct/reftests/reference/green-100x100.svg": [
+    [
+     {}
+    ]
+   ],
    "svg/styling/render/transform-box-ref.svg": [
     [
      {}
@@ -189814,6 +190024,41 @@
      {}
     ]
    ],
+   "svg/text/reftests/text-text-anchor-001-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-002-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-003-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-102-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-201-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-202-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/text/reftests/text-text-anchor-203-ref.svg": [
+    [
+     {}
+    ]
+   ],
    "svg/text/reftests/textpath-shape-001-ref.svg": [
     [
      {}
@@ -195749,6 +195994,16 @@
      {}
     ]
    ],
+   "tools/wptrunner/wptrunner/formatters/chromium.py": [
+    [
+     {}
+    ]
+   ],
+   "tools/wptrunner/wptrunner/formatters/tests/test_chromium.py": [
+    [
+     {}
+    ]
+   ],
    "tools/wptrunner/wptrunner/formatters/wptreport.py": [
     [
      {}
@@ -195799,6 +196054,11 @@
      {}
     ]
    ],
+   "tools/wptrunner/wptrunner/testharness_runner.html": [
+    [
+     {}
+    ]
+   ],
    "tools/wptrunner/wptrunner/testharnessreport-servo.js": [
     [
      {}
@@ -196959,11 +197219,6 @@
      {}
     ]
    ],
-   "wasm/jsapi/memory/constructor.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "wasm/jsapi/memory/constructor.any.worker-expected.txt": [
     [
      {}
@@ -196979,16 +197234,6 @@
      {}
     ]
    ],
-   "wasm/jsapi/module/customSections.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/jsapi/module/customSections.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "wasm/jsapi/table/assertions.js": [
     [
      {}
@@ -198779,11 +199024,6 @@
      {}
     ]
    ],
-   "webrtc/RTCSctpTransport-constructor-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "webrtc/RTCSctpTransport-maxMessageSize-expected.txt": [
     [
      {}
@@ -202819,11 +203059,6 @@
      {}
     ]
    ],
-   "xhr/formdata-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "xhr/getallresponseheaders-expected.txt": [
     [
      {}
@@ -202999,6 +203234,16 @@
      {}
     ]
    ],
+   "xhr/resources/auth10/auth.py": [
+    [
+     {}
+    ]
+   ],
+   "xhr/resources/auth11/auth.py": [
+    [
+     {}
+    ]
+   ],
    "xhr/resources/auth2/auth.py": [
     [
      {}
@@ -208915,6 +209160,16 @@
      {}
     ]
    ],
+   "IndexedDB/idbcursor-request.any.js": [
+    [
+     "/IndexedDB/idbcursor-request.any.html",
+     {}
+    ],
+    [
+     "/IndexedDB/idbcursor-request.any.worker.html",
+     {}
+    ]
+   ],
    "IndexedDB/idbcursor-reused.htm": [
     [
      "/IndexedDB/idbcursor-reused.htm",
@@ -220633,6 +220888,12 @@
      {}
     ]
    ],
+   "css/css-grid/alignment/grid-container-baseline-001.html": [
+    [
+     "/css/css-grid/alignment/grid-container-baseline-001.html",
+     {}
+    ]
+   ],
    "css/css-grid/alignment/grid-content-alignment-second-pass-001.html": [
     [
      "/css/css-grid/alignment/grid-content-alignment-second-pass-001.html",
@@ -222793,12 +223054,24 @@
      {}
     ]
    ],
+   "css/css-position/position-absolute-crash-chrome-003.html": [
+    [
+     "/css/css-position/position-absolute-crash-chrome-003.html",
+     {}
+    ]
+   ],
    "css/css-position/position-absolute-dynamic-containing-block.html": [
     [
      "/css/css-position/position-absolute-dynamic-containing-block.html",
      {}
     ]
    ],
+   "css/css-position/position-absolute-in-inline-001.html": [
+    [
+     "/css/css-position/position-absolute-in-inline-001.html",
+     {}
+    ]
+   ],
    "css/css-position/position-absolute-in-inline-crash.html": [
     [
      "/css/css-position/position-absolute-in-inline-crash.html",
@@ -224539,6 +224812,12 @@
      {}
     ]
    ],
+   "css/css-tables/caption-writing-mode-002.html": [
+    [
+     "/css/css-tables/caption-writing-mode-002.html",
+     {}
+    ]
+   ],
    "css/css-tables/fixed-layout-1.html": [
     [
      "/css/css-tables/fixed-layout-1.html",
@@ -232647,7 +232926,8 @@
     [
      "/dom/events/Event-dispatch-on-disabled-elements.html",
      {
-      "testdriver": true
+      "testdriver": true,
+      "timeout": "long"
      }
     ]
    ],
@@ -248257,6 +248537,12 @@
      {}
     ]
    ],
+   "html/browsers/the-window-object/BarProp.window.js": [
+    [
+     "/html/browsers/the-window-object/BarProp.window.html",
+     {}
+    ]
+   ],
    "html/browsers/the-window-object/Document-defaultView.html": [
     [
      "/html/browsers/the-window-object/Document-defaultView.html",
@@ -258795,6 +259081,12 @@
      {}
     ]
    ],
+   "html/webappapis/dynamic-markup-insertion/closing-the-input-stream/load-event-after-location-set-during-write.window.js": [
+    [
+     "/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/load-event-after-location-set-during-write.window.html",
+     {}
+    ]
+   ],
    "html/webappapis/dynamic-markup-insertion/document-write/001.html": [
     [
      "/html/webappapis/dynamic-markup-insertion/document-write/001.html",
@@ -275817,12 +276109,44 @@
      }
     ]
    ],
+   "pointerevents/pointerevent_mouse_capture_change_hover.html": [
+    [
+     "/pointerevents/pointerevent_mouse_capture_change_hover.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
+   "pointerevents/pointerevent_mouse_pointercapture_in_frame.html": [
+    [
+     "/pointerevents/pointerevent_mouse_pointercapture_in_frame.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
+   "pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html": [
+    [
+     "/pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "pointerevents/pointerevent_on_event_handlers.html": [
     [
      "/pointerevents/pointerevent_on_event_handlers.html",
      {}
     ]
    ],
+   "pointerevents/pointerevent_pointercancel_touch.html": [
+    [
+     "/pointerevents/pointerevent_pointercancel_touch.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "pointerevents/pointerevent_pointerenter_does_not_bubble.html": [
     [
      "/pointerevents/pointerevent_pointerenter_does_not_bubble.html",
@@ -287855,7 +288179,9 @@
    "service-workers/service-worker/extendable-event-async-waituntil.https.html": [
     [
      "/service-workers/service-worker/extendable-event-async-waituntil.https.html",
-     {}
+     {
+      "timeout": "long"
+     }
     ]
    ],
    "service-workers/service-worker/extendable-event-waituntil.https.html": [
@@ -289410,6 +289736,72 @@
      {}
     ]
    ],
+   "shape-detection/detected-boundingBox-read-only.html": [
+    [
+     "/shape-detection/detected-boundingBox-read-only.html",
+     {}
+    ]
+   ],
+   "shape-detection/detection-HTMLCanvasElement.html": [
+    [
+     "/shape-detection/detection-HTMLCanvasElement.html",
+     {}
+    ]
+   ],
+   "shape-detection/detection-HTMLImageElement.html": [
+    [
+     "/shape-detection/detection-HTMLImageElement.html",
+     {}
+    ]
+   ],
+   "shape-detection/detection-HTMLVideoElement.html": [
+    [
+     "/shape-detection/detection-HTMLVideoElement.html",
+     {}
+    ]
+   ],
+   "shape-detection/detection-ImageBitmap.html": [
+    [
+     "/shape-detection/detection-ImageBitmap.html",
+     {}
+    ]
+   ],
+   "shape-detection/detection-ImageData.html": [
+    [
+     "/shape-detection/detection-ImageData.html",
+     {}
+    ]
+   ],
+   "shape-detection/detection-getSupportedFormats.html": [
+    [
+     "/shape-detection/detection-getSupportedFormats.html",
+     {}
+    ]
+   ],
+   "shape-detection/detection-on-worker.worker.js": [
+    [
+     "/shape-detection/detection-on-worker.worker.html",
+     {}
+    ]
+   ],
+   "shape-detection/detection-options.html": [
+    [
+     "/shape-detection/detection-options.html",
+     {}
+    ]
+   ],
+   "shape-detection/detection-security-test.html": [
+    [
+     "/shape-detection/detection-security-test.html",
+     {}
+    ]
+   ],
+   "shape-detection/detector-same-object.html": [
+    [
+     "/shape-detection/detector-same-object.html",
+     {}
+    ]
+   ],
    "shape-detection/idlharness.any.js": [
     [
      "/shape-detection/idlharness.any.html",
@@ -289420,6 +289812,18 @@
      {}
     ]
    ],
+   "shape-detection/shapedetection-cross-origin.sub.html": [
+    [
+     "/shape-detection/shapedetection-cross-origin.sub.html",
+     {}
+    ]
+   ],
+   "shape-detection/shapedetection-empty-input.html": [
+    [
+     "/shape-detection/shapedetection-empty-input.html",
+     {}
+    ]
+   ],
    "signed-exchange/check-cert-request.tentative.html": [
     [
      "/signed-exchange/check-cert-request.tentative.html",
@@ -300920,6 +301324,12 @@
      {}
     ]
    ],
+   "webxr/xrRigidTransform_inverse.https.html": [
+    [
+     "/webxr/xrRigidTransform_inverse.https.html",
+     {}
+    ]
+   ],
    "webxr/xrRigidTransform_matrix.https.html": [
     [
      "/webxr/xrRigidTransform_matrix.https.html",
@@ -301086,6 +301496,26 @@
      {}
     ]
    ],
+   "workers/Worker-custom-event.any.js": [
+    [
+     "/workers/Worker-custom-event.any.serviceworker.html",
+     {}
+    ],
+    [
+     "/workers/Worker-custom-event.any.sharedworker.html",
+     {}
+    ],
+    [
+     "/workers/Worker-custom-event.any.worker.html",
+     {}
+    ]
+   ],
+   "workers/Worker-formdata.any.js": [
+    [
+     "/workers/Worker-formdata.any.worker.html",
+     {}
+    ]
+   ],
    "workers/Worker-location.sub.any.js": [
     [
      "/workers/Worker-location.sub.any.sharedworker.html",
@@ -301114,6 +301544,20 @@
      {}
     ]
    ],
+   "workers/Worker-replace-event-handler.any.js": [
+    [
+     "/workers/Worker-replace-event-handler.any.serviceworker.html",
+     {}
+    ],
+    [
+     "/workers/Worker-replace-event-handler.any.sharedworker.html",
+     {}
+    ],
+    [
+     "/workers/Worker-replace-event-handler.any.worker.html",
+     {}
+    ]
+   ],
    "workers/Worker-replace-global-constructor.any.js": [
     [
      "/workers/Worker-replace-global-constructor.any.serviceworker.html",
@@ -301340,6 +301784,20 @@
      {}
     ]
    ],
+   "workers/WorkerNavigator-hardware-concurrency.any.js": [
+    [
+     "/workers/WorkerNavigator-hardware-concurrency.any.serviceworker.html",
+     {}
+    ],
+    [
+     "/workers/WorkerNavigator-hardware-concurrency.any.sharedworker.html",
+     {}
+    ],
+    [
+     "/workers/WorkerNavigator-hardware-concurrency.any.worker.html",
+     {}
+    ]
+   ],
    "workers/WorkerNavigator.any.js": [
     [
      "/workers/WorkerNavigator.any.serviceworker.html",
@@ -303870,15 +304328,23 @@
      {}
     ]
    ],
-   "xhr/send-data-arraybuffer.htm": [
+   "xhr/send-data-arraybuffer.any.js": [
     [
-     "/xhr/send-data-arraybuffer.htm",
+     "/xhr/send-data-arraybuffer.any.html",
+     {}
+    ],
+    [
+     "/xhr/send-data-arraybuffer.any.worker.html",
      {}
     ]
    ],
-   "xhr/send-data-arraybufferview.htm": [
+   "xhr/send-data-arraybufferview.any.js": [
     [
-     "/xhr/send-data-arraybufferview.htm",
+     "/xhr/send-data-arraybufferview.any.html",
+     {}
+    ],
+    [
+     "/xhr/send-data-arraybufferview.any.worker.html",
      {}
     ]
    ],
@@ -303888,15 +304354,23 @@
      {}
     ]
    ],
-   "xhr/send-data-es-object.htm": [
+   "xhr/send-data-es-object.any.js": [
     [
-     "/xhr/send-data-es-object.htm",
+     "/xhr/send-data-es-object.any.html",
+     {}
+    ],
+    [
+     "/xhr/send-data-es-object.any.worker.html",
      {}
     ]
    ],
-   "xhr/send-data-formdata.htm": [
+   "xhr/send-data-formdata.any.js": [
     [
-     "/xhr/send-data-formdata.htm",
+     "/xhr/send-data-formdata.any.html",
+     {}
+    ],
+    [
+     "/xhr/send-data-formdata.any.worker.html",
      {}
     ]
    ],
@@ -311676,7 +312150,7 @@
  },
  "paths": {
   ".gitignore": [
-   "ad1e88ef593eec0e2e2da4a3c90bf554d457b2e2",
+   "23df18a95551f2c6e1fbc2417b9be1b84e0b1b14",
    "support"
   ],
   ".well-known/README.md": [
@@ -314200,7 +314674,7 @@
    "testharness"
   ],
   "2dcontext/imagebitmap/createImageBitmap-origin.sub.html": [
-   "24848f3d54d833b029bc0380ff365a2c6737bb44",
+   "ae8c70f9c0799c8834f0167a47e7040a5927514c",
    "testharness"
   ],
   "2dcontext/imagebitmap/createImageBitmap-sizeOverflow.html": [
@@ -316587,6 +317061,18 @@
    "9216a0c4416b47ab5ab51e0b407429512a0125d2",
    "testharness"
   ],
+  "IndexedDB/idbcursor-request.any-expected.txt": [
+   "c28fc3283d251184f7634ab7a6e793d1e0da90c3",
+   "support"
+  ],
+  "IndexedDB/idbcursor-request.any.js": [
+   "a62efc0b8eb7a39dffd0e3414b46d9c2969fc0d7",
+   "testharness"
+  ],
+  "IndexedDB/idbcursor-request.any.worker-expected.txt": [
+   "c28fc3283d251184f7634ab7a6e793d1e0da90c3",
+   "support"
+  ],
   "IndexedDB/idbcursor-reused.htm": [
    "603041e7cdf98bcbbf9a513970902db72b038e97",
    "testharness"
@@ -317651,10 +318137,26 @@
    "359f6fb69119b5c6605047f0e0c38ef6fe847009",
    "support"
   ],
+  "IndexedDB/idlharness.any-expected.txt": [
+   "b2a16a0835f199d09bac21cfffa04049197c1aaa",
+   "support"
+  ],
   "IndexedDB/idlharness.any.js": [
    "efb84661e8044d146ab0704f18a6a3805ff3c803",
    "testharness"
   ],
+  "IndexedDB/idlharness.any.serviceworker-expected.txt": [
+   "2dc632ce8fc9d0fde57e9ce1f7e876b59f656bf6",
+   "support"
+  ],
+  "IndexedDB/idlharness.any.sharedworker-expected.txt": [
+   "2dc632ce8fc9d0fde57e9ce1f7e876b59f656bf6",
+   "support"
+  ],
+  "IndexedDB/idlharness.any.worker-expected.txt": [
+   "2dc632ce8fc9d0fde57e9ce1f7e876b59f656bf6",
+   "support"
+  ],
   "IndexedDB/index_sort_order.htm": [
    "6249c4204897ffd9f292908ca50dae6f8655c02e",
    "testharness"
@@ -319651,6 +320153,14 @@
    "8b72d4e487c455f5e3d4d535a4ddf277fd988d01",
    "testharness"
   ],
+  "animation-worklet/worklet-animation-with-non-ascii-name-ref.html": [
+   "012f6f9d510581f577d8794f31badecb863d0698",
+   "support"
+  ],
+  "animation-worklet/worklet-animation-with-non-ascii-name.https.html": [
+   "d3a3f4ad35c6b297f8f47b5702a4d7d3877bae37",
+   "reftest"
+  ],
   "animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html": [
    "6f981854d38877d42b1c7b63afdb9ec989a32d42",
    "reftest"
@@ -321015,36 +321525,36 @@
    "f45bd507d9b0a107e33e55c8edf312cb08f42a0a",
    "support"
   ],
+  "clipboard-apis/async-interfaces.https-expected.txt": [
+   "6719ecbeee21795978d31cb29f0d0a7605067cd2",
+   "support"
+  ],
   "clipboard-apis/async-interfaces.https.html": [
    "0617ac11ac2e7dbc2cac3f0665e2df121d1ae477",
    "testharness"
   ],
   "clipboard-apis/async-navigator-clipboard-basics.https.html": [
-   "2d2ebf6c6c2667e1e2e465baa3dd78b657b97a7c",
+   "7d2cba8b5090d1ef268ddc6d159d1e06a49a3158",
    "testharness"
   ],
   "clipboard-apis/async-write-blobs-read-blobs-manual.https.html": [
-   "e616b5ed794bfd38dbd2199685c622e7ee01ec15",
+   "3666c93df027fd3962d0b31a6735dc56651ecd58",
    "manual"
   ],
   "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [
-   "bc8511efa72c6c7db097f2a35d1b864d92359039",
+   "44c574247825612ec906ba42d3f0171a97a17668",
    "manual"
   ],
   "clipboard-apis/async-write-blobtext-read-text-manual.https.html": [
-   "b1b85de65e8b3bdef5a462152946617082041d79",
-   "manual"
-  ],
-  "clipboard-apis/async-write-duplicate-mime-type-manual.https.html": [
-   "8e249fc993a810ff1bec41c4ecbccdac8c2982c4",
+   "c991f1fd324a330d4b322a1f33bb07a0f6ad6199",
    "manual"
   ],
   "clipboard-apis/async-write-image-read-image-manual.https.html": [
-   "76d3d872c980447d46da093800dff8e1116b215d",
+   "2a32348507f7206316f5851e2ff1f6dc6829fbdb",
    "manual"
   ],
   "clipboard-apis/async-write-text-read-blobtext-manual.https.html": [
-   "b54fa609b655d08083bfddd382cd76bb6447392f",
+   "24e6b6ed3cc3510f21620d86769e0fdfa3e0a9cb",
    "manual"
   ],
   "clipboard-apis/async-write-text-read-text-manual.https.html": [
@@ -321188,7 +321698,7 @@
    "support"
   ],
   "common/object-association.js": [
-   "e1ab07e71088828a28fe17b0dd02cbd978c68236",
+   "d58f94b62d652ad2879eb83821ba278b56006f7b",
    "support"
   ],
   "common/object-association.js.headers": [
@@ -340212,7 +340722,7 @@
    "reftest"
   ],
   "css/CSS2/text/white-space-003.xht": [
-   "239a554d461e0962b9c8e3229442941462dd031f",
+   "cf9f539461e80ab57b03753ea99607ac25b0cd32",
    "reftest"
   ],
   "css/CSS2/text/white-space-004-ref.xht": [
@@ -340528,11 +341038,11 @@
    "visual"
   ],
   "css/CSS2/text/white-space-pre-element-001-ref.xht": [
-   "f000117e8bc0bc7b748daaebe2c6f6e8ed691993",
+   "fecdfb157d1af506df724120616f9b2d818e85d9",
    "support"
   ],
   "css/CSS2/text/white-space-pre-element-001.xht": [
-   "cf49962d3731cb1d338a3e311de45cc8d8b31768",
+   "7ec2ba896d44d285ebd49649236bb2dddc534bf4",
    "reftest"
   ],
   "css/CSS2/text/white-space-processing-001.xht": [
@@ -340712,7 +341222,7 @@
    "reftest"
   ],
   "css/CSS2/text/white-space-processing-040.xht": [
-   "857107ea28302d5c6582a821548597a9fe429d5c",
+   "03245a2b0a2071d54330aaf9294661c5d46c74c1",
    "reftest"
   ],
   "css/CSS2/text/white-space-processing-041.xht": [
@@ -360139,6 +360649,10 @@
    "3630eee37558bfa33c84b9c5ec467224b747edef",
    "testharness"
   ],
+  "css/css-grid/alignment/grid-container-baseline-001.html": [
+   "d352977f9318395d0fa0c882bc6e1b9754da29ac",
+   "testharness"
+  ],
   "css/css-grid/alignment/grid-content-alignment-second-pass-001.html": [
    "5b4bbabbb160079796aa4eb6786ea15383f6dd75",
    "testharness"
@@ -366988,13 +367502,21 @@
    "testharness"
   ],
   "css/css-position/position-absolute-crash-chrome-002.html": [
-   "9a4ff0ae58349d7be0583b9e8ccc6bcf6104ab89",
+   "e7ed1daba51f9f8557f63272ccd6f502812af82e",
+   "testharness"
+  ],
+  "css/css-position/position-absolute-crash-chrome-003.html": [
+   "c443e836e57a361c7de9bc5f9a6debe7ff832fe0",
    "testharness"
   ],
   "css/css-position/position-absolute-dynamic-containing-block.html": [
    "3968f685849663574ca213fcb90dc5fb3eaffaa3",
    "testharness"
   ],
+  "css/css-position/position-absolute-in-inline-001.html": [
+   "204260ee6784c9e648ab9f1e86b113f0d7227e22",
+   "testharness"
+  ],
   "css/css-position/position-absolute-in-inline-crash.html": [
    "5d36710b6fe694b256d9841b3e7a0fff4535c85b",
    "testharness"
@@ -367628,7 +368150,7 @@
    "testharness"
   ],
   "css/css-pseudo/idlharness-expected.txt": [
-   "c7e205c6aa936728a33cfe6cc50b8ef0ad2049b2",
+   "977415282ae39a096e46008e91d55452f5244b02",
    "support"
   ],
   "css/css-pseudo/idlharness.html": [
@@ -370527,6 +371049,10 @@
    "835a5116ae36bca9f92698b7766d0b65f1514f9f",
    "testharness"
   ],
+  "css/css-tables/caption-writing-mode-002.html": [
+   "8a2b60864228d2d79af3ad18e6b8366e340dbbe3",
+   "testharness"
+  ],
   "css/css-tables/fixed-layout-1.html": [
    "3e0d013af1c6970a1180cf19db37e8e7b82cc0c0",
    "testharness"
@@ -383280,7 +383806,7 @@
    "testharness"
   ],
   "css/css-typed-om/interfaces-expected.txt": [
-   "caef6ac0dd647e3ffcf987044e7b84740aa4bb69",
+   "24e1caa9834da817fab540fa7bd2dbc93b7554e8",
    "support"
   ],
   "css/css-typed-om/interfaces.html": [
@@ -384892,7 +385418,7 @@
    "support"
   ],
   "css/css-ui/appearance-cssom-001-expected.txt": [
-   "ee395e8f73167c3eadae57e5fe76af4eed79aad9",
+   "5c7b72de572003688f50cdf269e2ddd6db1e601a",
    "support"
   ],
   "css/css-ui/appearance-cssom-001.html": [
@@ -404096,7 +404622,7 @@
    "reftest"
   ],
   "custom-elements/CustomElementRegistry-expected.txt": [
-   "d67fab0dd5d9253f1f3fea522deaa3850c3d84e4",
+   "a93d4f860d6dfb1119938a25181c81f9e65457c7",
    "support"
   ],
   "custom-elements/CustomElementRegistry.html": [
@@ -404164,7 +404690,7 @@
    "testharness"
   ],
   "custom-elements/custom-element-registry/per-global-expected.txt": [
-   "ec470d232543c9f2ccf3b9e6838cdbd0b40b5824",
+   "b6ce8a322bfc8f0a53c3bffa96fd6d3753f259ef",
    "support"
   ],
   "custom-elements/custom-element-registry/per-global.html": [
@@ -404239,12 +404765,8 @@
    "526de0f63fa2afbe9382eeae35369a3123a83fee",
    "testharness"
   ],
-  "custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt": [
-   "35cb638573fad9e71ff37c427f5a38a54853a88c",
-   "support"
-  ],
   "custom-elements/parser/parser-uses-registry-of-owner-document.html": [
-   "51e3e5ddfb1c92e6c2b39cfd3d4b851eabe08775",
+   "bb256da295165f0fee73214460aa519601046c4e",
    "testharness"
   ],
   "custom-elements/parser/serializing-html-fragments.html": [
@@ -404296,7 +404818,7 @@
    "testharness"
   ],
   "custom-elements/reactions/Document.html": [
-   "721ad1f4ced84b8c81291fe92fa402e7b6384358",
+   "1f05982a90cf94e8a0ba79bd107f663ed90eead0",
    "testharness"
   ],
   "custom-elements/reactions/Element.html": [
@@ -404680,7 +405202,7 @@
    "testharness"
   ],
   "dom/events/Event-dispatch-on-disabled-elements.html": [
-   "688524bd23879f7fadb5de3b0b055a2d6b05c065",
+   "a295ce1ef780d551490c41186aecb3dd97c87860",
    "testharness"
   ],
   "dom/events/Event-dispatch-order.html": [
@@ -406380,7 +406902,7 @@
    "testharness"
   ],
   "domparsing/interfaces.any.worker-expected.txt": [
-   "ac6137df9df30045488ad21d7cee76c7e270539c",
+   "80a51032e845bc91a376632d712f50b5245fb71b",
    "support"
   ],
   "domparsing/outerhtml-01.html": [
@@ -409872,7 +410394,7 @@
    "support"
   ],
   "feature-policy/experimental-features/document-write.tentative.html": [
-   "f0148783f1246b6bd60dabd837c64fc6d903e542",
+   "7e09ef7e77a632f81fcc115271c9a74143bd34a7",
    "testharness"
   ],
   "feature-policy/experimental-features/intrinsicsize-with-unsized-media.tentative.https.sub.html": [
@@ -412412,7 +412934,7 @@
    "testharness"
   ],
   "fetch/stale-while-revalidate/stale-css.py": [
-   "9566833e507603a35aadd4de622f388d4f77307f",
+   "a6ae546d0651f97f3020829452db6225486dc451",
    "support"
   ],
   "fetch/stale-while-revalidate/stale-css.tentative.html": [
@@ -412420,7 +412942,7 @@
    "testharness"
   ],
   "fetch/stale-while-revalidate/stale-image.py": [
-   "e0cf94bcd0abc3e2f3aba3ad4448d5f519312335",
+   "4b67184185eb6cf9206bc57e2ca25c3da96643c2",
    "support"
   ],
   "fetch/stale-while-revalidate/stale-image.tentative.html": [
@@ -412428,7 +412950,7 @@
    "testharness"
   ],
   "fetch/stale-while-revalidate/stale-script.py": [
-   "5ea5987db3dd707b7ab77d11d883c0217705aaf6",
+   "8ad54671f4211735f56df50a55deea6ed281d5a2",
    "support"
   ],
   "fetch/stale-while-revalidate/stale-script.tentative.html": [
@@ -415140,7 +415662,7 @@
    "testharness"
   ],
   "html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1-1.html": [
-   "af0118a01e7a2039bef85cfd83473e1845c6b9ad",
+   "945c8d81f8271cc9f67b01b5f0040f76651fd8d0",
    "support"
   ],
   "html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2-1.html": [
@@ -415388,15 +415910,11 @@
    "testharness"
   ],
   "html/browsers/history/the-location-interface/reload_document_open_write-1.html": [
-   "1c5a1db8ff8e81c4ace2d10abc7d23130a1a09f6",
-   "support"
-  ],
-  "html/browsers/history/the-location-interface/reload_document_open_write-expected.txt": [
-   "5dd39b793910cc69f7aa4870f402f254f969bebc",
+   "e1a2e811c9c84317856e30aba05de027070f2142",
    "support"
   ],
   "html/browsers/history/the-location-interface/reload_document_open_write.html": [
-   "0fc2a2c3d8ef4687c4d6f2dbfcaa0ef73fea2b65",
+   "905ef8874307b7052cd7195df6bda131471fdb17",
    "testharness"
   ],
   "html/browsers/history/the-location-interface/reload_document_write-1.html": [
@@ -415779,6 +416297,10 @@
    "bb7ced0a14bad94fe6d6274d297799c8a2e472db",
    "reftest"
   ],
+  "html/browsers/the-window-object/BarProp.window.js": [
+   "27a357cab591c92bab589924f78841ca89e69a71",
+   "testharness"
+  ],
   "html/browsers/the-window-object/Document-defaultView.html": [
    "dbc75d30b213cfa2a94a97815b9d793228ba3be1",
    "testharness"
@@ -416147,30 +416669,6 @@
    "c2446c6fe958a5a0507ffcf729fa027a8d202832",
    "support"
   ],
-  "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-locationbar-manual.html": [
-   "4331b3b66005f377d9d0e456e669f3ac5254fc06",
-   "manual"
-  ],
-  "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-menubar-manual.html": [
-   "43345934a589cc088fc5016a8b049f07875bd474",
-   "manual"
-  ],
-  "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-personalbar-manual.html": [
-   "d7f109840dcf0784106ce4787fa3065071f59c01",
-   "manual"
-  ],
-  "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-scrollbars-manual.html": [
-   "c412bdbe5eec004eaba9e681671b68c6e2e7efa6",
-   "manual"
-  ],
-  "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-statusbar-manual.html": [
-   "b09fcc017585f2374742d7b3e4d2353eee6d120e",
-   "manual"
-  ],
-  "html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-toolbar-manual.html": [
-   "ba465443151f91569fccce0f4df380859341504c",
-   "manual"
-  ],
   "html/browsers/the-window-object/window-aliases.html": [
    "135be02a30add5d51a5b870cbe519d735115d3e9",
    "testharness"
@@ -422283,6 +422781,18 @@
    "6f4f39b113bab7814274c05319119069c6a74e0a",
    "reftest"
   ],
+  "html/rendering/non-replaced-elements/tables/table-border-3-ref.html": [
+   "e465fd433c99a16c8312c98955da1afe190e596f",
+   "support"
+  ],
+  "html/rendering/non-replaced-elements/tables/table-border-3q.html": [
+   "4b481194dc902254c5569c67c9ec3d8b7ba98771",
+   "reftest"
+  ],
+  "html/rendering/non-replaced-elements/tables/table-border-3s.html": [
+   "c4c019c8eb308d382b960f8ad7a44fd4d00c03bb",
+   "reftest"
+  ],
   "html/rendering/non-replaced-elements/tables/table-cell-width-ref.html": [
    "b5ba0443f3cfacef82352ee792bc4963c582099d",
    "support"
@@ -424552,7 +425062,7 @@
    "testharness"
   ],
   "html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html": [
-   "a9cd73435a3aa3921edc70b76bb8e9a84a21a000",
+   "7a17dee2a75394f29d4bfdf0df62d5aaaaeb26a7",
    "testharness"
   ],
   "html/semantics/embedded-content/media-elements/track/track-element/track-css-cue-pseudo-class.html": [
@@ -431783,6 +432293,10 @@
    "cccc26bf17e3afe04cdad59cf2cf325ead1fb581",
    "testharness"
   ],
+  "html/webappapis/dynamic-markup-insertion/closing-the-input-stream/load-event-after-location-set-during-write.window.js": [
+   "d5c8469bafac20a967d8acb32dcb85bdff96cc3f",
+   "testharness"
+  ],
   "html/webappapis/dynamic-markup-insertion/document-write/001.html": [
    "3ac6423f4a8eb069af4b1320e30166d4dc0fc4f0",
    "testharness"
@@ -432460,7 +432974,7 @@
    "support"
   ],
   "html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/http-refresh.py": [
-   "d2acd4361f92fe286ab13688a9174ce7c5465755",
+   "d323f967b2177a431a4b118710dbfdfe6148315d",
    "support"
   ],
   "html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/meta-refresh.py": [
@@ -433784,7 +434298,7 @@
    "support"
   ],
   "infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini": [
-   "78bfa5f38a1c501c647c142e03a9586e1c2ed7d4",
+   "5df5c1f4561dcebdf92ff13c64a1e2fa28092f4e",
    "support"
   ],
   "infrastructure/metadata/infrastructure/testdriver/actions/elementPosition.html.ini": [
@@ -434104,15 +434618,15 @@
    "support"
   ],
   "interfaces/DOM-Parsing.idl": [
-   "f3a13342f5eb24b92523683ccc86b46d15ddbfb0",
+   "c5de42b0cfc5ce2a485fa692e33839b7eb4f2162",
    "support"
   ],
   "interfaces/FileAPI.idl": [
-   "1fd6bac945b70b526e4cdbe483e5c448a07d9b9d",
+   "15b2e5582fee1c7fee29e7d20bb82b0ca901af73",
    "support"
   ],
   "interfaces/IndexedDB.idl": [
-   "868338b3080ccad6195c5764e6b70eb4854a93c3",
+   "21ff252fffe57f1c49649790b7be8d59083aef86",
    "support"
   ],
   "interfaces/InputDeviceCapabilities.idl": [
@@ -434127,10 +434641,6 @@
    "024cd0885a67fca28f0f1a3d5a5c2df3ca4bd42d",
    "support"
   ],
-  "interfaces/ResizeObserver.idl": [
-   "fc56faf4f93ba59cdbf52d54fb39e5427549120e",
-   "support"
-  ],
   "interfaces/SRI.idl": [
    "3abb66cd6e7c5b2ac76faf466924d44c1d2cafc8",
    "support"
@@ -434180,7 +434690,7 @@
    "support"
   ],
   "interfaces/clipboard-apis.idl": [
-   "e48ca6a5e46330ca75faf8fb38b636358c353dbb",
+   "99d1155a3e36519633aa12351990723e3caed581",
    "support"
   ],
   "interfaces/compat.idl": [
@@ -434236,7 +434746,7 @@
    "support"
   ],
   "interfaces/css-layout-api.idl": [
-   "9440684a26ccdbddee0ba9b0f587a482fba42be5",
+   "31ab6eb4d0b2a8eab1acee7ad1f6f9f69e89a69f",
    "support"
   ],
   "interfaces/css-masking.idl": [
@@ -434252,11 +434762,11 @@
    "support"
   ],
   "interfaces/css-pseudo.idl": [
-   "c51f2217f34f67c3c3fba5a1108c36464984086c",
+   "2b557e653163863feffa05d3f4a4e961142aa944",
    "support"
   ],
   "interfaces/css-regions.idl": [
-   "1e2396007d0d6196e645aed85ef7760ee5c9bdf7",
+   "f7cf3d31a114a653734990ef081ac109478dfcd8",
    "support"
   ],
   "interfaces/css-transitions.idl": [
@@ -434264,7 +434774,7 @@
    "support"
   ],
   "interfaces/css-typed-om.idl": [
-   "02fe7bb83ad7dc6f7ec328636071d125d2181d62",
+   "be2946bc20f7689577c43635cc10ba635cc9c7df",
    "support"
   ],
   "interfaces/cssom-view.idl": [
@@ -434300,7 +434810,7 @@
    "support"
   ],
   "interfaces/feature-policy.idl": [
-   "2a04215801610c36895277b2270c9e9f8efb77f1",
+   "3ded1e9b0c64ec84d4f4d07b6b870effcb9cd893",
    "support"
   ],
   "interfaces/fetch.idl": [
@@ -434324,7 +434834,7 @@
    "support"
   ],
   "interfaces/generic-sensor.idl": [
-   "2e7aacbec176dbd7dfd0707de9d0cc5efb00123f",
+   "2921c50a65e8d4467a56c5d337ef4d476e3ee0a2",
    "support"
   ],
   "interfaces/geolocation-API.idl": [
@@ -434332,7 +434842,7 @@
    "support"
   ],
   "interfaces/geolocation-sensor.idl": [
-   "41c310acefe12f7dcf8ae2a3369fcc11230b2a09",
+   "074d7bb9731524b5fd79f689fe748b4b2a135336",
    "support"
   ],
   "interfaces/geometry.idl": [
@@ -434368,7 +434878,7 @@
    "support"
   ],
   "interfaces/keyboard-lock.idl": [
-   "90812ae89147757ed2d5b77aa9c5d0f1b349afa7",
+   "5990976c1c8211560e4dd5bbe87811d1bf06d9d0",
    "support"
   ],
   "interfaces/keyboard-map.idl": [
@@ -434392,7 +434902,7 @@
    "support"
   ],
   "interfaces/mediacapture-depth.idl": [
-   "63e839cba9377a06f61a6612e68187189fea973d",
+   "907940aed7deb9019b91ed1bac98f0e8f4693c85",
    "support"
   ],
   "interfaces/mediacapture-fromelement.idl": [
@@ -434400,7 +434910,7 @@
    "support"
   ],
   "interfaces/mediacapture-streams.idl": [
-   "a66e473493ede9d5de50005718cabe9b837830a0",
+   "0feea37802d9facb70978684b4faaf5780dbd0bb",
    "support"
   ],
   "interfaces/mediasession.idl": [
@@ -434472,7 +434982,7 @@
    "support"
   ],
   "interfaces/pointerevents.idl": [
-   "da822bba0e58e36ea0a892b008075120282d8a85",
+   "fd368bf5a0a25cf983ca92417a945a409b8e4ee3",
    "support"
   ],
   "interfaces/pointerlock.idl": [
@@ -434507,6 +435017,10 @@
    "812cc0ef81533136f537b2591cf6c1774bf525ba",
    "support"
   ],
+  "interfaces/resize-observer.idl": [
+   "fc56faf4f93ba59cdbf52d54fb39e5427549120e",
+   "support"
+  ],
   "interfaces/resource-timing.idl": [
    "fc14253f5e9aebec47ce83da1afa938819015f51",
    "support"
@@ -434516,7 +435030,7 @@
    "support"
   ],
   "interfaces/screen-orientation.idl": [
-   "2304cc286cc009bd26423fb112c378d2b06e04f4",
+   "b5481216729526387722a6c733ea529f5d1f831a",
    "support"
   ],
   "interfaces/scroll-animations.idl": [
@@ -434536,7 +435050,7 @@
    "support"
   ],
   "interfaces/service-workers.idl": [
-   "fb2e033a7aa06b2191eb93354cf7f4e56a54ccf3",
+   "99f55ab6add1940a021a4b15a6556ed5383febc4",
    "support"
   ],
   "interfaces/shape-detection-api.idl": [
@@ -434544,7 +435058,7 @@
    "support"
   ],
   "interfaces/speech-api.idl": [
-   "f94637a8d21eb8a5940ce5ddfb6f6ca1af52f289",
+   "ba86d5065b7a4d941b53e5aabf133fed54b16ff4",
    "support"
   ],
   "interfaces/storage.idl": [
@@ -434552,7 +435066,7 @@
    "support"
   ],
   "interfaces/touch-events.idl": [
-   "5e341bd7b17be06a615142dbccfad22e3e01fb5f",
+   "17be1b46b379fe1aefef076ef8066e0a4570bad0",
    "support"
   ],
   "interfaces/trusted-types.tentative.idl": [
@@ -434568,7 +435082,7 @@
    "support"
   ],
   "interfaces/user-timing.idl": [
-   "da8a0acd6738745fc2a724213e404c2f364329de",
+   "cd2e1446b89ef6bb2e03caadda707f141476c9b7",
    "support"
   ],
   "interfaces/vibration.idl": [
@@ -434580,7 +435094,7 @@
    "support"
   ],
   "interfaces/wake-lock.idl": [
-   "89da0b8dc829b92a25f2b8895cdf2bbb25a45fe2",
+   "10e714828d9b7c730555884d1c849ec3550e440c",
    "support"
   ],
   "interfaces/wasm-js-api.idl": [
@@ -434612,7 +435126,7 @@
    "support"
   ],
   "interfaces/webauthn.idl": [
-   "becf8dd335cbcd1f5dc4471fbe02b77e5d2f0115",
+   "be8d0c10c47e979ed6c7c8caa10f46d6578b972b",
    "support"
   ],
   "interfaces/webdriver.idl": [
@@ -434636,11 +435150,11 @@
    "support"
   ],
   "interfaces/webrtc-stats.idl": [
-   "c86097b697b56f105abedfcd700d496f9687a153",
+   "e5289283615c49145b69f718e45747b62e7031fa",
    "support"
   ],
   "interfaces/webrtc.idl": [
-   "d60139ad946ee625ed61f598a96f71d0680511c2",
+   "413a96ac56052a72e51ce55055286562e2e7673a",
    "support"
   ],
   "interfaces/webusb.idl": [
@@ -447160,7 +447674,7 @@
    "testharness"
   ],
   "payment-request/META.yml": [
-   "558db3e088c1b07ad90eff717feccbb0591e67fb",
+   "5897c26fe88725725792c07698e7691df403db8b",
    "support"
   ],
   "payment-request/MerchantValidationEvent/complete-method-manual.https-expected.txt": [
@@ -447224,7 +447738,7 @@
    "manual"
   ],
   "payment-request/PaymentRequestUpdateEvent/updateWith-method-abort-update-manual.https.html": [
-   "cf0bb289d73bf7168b93a19b81144d66349f5e95",
+   "99b7a28e90d2882068e71d8e22ce62f723f1f1c2",
    "manual"
   ],
   "payment-request/PaymentRequestUpdateEvent/updateWith-state-checks-manual.https.html": [
@@ -447568,7 +448082,7 @@
    "manual"
   ],
   "payment-request/updateWith-method-pmi-handling-manual.https.html": [
-   "8bab88212bab51ea771a0fc2a81a1a9e7ee6e0d1",
+   "6cddeb97365fb3b32395e6b76d887080b571208b",
    "manual"
   ],
   "payment-request/user-abort-algorithm-manual.https.html": [
@@ -447832,7 +448346,7 @@
    "support"
   ],
   "pointerevents/idlharness.window-expected.txt": [
-   "a7b5fb54018e1ad444bd4e435101e6174bdc2520",
+   "e0ed9cea2b41d3770ace3e16d0c64b05f03aae82",
    "support"
   ],
   "pointerevents/idlharness.window.js": [
@@ -447895,13 +448409,25 @@
    "6ce0f3e59a04db4ecf23d9fd60b57164ceb67f85",
    "testharness"
   ],
+  "pointerevents/pointerevent_mouse_capture_change_hover.html": [
+   "10b19f8474a95126302f824390302007a4f63fea",
+   "testharness"
+  ],
+  "pointerevents/pointerevent_mouse_pointercapture_in_frame.html": [
+   "83b4c1becc48339f74948fd01bdf15dfd27f96c1",
+   "testharness"
+  ],
+  "pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html": [
+   "524d19eecebfce60e4fb1e4a74c2c1d20e0ba770",
+   "testharness"
+  ],
   "pointerevents/pointerevent_on_event_handlers.html": [
    "d8cfa7a0f4c482be606e4e98f9a7900a0340a477",
    "testharness"
   ],
-  "pointerevents/pointerevent_pointercancel_touch-manual.html": [
-   "70a65eeb5ca4a340aff4a74873e12e869a07ac48",
-   "manual"
+  "pointerevents/pointerevent_pointercancel_touch.html": [
+   "a645033a247437604d6b1c4614079c9193c28e9d",
+   "testharness"
   ],
   "pointerevents/pointerevent_pointerenter_does_not_bubble.html": [
    "7d38de7446938de3715b19f4585d747a18912d77",
@@ -448004,7 +448530,7 @@
    "support"
   ],
   "pointerevents/pointerevent_support.js": [
-   "5c35e016a0ed51353868e0307af0896c62db64de",
+   "e8c847b12a880a557d8d3cd69bc0bc77cf3378af",
    "support"
   ],
   "pointerevents/pointerevent_suppress_compat_events_on_click.html": [
@@ -448139,6 +448665,14 @@
    "5245a3f2e16bf13967187231db515433217912aa",
    "support"
   ],
+  "pointerevents/resources/pointerevent_mouse_pointercapture-iframe.html": [
+   "817c6123cf96b0e966c04a48414725d794549c77",
+   "support"
+  ],
+  "pointerevents/resources/pointerevent_mouse_pointercapture_inactivate_pointer-iframe.html": [
+   "d4b4af1fba1d0090ee87038af5fd686495d4cb38",
+   "support"
+  ],
   "pointerevents/resources/pointerevent_pointerId_scope-iframe.html": [
    "ab33560b35216ea0976d1c037650122d9336ae39",
    "support"
@@ -458016,7 +458550,7 @@
    "support"
   ],
   "resize-observer/idlharness.window.js": [
-   "592af2e0c079197457e091d84dfdb3741703395e",
+   "2d459b0b1263682f0f3472d4bf706b8b735dbccc",
    "testharness"
   ],
   "resize-observer/notify.html": [
@@ -458631,6 +459165,22 @@
    "bf8dd16ca75d4be1095808138d09a9c400159b86",
    "support"
   ],
+  "resources/chromium/mock-barcodedetection.js": [
+   "2558bbda58913ec51c36bdce28e0f84a1aea32e7",
+   "support"
+  ],
+  "resources/chromium/mock-barcodedetection.js.headers": [
+   "6c61a34a4ec2e75096db0eb9f7748b142f0db7bb",
+   "support"
+  ],
+  "resources/chromium/mock-facedetection.js": [
+   "1275e4dd2f5e24988e723a728dbf5bb4acc4c6cb",
+   "support"
+  ],
+  "resources/chromium/mock-facedetection.js.headers": [
+   "6c61a34a4ec2e75096db0eb9f7748b142f0db7bb",
+   "support"
+  ],
   "resources/chromium/mock-imagecapture.js": [
    "329cbc3a761dc5720b7a67ed09ef68aec6a8bc3d",
    "support"
@@ -460640,7 +461190,7 @@
    "testharness"
   ],
   "service-workers/service-worker/extendable-event-async-waituntil.https.html": [
-   "cb4ed30a37fdfd07fd8b34181f073c6de2e165b9",
+   "04e98266b4f1a0b6ec572e1c317ab852fc2e4480",
    "testharness"
   ],
   "service-workers/service-worker/extendable-event-waituntil.https.html": [
@@ -460696,7 +461246,7 @@
    "testharness"
   ],
   "service-workers/service-worker/fetch-event-async-respond-with.https.html": [
-   "87fa04679832f792579b6fefcee2eee550bb58fd",
+   "7842a829c9b82c0ebff94a3902284ad191b5be71",
    "testharness"
   ],
   "service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html": [
@@ -460932,7 +461482,7 @@
    "testharness"
   ],
   "service-workers/service-worker/interfaces-sw.https-expected.txt": [
-   "15c9fb807acf01293590ddcaee5724cdcf4e4af5",
+   "5e51cf6272eebfd26a8af8489e681bfdb35d4766",
    "support"
   ],
   "service-workers/service-worker/interfaces-sw.https.html": [
@@ -461540,7 +462090,7 @@
    "support"
   ],
   "service-workers/service-worker/resources/extendable-event-async-waituntil.js": [
-   "abf54934a3b42e18908a730bdfa140e6b692c7ae",
+   "8a975b0d2e9b0789ce7ab7b05757b6d93f2ec400",
    "support"
   ],
   "service-workers/service-worker/resources/extendable-event-waituntil.js": [
@@ -461592,7 +462142,7 @@
    "support"
   ],
   "service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js": [
-   "7f66d20dfc2dff0af01dfa07f823c660b7a1ec1b",
+   "3409d0a0397bdc552da166961b435fb2363e3468",
    "support"
   ],
   "service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html": [
@@ -463395,12 +463945,76 @@
    "775462404762d0123d21601396bcec1e873dbcaa",
    "support"
   ],
+  "shape-detection/README.md": [
+   "556568baddbeec6ed0b597b5a8391833e807ebfa",
+   "support"
+  ],
+  "shape-detection/detected-boundingBox-read-only.html": [
+   "86b88892260602c17ebbf57e7a370d0342350374",
+   "testharness"
+  ],
+  "shape-detection/detection-HTMLCanvasElement.html": [
+   "4e9615a03d0d079bc55eee0f76b50b6d1de8b859",
+   "testharness"
+  ],
+  "shape-detection/detection-HTMLImageElement.html": [
+   "979efabdcb07cfdc0190383026a24e144dea1747",
+   "testharness"
+  ],
+  "shape-detection/detection-HTMLVideoElement.html": [
+   "7b3736d02e9b6b0769a18354b054e5c3ce268773",
+   "testharness"
+  ],
+  "shape-detection/detection-ImageBitmap.html": [
+   "a7157c0960eb463b953576e00bb9628cd48df73d",
+   "testharness"
+  ],
+  "shape-detection/detection-ImageData.html": [
+   "a74c2afbe1bcde274793853c593c662f4b161e91",
+   "testharness"
+  ],
+  "shape-detection/detection-getSupportedFormats.html": [
+   "4ccb5ab7661c7ba4217f2ae0f0fea15e53bb3b43",
+   "testharness"
+  ],
+  "shape-detection/detection-on-worker.worker.js": [
+   "6b440af7b81703915a1c25dad27f5518e1802e97",
+   "testharness"
+  ],
+  "shape-detection/detection-options.html": [
+   "31475575e3f42e1b63723c08031dd7833bb30bc8",
+   "testharness"
+  ],
+  "shape-detection/detection-security-test.html": [
+   "b3f458e23ee8869aaad56847b8c451e72c4ccf94",
+   "testharness"
+  ],
+  "shape-detection/detector-same-object.html": [
+   "52540271d27ecf76cfe68ca0502630eac8c5d0a3",
+   "testharness"
+  ],
   "shape-detection/idlharness.any-expected.txt": [
-   "da45152cbbb78189eb3a5c1d95f5020e0266f383",
+   "3eeafa7b065a771582a3e62d22e5c9aa8de9a7f4",
    "support"
   ],
   "shape-detection/idlharness.any.js": [
-   "ea7726891052c54b3afd3e0a7a2399dfb44e7509",
+   "dab7de99d2d1f15ed72f562a0fb7fbfb3367eeac",
+   "testharness"
+  ],
+  "shape-detection/idlharness.any.worker-expected.txt": [
+   "58b8ab303912cdd9d4464a9e5f1001aed1c9f36b",
+   "support"
+  ],
+  "shape-detection/resources/shapedetection-helpers.js": [
+   "09cea09c6fe0c1fb20c707a766e746b8246cfc02",
+   "support"
+  ],
+  "shape-detection/shapedetection-cross-origin.sub.html": [
+   "c9d86430356de470bca7a8dfef8596e9159164ad",
+   "testharness"
+  ],
+  "shape-detection/shapedetection-empty-input.html": [
+   "601c992ed85a58ca575901485bafc1f34f5bde24",
    "testharness"
   ],
   "signed-exchange/META.yml": [
@@ -463911,8 +464525,12 @@
    "61e179cca47b70d001e5e081e87166ec1363714a",
    "testharness"
   ],
+  "speech-api/SpeechSynthesisEvent-constructor-expected.txt": [
+   "666caa9cbf397114ac30d70afd554652537b8ee8",
+   "support"
+  ],
   "speech-api/SpeechSynthesisEvent-constructor.html": [
-   "47a37d25d9723cadcb9da2d778481fd9561c37aa",
+   "3ad6886b0aa9b4b868e5c57358ed742ebbeacff0",
    "testharness"
   ],
   "speech-api/SpeechSynthesisUtterance-basics.https-expected.txt": [
@@ -463932,7 +464550,7 @@
    "testharness"
   ],
   "speech-api/idlharness.window-expected.txt": [
-   "ee63d6ddb08884ca48c46c9428fbf14dbddfeab0",
+   "36527b02dbb64339651e5e27b8fa4a147044a0c9",
    "support"
   ],
   "speech-api/idlharness.window.js": [
@@ -465999,6 +466617,26 @@
    "862e5fde273a5b8ad467f8e062b3bb9ec16e5242",
    "testharness"
   ],
+  "svg/struct/reftests/reference/green-100x100.svg": [
+   "120941444a4898197d6b6001f9908a6cd48b62ba",
+   "support"
+  ],
+  "svg/struct/reftests/use-svg-dimensions-override-001.svg": [
+   "c658adce80f82d5ce6457101ecd3b3d3f562ddd9",
+   "reftest"
+  ],
+  "svg/struct/reftests/use-svg-dimensions-override-002.svg": [
+   "6c3f97b8dc48eb2150311de4bae409b464e948ca",
+   "reftest"
+  ],
+  "svg/struct/reftests/use-symbol-dimensions-override-001.svg": [
+   "1f8f71414783ec6f46d74d700cd63bdc225607a9",
+   "reftest"
+  ],
+  "svg/struct/reftests/use-symbol-dimensions-override-002.svg": [
+   "9c1fd49083ae55b5a6743c9da4b4ecab46683b2c",
+   "reftest"
+  ],
   "svg/styling/render/transform-box-ref.svg": [
    "b41f8bb2a7baac19d907c378a0e269b9a8e914fb",
    "support"
@@ -466231,6 +466869,62 @@
    "64b1307966c4527c0ba6546d7e80730512d8f382",
    "reftest"
   ],
+  "svg/text/reftests/text-text-anchor-001-ref.svg": [
+   "b9554bac696f5fd30f305f572b1d0edb71914545",
+   "support"
+  ],
+  "svg/text/reftests/text-text-anchor-001.svg": [
+   "015b3dd5ebb854e36aef0cd473d9ab2905d36800",
+   "reftest"
+  ],
+  "svg/text/reftests/text-text-anchor-002-ref.svg": [
+   "5721bc3e073b4eb38caf18e441fe6791a553c591",
+   "support"
+  ],
+  "svg/text/reftests/text-text-anchor-002.svg": [
+   "503ce16625b90d21610b4389cc71c7fe7cde8218",
+   "reftest"
+  ],
+  "svg/text/reftests/text-text-anchor-003-ref.svg": [
+   "797dea3d717479c54ede62c2dd3e25173a1d1060",
+   "support"
+  ],
+  "svg/text/reftests/text-text-anchor-003.svg": [
+   "eb5063020a74ca282afffb5331bf14f5f14dd0d1",
+   "reftest"
+  ],
+  "svg/text/reftests/text-text-anchor-102-ref.svg": [
+   "9c1d98c7ab49e7c905c48b14000fb0e761edb698",
+   "support"
+  ],
+  "svg/text/reftests/text-text-anchor-102.svg": [
+   "8cdcc988ded2794debc7d09f91178e21594708f8",
+   "reftest"
+  ],
+  "svg/text/reftests/text-text-anchor-201-ref.svg": [
+   "d8b6cc4e67d908d977682cde18ae7ce227bbdde7",
+   "support"
+  ],
+  "svg/text/reftests/text-text-anchor-201.svg": [
+   "84b644cd6a52808da17d4b41a5c0823084c00966",
+   "reftest"
+  ],
+  "svg/text/reftests/text-text-anchor-202-ref.svg": [
+   "72a8ee15a62cc1b40eb4d5c0128368af7ab34b12",
+   "support"
+  ],
+  "svg/text/reftests/text-text-anchor-202.svg": [
+   "79792ed33b6bfa496e39dee468d369253a1dde2c",
+   "reftest"
+  ],
+  "svg/text/reftests/text-text-anchor-203-ref.svg": [
+   "7ee99a2dcb8640c0a60e6a7adbab0e4aea94af4f",
+   "support"
+  ],
+  "svg/text/reftests/text-text-anchor-203.svg": [
+   "bb7c8206a116af9e7b242c4e9546d570cea6afd8",
+   "reftest"
+  ],
   "svg/text/reftests/textpath-shape-001-ref.svg": [
    "10827c85810cdf9dc7e70a665c289814d35ed219",
    "support"
@@ -466496,7 +467190,7 @@
    "support"
   ],
   "tools/ci/azure/affected_tests.yml": [
-   "8076bc386986ed48a7af50fd48a59a544bf8c3bc",
+   "17fca51d50cbd4f1986c63f3383b18dbdbe9c6fe",
    "support"
   ],
   "tools/ci/azure/checkout.yml": [
@@ -466508,7 +467202,7 @@
    "support"
   ],
   "tools/ci/azure/fyi_hook.yml": [
-   "ddfbe3d3cf8e1db0453a4b909a7b6176dc32a96f",
+   "5af16af31bcc34558ae3af3831ee2f3e39ba87e7",
    "support"
   ],
   "tools/ci/azure/install_certs.yml": [
@@ -466700,7 +467394,7 @@
    "support"
   ],
   "tools/manifest/manifest.py": [
-   "dc57c24ddb084e2af0eb93e6470f7e5024d6e469",
+   "e2e35d7ff992f944e983a727cd6acc574fbaf6fc",
    "support"
   ],
   "tools/manifest/sourcefile.py": [
@@ -466716,7 +467410,7 @@
    "support"
   ],
   "tools/manifest/vcs.py": [
-   "ecd565cf9e7bd5719b8d1d7dd23cd89c61ad1bf6",
+   "676e53f678546d52d74df790ea5c4ddf5bb9b832",
    "support"
   ],
   "tools/py27-flake8.ini": [
@@ -470892,7 +471586,7 @@
    "support"
   ],
   "tools/wpt/run.py": [
-   "a19851d14c5cd2a64355a4e0389ace0b7cbd022f",
+   "ea4bd1c8054ae874a098cf762627613e2511bd67",
    "support"
   ],
   "tools/wpt/testfiles.py": [
@@ -471171,6 +471865,14 @@
    "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
    "support"
   ],
+  "tools/wptrunner/wptrunner/formatters/chromium.py": [
+   "f54f23e5a9d5f6e8bf1698a50c597155c5a1d727",
+   "support"
+  ],
+  "tools/wptrunner/wptrunner/formatters/tests/test_chromium.py": [
+   "a6e6c2e1ed08d4c0d4209230082212c7988f8f11",
+   "support"
+  ],
   "tools/wptrunner/wptrunner/formatters/wptreport.py": [
    "c58422d0de0a594c237b7fa6b2e89bf14eaf44cc",
    "support"
@@ -471211,6 +471913,10 @@
    "3e88403636396c439759705c751433b28e05f3ab",
    "support"
   ],
+  "tools/wptrunner/wptrunner/testharness_runner.html": [
+   "1cc80a270e2c1e8f0bcb8dc4878a75d9ce01717a",
+   "support"
+  ],
   "tools/wptrunner/wptrunner/testharnessreport-servo.js": [
    "b672aea9a2540bf1446a23ddb288c93009bb26ba",
    "support"
@@ -471268,7 +471974,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/wptcommandline.py": [
-   "eb61461e4746041612612ecd83544af8961795c9",
+   "0b5dc82e067c2f50179d1093c3146e504c42056d",
    "support"
   ],
   "tools/wptrunner/wptrunner/wptlogging.py": [
@@ -471440,7 +472146,7 @@
    "testharness"
   ],
   "touch-events/idlharness.window-expected.txt": [
-   "610536241ea584ec951f8f93798739f0dce704a3",
+   "10ad2905fd59718ccc4b2d2ab618bab978894250",
    "support"
   ],
   "touch-events/idlharness.window.js": [
@@ -473007,10 +473713,6 @@
    "4788ffcf84ff8d88adbafbe416dd7d5b80ec89d1",
    "testharness"
   ],
-  "wasm/jsapi/memory/constructor.any-expected.txt": [
-   "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-   "support"
-  ],
   "wasm/jsapi/memory/constructor.any.js": [
    "cef713fe0fe74f009e9f8aadd9168e7fa5138eb0",
    "testharness"
@@ -473039,18 +473741,10 @@
    "2127e2810cb8d43f1e2e06d3c1e27b9fc664c764",
    "testharness"
   ],
-  "wasm/jsapi/module/customSections.any-expected.txt": [
-   "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-   "support"
-  ],
   "wasm/jsapi/module/customSections.any.js": [
    "387d4e4a31744d16627484650a35ecc86f992c66",
    "testharness"
   ],
-  "wasm/jsapi/module/customSections.any.worker-expected.txt": [
-   "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-   "support"
-  ],
   "wasm/jsapi/module/exports.any.js": [
    "4437daa052fad56e66b7bf9991c5f045689564e3",
    "testharness"
@@ -473304,7 +473998,7 @@
    "testharness"
   ],
   "wasm/webapi/instantiateStreaming.any.js": [
-   "224b0a3d0b78af89998992ec1aed212f307b6866",
+   "daec185484fbab675d226c52e7548b065bd9e701",
    "testharness"
   ],
   "wasm/webapi/invalid-args.any.js": [
@@ -476864,7 +477558,7 @@
    "testharness"
   ],
   "webrtc/RTCDtlsTransport-getRemoteCertificates-expected.txt": [
-   "eca828bcbabc5fbeac67e692dc22958dea906242",
+   "e4e58c4347f1512cc6f854d2e5183b27c267c434",
    "support"
   ],
   "webrtc/RTCDtlsTransport-getRemoteCertificates.html": [
@@ -476888,11 +477582,11 @@
    "testharness"
   ],
   "webrtc/RTCIceConnectionState-candidate-pair.https.html": [
-   "7280d040856370f448796a4de2f92f82f9c78c53",
+   "6c93aec9260d50d1d6cfcd637d15dd44385bee0d",
    "testharness"
   ],
   "webrtc/RTCIceTransport-expected.txt": [
-   "8fcf2e214bb23a9f5f023c4d69398c918ca8e49d",
+   "5de6f8abc62cb88744f6fa2691fd3af8bd007a5f",
    "support"
   ],
   "webrtc/RTCIceTransport-extension-helper.js": [
@@ -476940,7 +477634,7 @@
    "testharness"
   ],
   "webrtc/RTCPeerConnection-connectionState-expected.txt": [
-   "8b1b80863817b1beb2f0a160313ea5ea56e0a587",
+   "1aca75f066eec6f90465b4d7e4a2384682007047",
    "support"
   ],
   "webrtc/RTCPeerConnection-connectionState.html": [
@@ -477016,7 +477710,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt": [
-   "c5fd94e3f5ca952dc8b0fa85c50b56c6b8ecc8ed",
+   "96e7bba4d58c622f2f4a4ab5afa0804e8fadb4e3",
    "support"
   ],
   "webrtc/RTCPeerConnection-iceConnectionState.https.html": [
@@ -477024,7 +477718,7 @@
    "testharness"
   ],
   "webrtc/RTCPeerConnection-iceGatheringState-expected.txt": [
-   "cf325d504c3bb9819ed291c8aade04daea91877f",
+   "91d147acffff7d7ab95a32f7e382dd0e1dd23224",
    "support"
   ],
   "webrtc/RTCPeerConnection-iceGatheringState.html": [
@@ -477144,7 +477838,7 @@
    "testharness"
   ],
   "webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html": [
-   "4e9568f0bcdb4813d973197640aa7ea200598b56",
+   "59761c4c4bdca57141272b092fe56a917b612c7b",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-setRemoteDescription.html": [
@@ -477296,19 +477990,15 @@
    "testharness"
   ],
   "webrtc/RTCRtpTransceiver.https.html": [
-   "8004fec9f0833d5e59ae48c92dc5ee06beafd4c2",
+   "b5f3c55ee5810f30ee8439e0b33df84b379d975c",
    "testharness"
   ],
-  "webrtc/RTCSctpTransport-constructor-expected.txt": [
-   "f4f36f4a429a2dea87ff9af739cc363d3582b194",
-   "support"
-  ],
   "webrtc/RTCSctpTransport-constructor.html": [
-   "7d3df051d876e490c926639499c13ba0dcf8d30a",
+   "28dae0555324907af1649544344dad1f1899f39d",
    "testharness"
   ],
   "webrtc/RTCSctpTransport-maxMessageSize-expected.txt": [
-   "4d1f9a1caaf17f40ddebb8159844b40c70c05515",
+   "9527815986a4e65ad48f38a693dc0a84d310c409",
    "support"
   ],
   "webrtc/RTCSctpTransport-maxMessageSize.html": [
@@ -477368,7 +478058,7 @@
    "testharness"
   ],
   "webrtc/idlharness.https.window-expected.txt": [
-   "8191ea2a7c9656895284311205ac3e942e2448a0",
+   "be57dd0e60da78b3e3a2890fbea745d0eb590435",
    "support"
   ],
   "webrtc/idlharness.https.window.js": [
@@ -482008,7 +482698,7 @@
    "support"
   ],
   "webxr/idlharness.https.window-expected.txt": [
-   "979535e73edb7d4bb6aafa38d5e418f420c4ec14",
+   "1e7eedfb9bddd96261ad6d18846be5f143839b08",
    "support"
   ],
   "webxr/idlharness.https.window.js": [
@@ -482088,7 +482778,7 @@
    "testharness"
   ],
   "webxr/xrFrame_lifetime.https.html": [
-   "971a6d78a1e1ee1c51141a475868185318680495",
+   "30cf5f996773b9c278370c3ae7df086574d3b72d",
    "testharness"
   ],
   "webxr/xrRay_constructor.https.html": [
@@ -482103,6 +482793,10 @@
    "abaf8bf9ebe2fed3c99cef5bf52d697b9e8ed1c8",
    "testharness"
   ],
+  "webxr/xrRigidTransform_inverse.https.html": [
+   "ddae2af6469034e67dc579dfd6cfb53b86f28d6a",
+   "testharness"
+  ],
   "webxr/xrRigidTransform_matrix.https.html": [
    "21236c732461de4422dcab7a3709cdc7ffc0f3a6",
    "testharness"
@@ -482215,6 +482909,14 @@
    "73eabd55226d67b05fc3a86a9e57880b9a725e5b",
    "testharness"
   ],
+  "workers/Worker-custom-event.any.js": [
+   "201e0313b0e968b6b8c2d5d9a990476dab13c04b",
+   "testharness"
+  ],
+  "workers/Worker-formdata.any.js": [
+   "3ee42d9f4b76228bc25a89d0fb8a1c653139e45a",
+   "testharness"
+  ],
   "workers/Worker-location.sub.any.js": [
    "2ef944553105767535f6e3119048091f959bfac8",
    "testharness"
@@ -482231,6 +482933,10 @@
    "8863b7523010dd8566d1ed42094e519efc500a65",
    "testharness"
   ],
+  "workers/Worker-replace-event-handler.any.js": [
+   "1623573c7ebf5b436eb22b46fecc2da51cdccb8d",
+   "testharness"
+  ],
   "workers/Worker-replace-global-constructor.any.js": [
    "f208f3736362a82a322527b2f983b9e3ccaff33e",
    "testharness"
@@ -482371,6 +483077,10 @@
    "9907e6473c2dcf60f8f17335e3d6ab41f800418a",
    "testharness"
   ],
+  "workers/WorkerNavigator-hardware-concurrency.any.js": [
+   "bd4910fcafae58d0dfc34be0a246a8fa567a338e",
+   "testharness"
+  ],
   "workers/WorkerNavigator.any.js": [
    "3588045c490a45170c84bcfa5211086646afbb76",
    "testharness"
@@ -484068,7 +484778,7 @@
    "support"
   ],
   "xhr/FormData-append.html": [
-   "bf6c66d0f665df8cfb30b97063cca33442900250",
+   "a10244fa23d475a6fc4cb6fe2b15f869c3081218",
    "testharness"
   ],
   "xhr/META.yml": [
@@ -484455,10 +485165,6 @@
    "283b44b5ab01d1aaa51ba8751547d0f5670d6fcb",
    "testharness"
   ],
-  "xhr/formdata-expected.txt": [
-   "a22acdb935a8fd3bd2dc416460d33c26038d0318",
-   "support"
-  ],
   "xhr/formdata-foreach.html": [
    "3ad184c4d55789a2d2f23db61d41b7ad9c650b0b",
    "testharness"
@@ -484472,11 +485178,11 @@
    "testharness"
   ],
   "xhr/formdata-set.htm": [
-   "f030caa78f95309e223ece150c30261dbf85d937",
+   "ee43e1569f1958e5c71f14a3bd89b75756d6a85c",
    "testharness"
   ],
   "xhr/formdata.htm": [
-   "65a5d29c6714d25bfcf97e39f04ae2f7f04de761",
+   "699c11ab7838a32a3e62460f13a2a427d8d81707",
    "testharness"
   ],
   "xhr/getallresponseheaders-cookies.htm": [
@@ -484891,6 +485597,14 @@
    "8b6682686c8709994a19ae430ed2120a047f9398",
    "support"
   ],
+  "xhr/resources/auth10/auth.py": [
+   "8b6682686c8709994a19ae430ed2120a047f9398",
+   "support"
+  ],
+  "xhr/resources/auth11/auth.py": [
+   "8b6682686c8709994a19ae430ed2120a047f9398",
+   "support"
+  ],
   "xhr/resources/auth2/auth.py": [
    "8b6682686c8709994a19ae430ed2120a047f9398",
    "support"
@@ -485320,7 +486034,7 @@
    "testharness"
   ],
   "xhr/send-authentication-basic-cors-not-enabled.htm": [
-   "070b2ba321256b6bd772436a5addfd09c0b3ff5d",
+   "68ad5e95ed870f9b09401e8417df70116c0336af",
    "testharness"
   ],
   "xhr/send-authentication-basic-cors.htm": [
@@ -485328,7 +486042,7 @@
    "testharness"
   ],
   "xhr/send-authentication-basic-repeat-no-args.htm": [
-   "464d69cf789ecff6309c0866929e566e1c2703a7",
+   "38f1b20700a33e620ffd3217b74b8e3fcec6761b",
    "testharness"
   ],
   "xhr/send-authentication-basic-setrequestheader-and-arguments.htm": [
@@ -485403,24 +486117,24 @@
    "6c2c00823c6aab1e22ff15e5eca23d78f2407d02",
    "testharness"
   ],
-  "xhr/send-data-arraybuffer.htm": [
-   "25c5d24072788b32e4bcf136c7eb5a37b9d39148",
+  "xhr/send-data-arraybuffer.any.js": [
+   "71933d089780168d93954d0045b3a1d94b1c5741",
    "testharness"
   ],
-  "xhr/send-data-arraybufferview.htm": [
-   "4de7e9e8920b4e38d8a336065415b9998c08cc0f",
+  "xhr/send-data-arraybufferview.any.js": [
+   "a3985b4701db056ed8dfd28050c916179086d448",
    "testharness"
   ],
   "xhr/send-data-blob.htm": [
    "5285fc180cc979e33c567f537e8575abf285db50",
    "testharness"
   ],
-  "xhr/send-data-es-object.htm": [
-   "6f7743286ecdd06a52ce545d56dfb1589242996e",
+  "xhr/send-data-es-object.any.js": [
+   "d98a4ca65aa6b2f3f4043f09742354e6b12ff833",
    "testharness"
   ],
-  "xhr/send-data-formdata.htm": [
-   "9456aa77c53585f0c13bac628770521428e6022a",
+  "xhr/send-data-formdata.any.js": [
+   "6ff04793ea65057a095dd3389eee10a5db77966f",
    "testharness"
   ],
   "xhr/send-data-readablestream.any-expected.txt": [
diff --git a/third_party/blink/web_tests/external/wpt/2dcontext/imagebitmap/createImageBitmap-origin.sub.html b/third_party/blink/web_tests/external/wpt/2dcontext/imagebitmap/createImageBitmap-origin.sub.html
index 24848f3d..ae8c70f9 100644
--- a/third_party/blink/web_tests/external/wpt/2dcontext/imagebitmap/createImageBitmap-origin.sub.html
+++ b/third_party/blink/web_tests/external/wpt/2dcontext/imagebitmap/createImageBitmap-origin.sub.html
@@ -9,7 +9,7 @@
 <script>
 const crossOriginImageUrl = "http://{{domains[www1]}}:{{ports[http][0]}}/images/red.png";
 
-function assert_origin_unclean(bitmap) {
+function assert_origin_unclean_getImageData(bitmap) {
   const context = document.createElement("canvas").getContext("2d");
   context.drawImage(bitmap, 0, 0);
   assert_throws("SecurityError", () => {
@@ -17,6 +17,20 @@
   });
 }
 
+function assert_origin_unclean_drawImage(bitmap) {
+  const canvas = document.createElement('canvas');
+  const ctx = canvas.getContext('2d');
+  ctx.drawImage(bitmap, 0, 0);
+  assert_throws('SecurityError', () => canvas.toDataURL());
+}
+
+function assert_origin_unclean_transferFromImageBitmap(bitmap) {
+  var canvas = document.createElement('canvas');
+  var ctx = canvas.getContext('bitmaprenderer');
+  ctx.transferFromImageBitmap(bitmap);
+  assert_throws('SecurityError', () => canvas.toDataURL());
+}
+
 function makeImage() {
   return new Promise((resolve, reject) => {
     const image = new Image();
@@ -104,7 +118,13 @@
 
 for (let { name, factory } of arguments) {
   promise_test(function() {
-    return factory().then(createImageBitmap).then(assert_origin_unclean);
-  }, name);
+    return factory().then(createImageBitmap).then(assert_origin_unclean_getImageData);
+  }, `${name}: origin unclear getImageData`);
+  promise_test(function() {
+    return factory().then(createImageBitmap).then(assert_origin_unclean_drawImage);
+  }, `${name}: origin unclear 2dContext.drawImage`);
+  promise_test(function() {
+    return factory().then(createImageBitmap).then(assert_origin_unclean_transferFromImageBitmap);
+  }, `${name}: origin unclear bitmaprenderer.transferFromImageBitmap`);
 }
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request.any-expected.txt b/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request.any-expected.txt
new file mode 100644
index 0000000..c28fc328
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request.any-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL cursor.request from IDBObjectStore.openCursor assert_equals: cursor.request expected (object) object "[object IDBRequest]" but got (undefined) undefined
+FAIL cursor.request from IDBObjectStore.openKeyCursor assert_equals: cursor.request expected (object) object "[object IDBRequest]" but got (undefined) undefined
+FAIL cursor.request from IDBIndex.openCursor assert_equals: cursor.request expected (object) object "[object IDBRequest]" but got (undefined) undefined
+FAIL cursor.request from IDBIndex.openKeyCursor assert_equals: cursor.request expected (object) object "[object IDBRequest]" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request.any.js b/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request.any.js
new file mode 100644
index 0000000..a62efc0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request.any.js
@@ -0,0 +1,40 @@
+// META: script=support.js
+
+function cursorRequestTest({ useIndex, useKeyCursor }) {
+  indexeddb_test(
+    (t, db) => {
+      const objStore = db.createObjectStore("my_objectstore");
+      objStore.add("data",  1);
+      objStore.createIndex("my_index", "");
+    },
+    (t, db) => {
+      const tx = db.transaction("my_objectstore");
+      let source = tx.objectStore("my_objectstore");
+      if (useIndex) source = source.index('my_index');
+      const req = useKeyCursor ? source.openKeyCursor() : source.openCursor();
+      let cursor;
+
+      req.onsuccess = t.step_func(() => {
+        cursor = req.result;
+        assert_equals(cursor.request, req, 'cursor.request');
+        assert_readonly(cursor, 'request');
+      });
+
+      req.transaction.oncomplete = t.step_func(() => {
+        setTimeout(t.step_func(() => {
+          assert_equals(cursor.request, req, 'cursor.request after transaction complete');
+          t.done();
+        }), 0);
+      });
+
+      req.transaction.onerror = t.unreached_func('Transaction error');
+    },
+    `cursor.request from ${useIndex ? 'IDBIndex' : 'IDBObjectStore'}.${useKeyCursor ? 'openKeyCursor' : 'openCursor'}`
+  );
+}
+
+for (const useIndex of [false, true]) {
+  for (const useKeyCursor of [false, true]) {
+    cursorRequestTest({ useIndex, useKeyCursor });
+  }
+}
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request.any.worker-expected.txt
new file mode 100644
index 0000000..c28fc328
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL cursor.request from IDBObjectStore.openCursor assert_equals: cursor.request expected (object) object "[object IDBRequest]" but got (undefined) undefined
+FAIL cursor.request from IDBObjectStore.openKeyCursor assert_equals: cursor.request expected (object) object "[object IDBRequest]" but got (undefined) undefined
+FAIL cursor.request from IDBIndex.openCursor assert_equals: cursor.request expected (object) object "[object IDBRequest]" but got (undefined) undefined
+FAIL cursor.request from IDBIndex.openKeyCursor assert_equals: cursor.request expected (object) object "[object IDBRequest]" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any-expected.txt b/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any-expected.txt
new file mode 100644
index 0000000..b2a16a0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any-expected.txt
@@ -0,0 +1,190 @@
+This is a testharness.js-based test.
+Found 186 tests; 185 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS idl_test setup
+PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
+PASS IDBRequest interface: existence and properties of interface object
+PASS IDBRequest interface object length
+PASS IDBRequest interface object name
+PASS IDBRequest interface: existence and properties of interface prototype object
+PASS IDBRequest interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBRequest interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBRequest interface: attribute result
+PASS IDBRequest interface: attribute error
+PASS IDBRequest interface: attribute source
+PASS IDBRequest interface: attribute transaction
+PASS IDBRequest interface: attribute readyState
+PASS IDBRequest interface: attribute onsuccess
+PASS IDBRequest interface: attribute onerror
+PASS IDBOpenDBRequest interface: existence and properties of interface object
+PASS IDBOpenDBRequest interface object length
+PASS IDBOpenDBRequest interface object name
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBOpenDBRequest interface: attribute onblocked
+PASS IDBOpenDBRequest interface: attribute onupgradeneeded
+PASS IDBVersionChangeEvent interface: existence and properties of interface object
+PASS IDBVersionChangeEvent interface object length
+PASS IDBVersionChangeEvent interface object name
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBVersionChangeEvent interface: attribute oldVersion
+PASS IDBVersionChangeEvent interface: attribute newVersion
+PASS IDBVersionChangeEvent must be primary interface of new IDBVersionChangeEvent("type")
+PASS Stringification of new IDBVersionChangeEvent("type")
+PASS IDBVersionChangeEvent interface: new IDBVersionChangeEvent("type") must inherit property "oldVersion" with the proper type
+PASS IDBVersionChangeEvent interface: new IDBVersionChangeEvent("type") must inherit property "newVersion" with the proper type
+PASS IDBFactory interface: existence and properties of interface object
+PASS IDBFactory interface object length
+PASS IDBFactory interface object name
+PASS IDBFactory interface: existence and properties of interface prototype object
+PASS IDBFactory interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBFactory interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBFactory interface: operation open(DOMString, unsigned long long)
+PASS IDBFactory interface: operation deleteDatabase(DOMString)
+PASS IDBFactory interface: operation databases()
+PASS IDBFactory interface: operation cmp(any, any)
+PASS IDBFactory must be primary interface of [object IDBFactory]
+PASS Stringification of [object IDBFactory]
+PASS IDBFactory interface: [object IDBFactory] must inherit property "open(DOMString, unsigned long long)" with the proper type
+PASS IDBFactory interface: calling open(DOMString, unsigned long long) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBFactory interface: [object IDBFactory] must inherit property "deleteDatabase(DOMString)" with the proper type
+PASS IDBFactory interface: calling deleteDatabase(DOMString) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBFactory interface: [object IDBFactory] must inherit property "databases()" with the proper type
+PASS IDBFactory interface: [object IDBFactory] must inherit property "cmp(any, any)" with the proper type
+PASS IDBFactory interface: calling cmp(any, any) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBDatabase interface: existence and properties of interface object
+PASS IDBDatabase interface object length
+PASS IDBDatabase interface object name
+PASS IDBDatabase interface: existence and properties of interface prototype object
+PASS IDBDatabase interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBDatabase interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBDatabase interface: attribute name
+PASS IDBDatabase interface: attribute version
+PASS IDBDatabase interface: attribute objectStoreNames
+PASS IDBDatabase interface: operation transaction([object Object],[object Object], IDBTransactionMode)
+PASS IDBDatabase interface: operation close()
+PASS IDBDatabase interface: operation createObjectStore(DOMString, IDBObjectStoreParameters)
+PASS IDBDatabase interface: operation deleteObjectStore(DOMString)
+PASS IDBDatabase interface: attribute onabort
+PASS IDBDatabase interface: attribute onclose
+PASS IDBDatabase interface: attribute onerror
+PASS IDBDatabase interface: attribute onversionchange
+PASS IDBObjectStore interface: existence and properties of interface object
+PASS IDBObjectStore interface object length
+PASS IDBObjectStore interface object name
+PASS IDBObjectStore interface: existence and properties of interface prototype object
+PASS IDBObjectStore interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBObjectStore interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBObjectStore interface: attribute name
+PASS IDBObjectStore interface: attribute keyPath
+PASS IDBObjectStore interface: attribute indexNames
+PASS IDBObjectStore interface: attribute transaction
+PASS IDBObjectStore interface: attribute autoIncrement
+PASS IDBObjectStore interface: operation put(any, any)
+PASS IDBObjectStore interface: operation add(any, any)
+PASS IDBObjectStore interface: operation delete(any)
+PASS IDBObjectStore interface: operation clear()
+PASS IDBObjectStore interface: operation get(any)
+PASS IDBObjectStore interface: operation getKey(any)
+PASS IDBObjectStore interface: operation getAll(any, unsigned long)
+PASS IDBObjectStore interface: operation getAllKeys(any, unsigned long)
+PASS IDBObjectStore interface: operation count(any)
+PASS IDBObjectStore interface: operation openCursor(any, IDBCursorDirection)
+PASS IDBObjectStore interface: operation openKeyCursor(any, IDBCursorDirection)
+PASS IDBObjectStore interface: operation index(DOMString)
+PASS IDBObjectStore interface: operation createIndex(DOMString, [object Object],[object Object], IDBIndexParameters)
+PASS IDBObjectStore interface: operation deleteIndex(DOMString)
+PASS IDBIndex interface: existence and properties of interface object
+PASS IDBIndex interface object length
+PASS IDBIndex interface object name
+PASS IDBIndex interface: existence and properties of interface prototype object
+PASS IDBIndex interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBIndex interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBIndex interface: attribute name
+PASS IDBIndex interface: attribute objectStore
+PASS IDBIndex interface: attribute keyPath
+PASS IDBIndex interface: attribute multiEntry
+PASS IDBIndex interface: attribute unique
+PASS IDBIndex interface: operation get(any)
+PASS IDBIndex interface: operation getKey(any)
+PASS IDBIndex interface: operation getAll(any, unsigned long)
+PASS IDBIndex interface: operation getAllKeys(any, unsigned long)
+PASS IDBIndex interface: operation count(any)
+PASS IDBIndex interface: operation openCursor(any, IDBCursorDirection)
+PASS IDBIndex interface: operation openKeyCursor(any, IDBCursorDirection)
+PASS IDBKeyRange interface: existence and properties of interface object
+PASS IDBKeyRange interface object length
+PASS IDBKeyRange interface object name
+PASS IDBKeyRange interface: existence and properties of interface prototype object
+PASS IDBKeyRange interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBKeyRange interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBKeyRange interface: attribute lower
+PASS IDBKeyRange interface: attribute upper
+PASS IDBKeyRange interface: attribute lowerOpen
+PASS IDBKeyRange interface: attribute upperOpen
+PASS IDBKeyRange interface: operation only(any)
+PASS IDBKeyRange interface: operation lowerBound(any, boolean)
+PASS IDBKeyRange interface: operation upperBound(any, boolean)
+PASS IDBKeyRange interface: operation bound(any, any, boolean, boolean)
+PASS IDBKeyRange interface: operation includes(any)
+PASS IDBKeyRange must be primary interface of [object IDBKeyRange]
+PASS Stringification of [object IDBKeyRange]
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lower" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upper" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lowerOpen" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upperOpen" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "only(any)" with the proper type
+PASS IDBKeyRange interface: calling only(any) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lowerBound(any, boolean)" with the proper type
+PASS IDBKeyRange interface: calling lowerBound(any, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upperBound(any, boolean)" with the proper type
+PASS IDBKeyRange interface: calling upperBound(any, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "bound(any, any, boolean, boolean)" with the proper type
+PASS IDBKeyRange interface: calling bound(any, any, boolean, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "includes(any)" with the proper type
+PASS IDBKeyRange interface: calling includes(any) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBCursor interface: existence and properties of interface object
+PASS IDBCursor interface object length
+PASS IDBCursor interface object name
+PASS IDBCursor interface: existence and properties of interface prototype object
+PASS IDBCursor interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBCursor interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBCursor interface: attribute source
+PASS IDBCursor interface: attribute direction
+PASS IDBCursor interface: attribute key
+PASS IDBCursor interface: attribute primaryKey
+FAIL IDBCursor interface: attribute request assert_true: The prototype object must have a property "request" expected true got false
+PASS IDBCursor interface: operation advance(unsigned long)
+PASS IDBCursor interface: operation continue(any)
+PASS IDBCursor interface: operation continuePrimaryKey(any, any)
+PASS IDBCursor interface: operation update(any)
+PASS IDBCursor interface: operation delete()
+PASS IDBCursorWithValue interface: existence and properties of interface object
+PASS IDBCursorWithValue interface object length
+PASS IDBCursorWithValue interface object name
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBCursorWithValue interface: attribute value
+PASS IDBTransaction interface: existence and properties of interface object
+PASS IDBTransaction interface object length
+PASS IDBTransaction interface object name
+PASS IDBTransaction interface: existence and properties of interface prototype object
+PASS IDBTransaction interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBTransaction interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBTransaction interface: attribute objectStoreNames
+PASS IDBTransaction interface: attribute mode
+PASS IDBTransaction interface: attribute db
+PASS IDBTransaction interface: attribute error
+PASS IDBTransaction interface: operation objectStore(DOMString)
+PASS IDBTransaction interface: operation commit()
+PASS IDBTransaction interface: operation abort()
+PASS IDBTransaction interface: attribute onabort
+PASS IDBTransaction interface: attribute oncomplete
+PASS IDBTransaction interface: attribute onerror
+PASS Window interface: attribute indexedDB
+PASS WorkerGlobalScope interface: existence and properties of interface object
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any.serviceworker-expected.txt
new file mode 100644
index 0000000..2dc632c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any.serviceworker-expected.txt
@@ -0,0 +1,190 @@
+This is a testharness.js-based test.
+Found 186 tests; 185 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS idl_test setup
+PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
+PASS IDBRequest interface: existence and properties of interface object
+PASS IDBRequest interface object length
+PASS IDBRequest interface object name
+PASS IDBRequest interface: existence and properties of interface prototype object
+PASS IDBRequest interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBRequest interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBRequest interface: attribute result
+PASS IDBRequest interface: attribute error
+PASS IDBRequest interface: attribute source
+PASS IDBRequest interface: attribute transaction
+PASS IDBRequest interface: attribute readyState
+PASS IDBRequest interface: attribute onsuccess
+PASS IDBRequest interface: attribute onerror
+PASS IDBOpenDBRequest interface: existence and properties of interface object
+PASS IDBOpenDBRequest interface object length
+PASS IDBOpenDBRequest interface object name
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBOpenDBRequest interface: attribute onblocked
+PASS IDBOpenDBRequest interface: attribute onupgradeneeded
+PASS IDBVersionChangeEvent interface: existence and properties of interface object
+PASS IDBVersionChangeEvent interface object length
+PASS IDBVersionChangeEvent interface object name
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBVersionChangeEvent interface: attribute oldVersion
+PASS IDBVersionChangeEvent interface: attribute newVersion
+PASS IDBVersionChangeEvent must be primary interface of new IDBVersionChangeEvent("type")
+PASS Stringification of new IDBVersionChangeEvent("type")
+PASS IDBVersionChangeEvent interface: new IDBVersionChangeEvent("type") must inherit property "oldVersion" with the proper type
+PASS IDBVersionChangeEvent interface: new IDBVersionChangeEvent("type") must inherit property "newVersion" with the proper type
+PASS IDBFactory interface: existence and properties of interface object
+PASS IDBFactory interface object length
+PASS IDBFactory interface object name
+PASS IDBFactory interface: existence and properties of interface prototype object
+PASS IDBFactory interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBFactory interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBFactory interface: operation open(DOMString, unsigned long long)
+PASS IDBFactory interface: operation deleteDatabase(DOMString)
+PASS IDBFactory interface: operation databases()
+PASS IDBFactory interface: operation cmp(any, any)
+PASS IDBFactory must be primary interface of [object IDBFactory]
+PASS Stringification of [object IDBFactory]
+PASS IDBFactory interface: [object IDBFactory] must inherit property "open(DOMString, unsigned long long)" with the proper type
+PASS IDBFactory interface: calling open(DOMString, unsigned long long) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBFactory interface: [object IDBFactory] must inherit property "deleteDatabase(DOMString)" with the proper type
+PASS IDBFactory interface: calling deleteDatabase(DOMString) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBFactory interface: [object IDBFactory] must inherit property "databases()" with the proper type
+PASS IDBFactory interface: [object IDBFactory] must inherit property "cmp(any, any)" with the proper type
+PASS IDBFactory interface: calling cmp(any, any) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBDatabase interface: existence and properties of interface object
+PASS IDBDatabase interface object length
+PASS IDBDatabase interface object name
+PASS IDBDatabase interface: existence and properties of interface prototype object
+PASS IDBDatabase interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBDatabase interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBDatabase interface: attribute name
+PASS IDBDatabase interface: attribute version
+PASS IDBDatabase interface: attribute objectStoreNames
+PASS IDBDatabase interface: operation transaction([object Object],[object Object], IDBTransactionMode)
+PASS IDBDatabase interface: operation close()
+PASS IDBDatabase interface: operation createObjectStore(DOMString, IDBObjectStoreParameters)
+PASS IDBDatabase interface: operation deleteObjectStore(DOMString)
+PASS IDBDatabase interface: attribute onabort
+PASS IDBDatabase interface: attribute onclose
+PASS IDBDatabase interface: attribute onerror
+PASS IDBDatabase interface: attribute onversionchange
+PASS IDBObjectStore interface: existence and properties of interface object
+PASS IDBObjectStore interface object length
+PASS IDBObjectStore interface object name
+PASS IDBObjectStore interface: existence and properties of interface prototype object
+PASS IDBObjectStore interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBObjectStore interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBObjectStore interface: attribute name
+PASS IDBObjectStore interface: attribute keyPath
+PASS IDBObjectStore interface: attribute indexNames
+PASS IDBObjectStore interface: attribute transaction
+PASS IDBObjectStore interface: attribute autoIncrement
+PASS IDBObjectStore interface: operation put(any, any)
+PASS IDBObjectStore interface: operation add(any, any)
+PASS IDBObjectStore interface: operation delete(any)
+PASS IDBObjectStore interface: operation clear()
+PASS IDBObjectStore interface: operation get(any)
+PASS IDBObjectStore interface: operation getKey(any)
+PASS IDBObjectStore interface: operation getAll(any, unsigned long)
+PASS IDBObjectStore interface: operation getAllKeys(any, unsigned long)
+PASS IDBObjectStore interface: operation count(any)
+PASS IDBObjectStore interface: operation openCursor(any, IDBCursorDirection)
+PASS IDBObjectStore interface: operation openKeyCursor(any, IDBCursorDirection)
+PASS IDBObjectStore interface: operation index(DOMString)
+PASS IDBObjectStore interface: operation createIndex(DOMString, [object Object],[object Object], IDBIndexParameters)
+PASS IDBObjectStore interface: operation deleteIndex(DOMString)
+PASS IDBIndex interface: existence and properties of interface object
+PASS IDBIndex interface object length
+PASS IDBIndex interface object name
+PASS IDBIndex interface: existence and properties of interface prototype object
+PASS IDBIndex interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBIndex interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBIndex interface: attribute name
+PASS IDBIndex interface: attribute objectStore
+PASS IDBIndex interface: attribute keyPath
+PASS IDBIndex interface: attribute multiEntry
+PASS IDBIndex interface: attribute unique
+PASS IDBIndex interface: operation get(any)
+PASS IDBIndex interface: operation getKey(any)
+PASS IDBIndex interface: operation getAll(any, unsigned long)
+PASS IDBIndex interface: operation getAllKeys(any, unsigned long)
+PASS IDBIndex interface: operation count(any)
+PASS IDBIndex interface: operation openCursor(any, IDBCursorDirection)
+PASS IDBIndex interface: operation openKeyCursor(any, IDBCursorDirection)
+PASS IDBKeyRange interface: existence and properties of interface object
+PASS IDBKeyRange interface object length
+PASS IDBKeyRange interface object name
+PASS IDBKeyRange interface: existence and properties of interface prototype object
+PASS IDBKeyRange interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBKeyRange interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBKeyRange interface: attribute lower
+PASS IDBKeyRange interface: attribute upper
+PASS IDBKeyRange interface: attribute lowerOpen
+PASS IDBKeyRange interface: attribute upperOpen
+PASS IDBKeyRange interface: operation only(any)
+PASS IDBKeyRange interface: operation lowerBound(any, boolean)
+PASS IDBKeyRange interface: operation upperBound(any, boolean)
+PASS IDBKeyRange interface: operation bound(any, any, boolean, boolean)
+PASS IDBKeyRange interface: operation includes(any)
+PASS IDBKeyRange must be primary interface of [object IDBKeyRange]
+PASS Stringification of [object IDBKeyRange]
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lower" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upper" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lowerOpen" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upperOpen" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "only(any)" with the proper type
+PASS IDBKeyRange interface: calling only(any) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lowerBound(any, boolean)" with the proper type
+PASS IDBKeyRange interface: calling lowerBound(any, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upperBound(any, boolean)" with the proper type
+PASS IDBKeyRange interface: calling upperBound(any, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "bound(any, any, boolean, boolean)" with the proper type
+PASS IDBKeyRange interface: calling bound(any, any, boolean, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "includes(any)" with the proper type
+PASS IDBKeyRange interface: calling includes(any) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBCursor interface: existence and properties of interface object
+PASS IDBCursor interface object length
+PASS IDBCursor interface object name
+PASS IDBCursor interface: existence and properties of interface prototype object
+PASS IDBCursor interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBCursor interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBCursor interface: attribute source
+PASS IDBCursor interface: attribute direction
+PASS IDBCursor interface: attribute key
+PASS IDBCursor interface: attribute primaryKey
+FAIL IDBCursor interface: attribute request assert_true: The prototype object must have a property "request" expected true got false
+PASS IDBCursor interface: operation advance(unsigned long)
+PASS IDBCursor interface: operation continue(any)
+PASS IDBCursor interface: operation continuePrimaryKey(any, any)
+PASS IDBCursor interface: operation update(any)
+PASS IDBCursor interface: operation delete()
+PASS IDBCursorWithValue interface: existence and properties of interface object
+PASS IDBCursorWithValue interface object length
+PASS IDBCursorWithValue interface object name
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBCursorWithValue interface: attribute value
+PASS IDBTransaction interface: existence and properties of interface object
+PASS IDBTransaction interface object length
+PASS IDBTransaction interface object name
+PASS IDBTransaction interface: existence and properties of interface prototype object
+PASS IDBTransaction interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBTransaction interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBTransaction interface: attribute objectStoreNames
+PASS IDBTransaction interface: attribute mode
+PASS IDBTransaction interface: attribute db
+PASS IDBTransaction interface: attribute error
+PASS IDBTransaction interface: operation objectStore(DOMString)
+PASS IDBTransaction interface: operation commit()
+PASS IDBTransaction interface: operation abort()
+PASS IDBTransaction interface: attribute onabort
+PASS IDBTransaction interface: attribute oncomplete
+PASS IDBTransaction interface: attribute onerror
+PASS Window interface: existence and properties of interface object
+PASS WorkerGlobalScope interface: attribute indexedDB
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any.sharedworker-expected.txt
new file mode 100644
index 0000000..2dc632c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any.sharedworker-expected.txt
@@ -0,0 +1,190 @@
+This is a testharness.js-based test.
+Found 186 tests; 185 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS idl_test setup
+PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
+PASS IDBRequest interface: existence and properties of interface object
+PASS IDBRequest interface object length
+PASS IDBRequest interface object name
+PASS IDBRequest interface: existence and properties of interface prototype object
+PASS IDBRequest interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBRequest interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBRequest interface: attribute result
+PASS IDBRequest interface: attribute error
+PASS IDBRequest interface: attribute source
+PASS IDBRequest interface: attribute transaction
+PASS IDBRequest interface: attribute readyState
+PASS IDBRequest interface: attribute onsuccess
+PASS IDBRequest interface: attribute onerror
+PASS IDBOpenDBRequest interface: existence and properties of interface object
+PASS IDBOpenDBRequest interface object length
+PASS IDBOpenDBRequest interface object name
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBOpenDBRequest interface: attribute onblocked
+PASS IDBOpenDBRequest interface: attribute onupgradeneeded
+PASS IDBVersionChangeEvent interface: existence and properties of interface object
+PASS IDBVersionChangeEvent interface object length
+PASS IDBVersionChangeEvent interface object name
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBVersionChangeEvent interface: attribute oldVersion
+PASS IDBVersionChangeEvent interface: attribute newVersion
+PASS IDBVersionChangeEvent must be primary interface of new IDBVersionChangeEvent("type")
+PASS Stringification of new IDBVersionChangeEvent("type")
+PASS IDBVersionChangeEvent interface: new IDBVersionChangeEvent("type") must inherit property "oldVersion" with the proper type
+PASS IDBVersionChangeEvent interface: new IDBVersionChangeEvent("type") must inherit property "newVersion" with the proper type
+PASS IDBFactory interface: existence and properties of interface object
+PASS IDBFactory interface object length
+PASS IDBFactory interface object name
+PASS IDBFactory interface: existence and properties of interface prototype object
+PASS IDBFactory interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBFactory interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBFactory interface: operation open(DOMString, unsigned long long)
+PASS IDBFactory interface: operation deleteDatabase(DOMString)
+PASS IDBFactory interface: operation databases()
+PASS IDBFactory interface: operation cmp(any, any)
+PASS IDBFactory must be primary interface of [object IDBFactory]
+PASS Stringification of [object IDBFactory]
+PASS IDBFactory interface: [object IDBFactory] must inherit property "open(DOMString, unsigned long long)" with the proper type
+PASS IDBFactory interface: calling open(DOMString, unsigned long long) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBFactory interface: [object IDBFactory] must inherit property "deleteDatabase(DOMString)" with the proper type
+PASS IDBFactory interface: calling deleteDatabase(DOMString) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBFactory interface: [object IDBFactory] must inherit property "databases()" with the proper type
+PASS IDBFactory interface: [object IDBFactory] must inherit property "cmp(any, any)" with the proper type
+PASS IDBFactory interface: calling cmp(any, any) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBDatabase interface: existence and properties of interface object
+PASS IDBDatabase interface object length
+PASS IDBDatabase interface object name
+PASS IDBDatabase interface: existence and properties of interface prototype object
+PASS IDBDatabase interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBDatabase interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBDatabase interface: attribute name
+PASS IDBDatabase interface: attribute version
+PASS IDBDatabase interface: attribute objectStoreNames
+PASS IDBDatabase interface: operation transaction([object Object],[object Object], IDBTransactionMode)
+PASS IDBDatabase interface: operation close()
+PASS IDBDatabase interface: operation createObjectStore(DOMString, IDBObjectStoreParameters)
+PASS IDBDatabase interface: operation deleteObjectStore(DOMString)
+PASS IDBDatabase interface: attribute onabort
+PASS IDBDatabase interface: attribute onclose
+PASS IDBDatabase interface: attribute onerror
+PASS IDBDatabase interface: attribute onversionchange
+PASS IDBObjectStore interface: existence and properties of interface object
+PASS IDBObjectStore interface object length
+PASS IDBObjectStore interface object name
+PASS IDBObjectStore interface: existence and properties of interface prototype object
+PASS IDBObjectStore interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBObjectStore interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBObjectStore interface: attribute name
+PASS IDBObjectStore interface: attribute keyPath
+PASS IDBObjectStore interface: attribute indexNames
+PASS IDBObjectStore interface: attribute transaction
+PASS IDBObjectStore interface: attribute autoIncrement
+PASS IDBObjectStore interface: operation put(any, any)
+PASS IDBObjectStore interface: operation add(any, any)
+PASS IDBObjectStore interface: operation delete(any)
+PASS IDBObjectStore interface: operation clear()
+PASS IDBObjectStore interface: operation get(any)
+PASS IDBObjectStore interface: operation getKey(any)
+PASS IDBObjectStore interface: operation getAll(any, unsigned long)
+PASS IDBObjectStore interface: operation getAllKeys(any, unsigned long)
+PASS IDBObjectStore interface: operation count(any)
+PASS IDBObjectStore interface: operation openCursor(any, IDBCursorDirection)
+PASS IDBObjectStore interface: operation openKeyCursor(any, IDBCursorDirection)
+PASS IDBObjectStore interface: operation index(DOMString)
+PASS IDBObjectStore interface: operation createIndex(DOMString, [object Object],[object Object], IDBIndexParameters)
+PASS IDBObjectStore interface: operation deleteIndex(DOMString)
+PASS IDBIndex interface: existence and properties of interface object
+PASS IDBIndex interface object length
+PASS IDBIndex interface object name
+PASS IDBIndex interface: existence and properties of interface prototype object
+PASS IDBIndex interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBIndex interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBIndex interface: attribute name
+PASS IDBIndex interface: attribute objectStore
+PASS IDBIndex interface: attribute keyPath
+PASS IDBIndex interface: attribute multiEntry
+PASS IDBIndex interface: attribute unique
+PASS IDBIndex interface: operation get(any)
+PASS IDBIndex interface: operation getKey(any)
+PASS IDBIndex interface: operation getAll(any, unsigned long)
+PASS IDBIndex interface: operation getAllKeys(any, unsigned long)
+PASS IDBIndex interface: operation count(any)
+PASS IDBIndex interface: operation openCursor(any, IDBCursorDirection)
+PASS IDBIndex interface: operation openKeyCursor(any, IDBCursorDirection)
+PASS IDBKeyRange interface: existence and properties of interface object
+PASS IDBKeyRange interface object length
+PASS IDBKeyRange interface object name
+PASS IDBKeyRange interface: existence and properties of interface prototype object
+PASS IDBKeyRange interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBKeyRange interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBKeyRange interface: attribute lower
+PASS IDBKeyRange interface: attribute upper
+PASS IDBKeyRange interface: attribute lowerOpen
+PASS IDBKeyRange interface: attribute upperOpen
+PASS IDBKeyRange interface: operation only(any)
+PASS IDBKeyRange interface: operation lowerBound(any, boolean)
+PASS IDBKeyRange interface: operation upperBound(any, boolean)
+PASS IDBKeyRange interface: operation bound(any, any, boolean, boolean)
+PASS IDBKeyRange interface: operation includes(any)
+PASS IDBKeyRange must be primary interface of [object IDBKeyRange]
+PASS Stringification of [object IDBKeyRange]
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lower" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upper" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lowerOpen" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upperOpen" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "only(any)" with the proper type
+PASS IDBKeyRange interface: calling only(any) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lowerBound(any, boolean)" with the proper type
+PASS IDBKeyRange interface: calling lowerBound(any, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upperBound(any, boolean)" with the proper type
+PASS IDBKeyRange interface: calling upperBound(any, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "bound(any, any, boolean, boolean)" with the proper type
+PASS IDBKeyRange interface: calling bound(any, any, boolean, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "includes(any)" with the proper type
+PASS IDBKeyRange interface: calling includes(any) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBCursor interface: existence and properties of interface object
+PASS IDBCursor interface object length
+PASS IDBCursor interface object name
+PASS IDBCursor interface: existence and properties of interface prototype object
+PASS IDBCursor interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBCursor interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBCursor interface: attribute source
+PASS IDBCursor interface: attribute direction
+PASS IDBCursor interface: attribute key
+PASS IDBCursor interface: attribute primaryKey
+FAIL IDBCursor interface: attribute request assert_true: The prototype object must have a property "request" expected true got false
+PASS IDBCursor interface: operation advance(unsigned long)
+PASS IDBCursor interface: operation continue(any)
+PASS IDBCursor interface: operation continuePrimaryKey(any, any)
+PASS IDBCursor interface: operation update(any)
+PASS IDBCursor interface: operation delete()
+PASS IDBCursorWithValue interface: existence and properties of interface object
+PASS IDBCursorWithValue interface object length
+PASS IDBCursorWithValue interface object name
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBCursorWithValue interface: attribute value
+PASS IDBTransaction interface: existence and properties of interface object
+PASS IDBTransaction interface object length
+PASS IDBTransaction interface object name
+PASS IDBTransaction interface: existence and properties of interface prototype object
+PASS IDBTransaction interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBTransaction interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBTransaction interface: attribute objectStoreNames
+PASS IDBTransaction interface: attribute mode
+PASS IDBTransaction interface: attribute db
+PASS IDBTransaction interface: attribute error
+PASS IDBTransaction interface: operation objectStore(DOMString)
+PASS IDBTransaction interface: operation commit()
+PASS IDBTransaction interface: operation abort()
+PASS IDBTransaction interface: attribute onabort
+PASS IDBTransaction interface: attribute oncomplete
+PASS IDBTransaction interface: attribute onerror
+PASS Window interface: existence and properties of interface object
+PASS WorkerGlobalScope interface: attribute indexedDB
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any.worker-expected.txt
new file mode 100644
index 0000000..2dc632c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idlharness.any.worker-expected.txt
@@ -0,0 +1,190 @@
+This is a testharness.js-based test.
+Found 186 tests; 185 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS idl_test setup
+PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
+PASS IDBRequest interface: existence and properties of interface object
+PASS IDBRequest interface object length
+PASS IDBRequest interface object name
+PASS IDBRequest interface: existence and properties of interface prototype object
+PASS IDBRequest interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBRequest interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBRequest interface: attribute result
+PASS IDBRequest interface: attribute error
+PASS IDBRequest interface: attribute source
+PASS IDBRequest interface: attribute transaction
+PASS IDBRequest interface: attribute readyState
+PASS IDBRequest interface: attribute onsuccess
+PASS IDBRequest interface: attribute onerror
+PASS IDBOpenDBRequest interface: existence and properties of interface object
+PASS IDBOpenDBRequest interface object length
+PASS IDBOpenDBRequest interface object name
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBOpenDBRequest interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBOpenDBRequest interface: attribute onblocked
+PASS IDBOpenDBRequest interface: attribute onupgradeneeded
+PASS IDBVersionChangeEvent interface: existence and properties of interface object
+PASS IDBVersionChangeEvent interface object length
+PASS IDBVersionChangeEvent interface object name
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBVersionChangeEvent interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBVersionChangeEvent interface: attribute oldVersion
+PASS IDBVersionChangeEvent interface: attribute newVersion
+PASS IDBVersionChangeEvent must be primary interface of new IDBVersionChangeEvent("type")
+PASS Stringification of new IDBVersionChangeEvent("type")
+PASS IDBVersionChangeEvent interface: new IDBVersionChangeEvent("type") must inherit property "oldVersion" with the proper type
+PASS IDBVersionChangeEvent interface: new IDBVersionChangeEvent("type") must inherit property "newVersion" with the proper type
+PASS IDBFactory interface: existence and properties of interface object
+PASS IDBFactory interface object length
+PASS IDBFactory interface object name
+PASS IDBFactory interface: existence and properties of interface prototype object
+PASS IDBFactory interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBFactory interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBFactory interface: operation open(DOMString, unsigned long long)
+PASS IDBFactory interface: operation deleteDatabase(DOMString)
+PASS IDBFactory interface: operation databases()
+PASS IDBFactory interface: operation cmp(any, any)
+PASS IDBFactory must be primary interface of [object IDBFactory]
+PASS Stringification of [object IDBFactory]
+PASS IDBFactory interface: [object IDBFactory] must inherit property "open(DOMString, unsigned long long)" with the proper type
+PASS IDBFactory interface: calling open(DOMString, unsigned long long) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBFactory interface: [object IDBFactory] must inherit property "deleteDatabase(DOMString)" with the proper type
+PASS IDBFactory interface: calling deleteDatabase(DOMString) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBFactory interface: [object IDBFactory] must inherit property "databases()" with the proper type
+PASS IDBFactory interface: [object IDBFactory] must inherit property "cmp(any, any)" with the proper type
+PASS IDBFactory interface: calling cmp(any, any) on [object IDBFactory] with too few arguments must throw TypeError
+PASS IDBDatabase interface: existence and properties of interface object
+PASS IDBDatabase interface object length
+PASS IDBDatabase interface object name
+PASS IDBDatabase interface: existence and properties of interface prototype object
+PASS IDBDatabase interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBDatabase interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBDatabase interface: attribute name
+PASS IDBDatabase interface: attribute version
+PASS IDBDatabase interface: attribute objectStoreNames
+PASS IDBDatabase interface: operation transaction([object Object],[object Object], IDBTransactionMode)
+PASS IDBDatabase interface: operation close()
+PASS IDBDatabase interface: operation createObjectStore(DOMString, IDBObjectStoreParameters)
+PASS IDBDatabase interface: operation deleteObjectStore(DOMString)
+PASS IDBDatabase interface: attribute onabort
+PASS IDBDatabase interface: attribute onclose
+PASS IDBDatabase interface: attribute onerror
+PASS IDBDatabase interface: attribute onversionchange
+PASS IDBObjectStore interface: existence and properties of interface object
+PASS IDBObjectStore interface object length
+PASS IDBObjectStore interface object name
+PASS IDBObjectStore interface: existence and properties of interface prototype object
+PASS IDBObjectStore interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBObjectStore interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBObjectStore interface: attribute name
+PASS IDBObjectStore interface: attribute keyPath
+PASS IDBObjectStore interface: attribute indexNames
+PASS IDBObjectStore interface: attribute transaction
+PASS IDBObjectStore interface: attribute autoIncrement
+PASS IDBObjectStore interface: operation put(any, any)
+PASS IDBObjectStore interface: operation add(any, any)
+PASS IDBObjectStore interface: operation delete(any)
+PASS IDBObjectStore interface: operation clear()
+PASS IDBObjectStore interface: operation get(any)
+PASS IDBObjectStore interface: operation getKey(any)
+PASS IDBObjectStore interface: operation getAll(any, unsigned long)
+PASS IDBObjectStore interface: operation getAllKeys(any, unsigned long)
+PASS IDBObjectStore interface: operation count(any)
+PASS IDBObjectStore interface: operation openCursor(any, IDBCursorDirection)
+PASS IDBObjectStore interface: operation openKeyCursor(any, IDBCursorDirection)
+PASS IDBObjectStore interface: operation index(DOMString)
+PASS IDBObjectStore interface: operation createIndex(DOMString, [object Object],[object Object], IDBIndexParameters)
+PASS IDBObjectStore interface: operation deleteIndex(DOMString)
+PASS IDBIndex interface: existence and properties of interface object
+PASS IDBIndex interface object length
+PASS IDBIndex interface object name
+PASS IDBIndex interface: existence and properties of interface prototype object
+PASS IDBIndex interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBIndex interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBIndex interface: attribute name
+PASS IDBIndex interface: attribute objectStore
+PASS IDBIndex interface: attribute keyPath
+PASS IDBIndex interface: attribute multiEntry
+PASS IDBIndex interface: attribute unique
+PASS IDBIndex interface: operation get(any)
+PASS IDBIndex interface: operation getKey(any)
+PASS IDBIndex interface: operation getAll(any, unsigned long)
+PASS IDBIndex interface: operation getAllKeys(any, unsigned long)
+PASS IDBIndex interface: operation count(any)
+PASS IDBIndex interface: operation openCursor(any, IDBCursorDirection)
+PASS IDBIndex interface: operation openKeyCursor(any, IDBCursorDirection)
+PASS IDBKeyRange interface: existence and properties of interface object
+PASS IDBKeyRange interface object length
+PASS IDBKeyRange interface object name
+PASS IDBKeyRange interface: existence and properties of interface prototype object
+PASS IDBKeyRange interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBKeyRange interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBKeyRange interface: attribute lower
+PASS IDBKeyRange interface: attribute upper
+PASS IDBKeyRange interface: attribute lowerOpen
+PASS IDBKeyRange interface: attribute upperOpen
+PASS IDBKeyRange interface: operation only(any)
+PASS IDBKeyRange interface: operation lowerBound(any, boolean)
+PASS IDBKeyRange interface: operation upperBound(any, boolean)
+PASS IDBKeyRange interface: operation bound(any, any, boolean, boolean)
+PASS IDBKeyRange interface: operation includes(any)
+PASS IDBKeyRange must be primary interface of [object IDBKeyRange]
+PASS Stringification of [object IDBKeyRange]
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lower" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upper" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lowerOpen" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upperOpen" with the proper type
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "only(any)" with the proper type
+PASS IDBKeyRange interface: calling only(any) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "lowerBound(any, boolean)" with the proper type
+PASS IDBKeyRange interface: calling lowerBound(any, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "upperBound(any, boolean)" with the proper type
+PASS IDBKeyRange interface: calling upperBound(any, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "bound(any, any, boolean, boolean)" with the proper type
+PASS IDBKeyRange interface: calling bound(any, any, boolean, boolean) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBKeyRange interface: [object IDBKeyRange] must inherit property "includes(any)" with the proper type
+PASS IDBKeyRange interface: calling includes(any) on [object IDBKeyRange] with too few arguments must throw TypeError
+PASS IDBCursor interface: existence and properties of interface object
+PASS IDBCursor interface object length
+PASS IDBCursor interface object name
+PASS IDBCursor interface: existence and properties of interface prototype object
+PASS IDBCursor interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBCursor interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBCursor interface: attribute source
+PASS IDBCursor interface: attribute direction
+PASS IDBCursor interface: attribute key
+PASS IDBCursor interface: attribute primaryKey
+FAIL IDBCursor interface: attribute request assert_true: The prototype object must have a property "request" expected true got false
+PASS IDBCursor interface: operation advance(unsigned long)
+PASS IDBCursor interface: operation continue(any)
+PASS IDBCursor interface: operation continuePrimaryKey(any, any)
+PASS IDBCursor interface: operation update(any)
+PASS IDBCursor interface: operation delete()
+PASS IDBCursorWithValue interface: existence and properties of interface object
+PASS IDBCursorWithValue interface object length
+PASS IDBCursorWithValue interface object name
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBCursorWithValue interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBCursorWithValue interface: attribute value
+PASS IDBTransaction interface: existence and properties of interface object
+PASS IDBTransaction interface object length
+PASS IDBTransaction interface object name
+PASS IDBTransaction interface: existence and properties of interface prototype object
+PASS IDBTransaction interface: existence and properties of interface prototype object's "constructor" property
+PASS IDBTransaction interface: existence and properties of interface prototype object's @@unscopables property
+PASS IDBTransaction interface: attribute objectStoreNames
+PASS IDBTransaction interface: attribute mode
+PASS IDBTransaction interface: attribute db
+PASS IDBTransaction interface: attribute error
+PASS IDBTransaction interface: operation objectStore(DOMString)
+PASS IDBTransaction interface: operation commit()
+PASS IDBTransaction interface: operation abort()
+PASS IDBTransaction interface: attribute onabort
+PASS IDBTransaction interface: attribute oncomplete
+PASS IDBTransaction interface: attribute onerror
+PASS Window interface: existence and properties of interface object
+PASS WorkerGlobalScope interface: attribute indexedDB
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-interfaces.https-expected.txt b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-interfaces.https-expected.txt
new file mode 100644
index 0000000..6719ecb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-interfaces.https-expected.txt
@@ -0,0 +1,47 @@
+This is a testharness.js-based test.
+PASS Test driver
+PASS Partial interface Navigator: original interface defined
+PASS Navigator interface: attribute clipboard
+PASS Navigator interface: navigator must inherit property "clipboard" with the proper type
+PASS ClipboardEvent interface: existence and properties of interface object
+PASS ClipboardEvent interface object length
+PASS ClipboardEvent interface object name
+PASS ClipboardEvent interface: existence and properties of interface prototype object
+PASS ClipboardEvent interface: existence and properties of interface prototype object's "constructor" property
+PASS ClipboardEvent interface: existence and properties of interface prototype object's @@unscopables property
+PASS ClipboardEvent interface: attribute clipboardData
+PASS ClipboardEvent must be primary interface of new ClipboardEvent("x")
+PASS Stringification of new ClipboardEvent("x")
+PASS ClipboardEvent interface: new ClipboardEvent("x") must inherit property "clipboardData" with the proper type
+PASS Clipboard interface: existence and properties of interface object
+PASS Clipboard interface object length
+PASS Clipboard interface object name
+PASS Clipboard interface: existence and properties of interface prototype object
+PASS Clipboard interface: existence and properties of interface prototype object's "constructor" property
+PASS Clipboard interface: existence and properties of interface prototype object's @@unscopables property
+PASS Clipboard interface: operation read()
+PASS Clipboard interface: operation readText()
+PASS Clipboard interface: operation write(ClipboardItems)
+PASS Clipboard interface: operation writeText(DOMString)
+PASS Clipboard must be primary interface of navigator.clipboard
+PASS Stringification of navigator.clipboard
+PASS Clipboard interface: navigator.clipboard must inherit property "read()" with the proper type
+PASS Clipboard interface: navigator.clipboard must inherit property "readText()" with the proper type
+PASS Clipboard interface: navigator.clipboard must inherit property "write(ClipboardItems)" with the proper type
+PASS Clipboard interface: calling write(ClipboardItems) on navigator.clipboard with too few arguments must throw TypeError
+PASS Clipboard interface: navigator.clipboard must inherit property "writeText(DOMString)" with the proper type
+PASS Clipboard interface: calling writeText(DOMString) on navigator.clipboard with too few arguments must throw TypeError
+FAIL ClipboardItem interface: existence and properties of interface object assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface object length assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface object name assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface: operation createDelayed([object Object],[object Object], ClipboardItemOptions) assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface: attribute presentationStyle assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface: attribute lastModified assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface: attribute delayed assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface: attribute types assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+FAIL ClipboardItem interface: operation getType(DOMString) assert_own_property: self does not have own property "ClipboardItem" expected property "ClipboardItem" missing
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/common/object-association.js b/third_party/blink/web_tests/external/wpt/common/object-association.js
index e1ab07e7..d58f94b 100644
--- a/third_party/blink/web_tests/external/wpt/common/object-association.js
+++ b/third_party/blink/web_tests/external/wpt/common/object-association.js
@@ -41,9 +41,7 @@
     iframe.src = "/common/blank.html";
   }, `Navigating from the initial about:blank must not replace window.${propertyName}`);
 
-  // Note: document.open()'s spec doesn't match most browsers; see https://github.com/whatwg/html/issues/1698.
-  // However, as explained in https://github.com/whatwg/html/issues/1698#issuecomment-298748641, even an updated spec
-  // will probably still reset Window-associated properties.
+  // Per spec, document.open() should not change any of the Window state.
   async_test(t => {
     const iframe = document.createElement("iframe");
 
@@ -55,7 +53,7 @@
       frame.document.open();
 
       const after = frame[propertyName];
-      assert_not_equals(after, before);
+      assert_equals(after, before);
 
       frame.document.close();
     });
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-003.xht b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-003.xht
index 239a554..cf9f5394 100644
--- a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-003.xht
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-003.xht
@@ -43,7 +43,7 @@
         </style>
     </head>
     <body>
-        <p>Test passes if there are two black squares on the page.</p>
+        <p>Test passes if there are 2 filled black squares.</p>
         <div id="test">XX   XX</div>
         <div id="reference"><div id="div1"></div><div id="div2"></div><div id="div3"></div></div>
     </body>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-pre-element-001-ref.xht b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-pre-element-001-ref.xht
index f000117..fecdfb1 100644
--- a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-pre-element-001-ref.xht
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-pre-element-001-ref.xht
@@ -9,6 +9,7 @@
             {
                 font-family: monospace;
                 font-size: 10pt;
+                margin: 0;
             }
             div
             {
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-pre-element-001.xht b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-pre-element-001.xht
index cf49962d..7ec2ba8 100644
--- a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-pre-element-001.xht
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-pre-element-001.xht
@@ -12,6 +12,7 @@
             {
                 font-family: monospace;
                 font-size: 10pt;
+                margin: 0;
             }
             div
             {
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-040.xht b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-040.xht
index 857107ea..03245a2 100644
--- a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-040.xht
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-040.xht
@@ -16,12 +16,12 @@
             #div1
             {
                 white-space: pre-wrap;
+                margin-left: -1em;
             }
             #div2
             {
                 background: black;
                 height: 1em;
-                margin-left: 1em;
                 width: 1em;
             }
         </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/idlharness-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-pseudo/idlharness-expected.txt
index c7e205c..9774152 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/idlharness-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/idlharness-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 FAIL idl_test setup promise_test: Unhandled rejection with value: object "TypeError: window.getPseudoElements is not a function"
-PASS Partial interface Window: original interface defined
+PASS Partial interface Element: original interface defined
 FAIL CSSPseudoElement interface: existence and properties of interface object assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
 FAIL CSSPseudoElement interface object length assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
 FAIL CSSPseudoElement interface object name assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
@@ -9,30 +9,10 @@
 FAIL CSSPseudoElement interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
 FAIL CSSPseudoElement interface: attribute type assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
 FAIL CSSPseudoElement interface: attribute element assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: attribute style assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
 FAIL CSSPseudoElement must be primary interface of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
 FAIL Stringification of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
 FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "type" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
 FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "element" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
-FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "style" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
-FAIL CSSPseudoElementList interface: existence and properties of interface object assert_own_property: self does not have own property "CSSPseudoElementList" expected property "CSSPseudoElementList" missing
-FAIL CSSPseudoElementList interface object length assert_own_property: self does not have own property "CSSPseudoElementList" expected property "CSSPseudoElementList" missing
-FAIL CSSPseudoElementList interface object name assert_own_property: self does not have own property "CSSPseudoElementList" expected property "CSSPseudoElementList" missing
-FAIL CSSPseudoElementList interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CSSPseudoElementList" expected property "CSSPseudoElementList" missing
-FAIL CSSPseudoElementList interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CSSPseudoElementList" expected property "CSSPseudoElementList" missing
-FAIL CSSPseudoElementList interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CSSPseudoElementList" expected property "CSSPseudoElementList" missing
-FAIL CSSPseudoElementList interface: attribute length assert_own_property: self does not have own property "CSSPseudoElementList" expected property "CSSPseudoElementList" missing
-FAIL CSSPseudoElementList interface: operation item(unsigned long) assert_own_property: self does not have own property "CSSPseudoElementList" expected property "CSSPseudoElementList" missing
-FAIL CSSPseudoElementList interface: operation getByType(CSSOMString) assert_own_property: self does not have own property "CSSPseudoElementList" expected property "CSSPseudoElementList" missing
-FAIL CSSPseudoElementList must be primary interface of beforeElements assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
-FAIL Stringification of beforeElements assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
-FAIL CSSPseudoElementList interface: beforeElements must inherit property "length" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
-FAIL CSSPseudoElementList interface: beforeElements must inherit property "item(unsigned long)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
-FAIL CSSPseudoElementList interface: calling item(unsigned long) on beforeElements with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
-FAIL CSSPseudoElementList interface: beforeElements must inherit property "getByType(CSSOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
-FAIL CSSPseudoElementList interface: calling getByType(CSSOMString) on beforeElements with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
-FAIL Window interface: operation getPseudoElements(Element, CSSOMString) assert_own_property: global object missing non-static operation expected property "getPseudoElements" missing
-FAIL Window interface: window must inherit property "getPseudoElements(Element, CSSOMString)" with the proper type assert_own_property: expected property "getPseudoElements" missing
-FAIL Window interface: calling getPseudoElements(Element, CSSOMString) on window with too few arguments must throw TypeError assert_own_property: expected property "getPseudoElements" missing
+FAIL Element interface: operation pseudo(CSSOMString) assert_own_property: interface prototype object missing non-static operation expected property "pseudo" missing
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/interfaces-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-typed-om/interfaces-expected.txt
index caef6ac..24e1caa9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/interfaces-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/interfaces-expected.txt
@@ -3,7 +3,7 @@
 PASS idl_test setup
 PASS Partial interface Element: original interface defined
 PASS Partial interface CSSStyleRule: original interface defined
-PASS Partial interface ElementCSSInlineStyle: original interface defined
+PASS Partial interface mixin ElementCSSInlineStyle: original interface mixin defined
 PASS Partial namespace CSS: original namespace defined
 PASS CSSStyleValue interface: existence and properties of interface object
 PASS CSSStyleValue interface object length
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/custom-element-registry/per-global-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/custom-element-registry/per-global-expected.txt
index ec470d23..b6ce8a3 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/custom-element-registry/per-global-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/custom-element-registry/per-global-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 PASS Discarding the browsing context must not change window.customElements
 FAIL Navigating from the initial about:blank must not replace window.customElements assert_equals: expected object "[object CustomElementRegistry]" but got object "[object CustomElementRegistry]"
-FAIL document.open() must replace window.customElements assert_not_equals: got disallowed value object "[object CustomElementRegistry]"
+PASS document.open() must replace window.customElements
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt
deleted file mode 100644
index 35cb638..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS HTML parser must not instantiate custom elements inside template elements
-PASS HTML parser must not use the registry of the owner element's document inside an iframe
-PASS HTML parser must use the registry of the content document inside an iframe
-PASS HTML parser must not instantiate a custom element defined inside an frame in frame element's owner document
-PASS HTML parser must use the registry of window.document in a document created by DOMParser
-PASS HTML parser must use the registry of window.document in a document created by document.implementation.createXHTMLDocument()
-PASS HTML parser must use the registry of window.document in a document created by new Document
-PASS HTML parser must use the registry of window.document in a document created by XMLHttpRequest
-FAIL document.write() must not instantiate a custom element without a defined insertion point assert_false: expected false got true
-FAIL document.writeln() must not instantiate a custom element without a defined insertion point assert_false: expected false got true
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document.html b/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document.html
index 51e3e5dd..bb256da 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document.html
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document.html
@@ -125,29 +125,27 @@
 
 test_with_window(function (contentWindow, contentDocument) {
     const element = define_custom_element_in_window(contentWindow, 'my-custom-element', []);
-    // document-open-steps spec doesn't match most browsers; see https://github.com/whatwg/html/issues/1698.
-    // However, as explained in https://github.com/whatwg/html/issues/1698#issuecomment-298748641
-    // the custom element registry will be replaced after document-open-steps.
+    // document-open-steps spec doesn't do anything with the custom element
+    // registry, so it should just stick around.
     contentDocument.write('<my-custom-element></my-custom-element>');
 
     var instance = contentDocument.querySelector('my-custom-element');
 
     assert_true(instance instanceof contentWindow.HTMLElement);
-    assert_false(instance instanceof element.class);
+    assert_true(instance instanceof element.class);
 
 }, 'document.write() must not instantiate a custom element without a defined insertion point');
 
 test_with_window(function (contentWindow, contentDocument) {
     const element = define_custom_element_in_window(contentWindow, 'my-custom-element', []);
-    // document-open-steps spec doesn't match most browsers; see https://github.com/whatwg/html/issues/1698.
-    // However, as explained in https://github.com/whatwg/html/issues/1698#issuecomment-298748641
-    // the custom element registry will be replaced after document-open-steps.
+    // document-open-steps spec doesn't do anything with the custom element
+    // registry, so it should just stick around.
     contentDocument.writeln('<my-custom-element></my-custom-element>');
 
     var instance = contentDocument.querySelector('my-custom-element');
 
     assert_true(instance instanceof contentWindow.HTMLElement);
-    assert_false(instance instanceof element.class);
+    assert_true(instance instanceof element.class);
 
 }, 'document.writeln() must not instantiate a custom element without a defined insertion point');
 
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Document.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Document.html
index 721ad1f..1f05982a 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Document.html
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Document.html
@@ -130,11 +130,6 @@
 
 test_with_window(function (contentWindow, contentDocument) {
     contentWindow.document.open();
-    // document.open()'s spec doesn't match most browsers; see https://github.com/whatwg/html/issues/1698.
-    // However, as explained in https://github.com/whatwg/html/issues/1698#issuecomment-298748641
-    // the custom element registry will be replaced after document.open() call,
-    // So call customElements.define() after that in order to register defintion
-    // to correct custom elements registry.
     const element = define_custom_element_in_window(contentWindow, 'custom-element', []);
     contentWindow.document.write('<custom-element></custom-element>');
     assert_array_equals(element.takeLog().types(), ['constructed', 'connected']);
@@ -151,11 +146,6 @@
 
 test_with_window(function (contentWindow) {
     contentWindow.document.open();
-    // document.open()'s spec doesn't match most browsers; see https://github.com/whatwg/html/issues/1698.
-    // However, as explained in https://github.com/whatwg/html/issues/1698#issuecomment-298748641
-    // the custom element registry will be replaced after document.open() call,
-    // So call customElements.define() after that in order to register defintion
-    // to correct custom elements registry.
     const element = define_custom_element_in_window(contentWindow, 'custom-element', []);
     contentWindow.document.writeln('<custom-element></custom-element>');
     assert_array_equals(element.takeLog().types(), ['constructed', 'connected']);
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-on-disabled-elements.html b/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-on-disabled-elements.html
index 688524bd2..a295ce1 100644
--- a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-on-disabled-elements.html
+++ b/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-on-disabled-elements.html
@@ -1,5 +1,6 @@
 <!doctype html>
 <meta charset="utf8">
+<meta name="timeout" content="long">
 <title>Events must dispatch on disabled elements</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
@@ -99,29 +100,99 @@
 }, "Calling click() on disabled elements must not dispatch events.");
 
 promise_test(async () => {
+  // Style sheet that controls transition.
+  const style = document.createElement("style");
+  style.innerText = `
+    ${formElements.join(", ")} {
+      opacity: 0.1;
+      transition-property: opacity;
+      transition-duration: .1s;
+    }
+    .transition {
+      opacity: 1;
+    }
+  `;
+  document.head.appendChild(style);
+
+  // Triggers the transition in the element being tested.
+  const transitionTrigger = document.createElement("button");
+  transitionTrigger.innerText = "Trigger button";
+  document.body.appendChild(transitionTrigger);
+
+  // For each form element type, set up transition event handlers.
   for (const localName of formElements) {
     const elem = document.createElement(localName);
     elem.disabled = true;
     document.body.appendChild(elem);
+    const transitionPromises = [
+      "transitionrun",
+      "transitionstart",
+      "transitionend",
+    ].map(eventType => {
+      return new Promise(r => {
+        const handlerName = `on${eventType}`;
+        elem[handlerName] = ev => {
+          elem[handlerName] = null;
+          r();
+        };
+      });
+    });
 
+    // Trigger transitions specifically on this element
+    // it requires a trusted event.
+    transitionTrigger.onclick = () => {
+      elem.classList.toggle("transition");
+    };
+    await test_driver.click(transitionTrigger);
+
+    // All the events fire...
+    await Promise.all(transitionPromises);
+    elem.classList.remove("transition");
+
+    // Let's now test the "transitioncancel" event.
+    elem.ontransitionstart = () => {
+      // Cancel the transition by hiding it.
+      elem.style.display = "none";
+      elem.classList.remove("transition");
+    };
+
+    // Trigger the transition again!
+    const promiseToCancel = new Promise(r => {
+      elem.ontransitioncancel = r;
+    });
+    await test_driver.click(transitionTrigger);
+    await promiseToCancel;
+    // And we are done with this element.
+    elem.remove();
+  }
+  // And we are done with the test... clean up.
+  transitionTrigger.remove();
+  style.remove();
+}, "CSS Transitions events fire on disabled form elements");
+
+promise_test(async () => {
+  for (const localName of formElements) {
+    const elem = document.createElement(localName);
+    elem.disabled = true;
+    document.body.appendChild(elem);
     // Element is disabled, so clicking must not fire events
     let pass = true;
     elem.onclick = e => {
       pass = false;
     };
-    await test_driver.click(elem); // triggers "onclick"
+    // Disabled elements are not clickable.
+    await test_driver.click(elem);
     assert_true(
       pass,
       `${elem.constructor.name} is disabled, so onclick must not fire.`
     );
-
     // Element is (re)enabled... so this click() will fire an event.
     pass = false;
     elem.disabled = false;
     elem.onclick = () => {
       pass = true;
     };
-    await test_driver.click(elem); // triggers "onclick"
+    await test_driver.click(elem);
     assert_true(
       pass,
       `${elem.constructor.name} is enabled, so onclick must fire.`
diff --git a/third_party/blink/web_tests/external/wpt/domparsing/interfaces.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/domparsing/interfaces.any.worker-expected.txt
index ac6137d..80a5103 100644
--- a/third_party/blink/web_tests/external/wpt/domparsing/interfaces.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/domparsing/interfaces.any.worker-expected.txt
@@ -11,10 +11,12 @@
 FAIL Stringification of new XMLSerializer() assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: XMLSerializer is not defined"
 FAIL XMLSerializer interface: new XMLSerializer() must not have property "serializeToString" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: XMLSerializer is not defined"
 PASS Node interface: existence and properties of interface object
+PASS DocumentFragment interface: existence and properties of interface object
+PASS ShadowRoot interface: existence and properties of interface object
 PASS Element interface: existence and properties of interface object
-FAIL Element interface: document.createElement("div") must not have property "innerHTML" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: document is not defined"
 FAIL Element interface: document.createElement("div") must not have property "outerHTML" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: document is not defined"
 FAIL Element interface: document.createElement("div") must not have property "insertAdjacentHTML" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: document is not defined"
+FAIL Element interface: document.createElement("div") must not have property "innerHTML" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: document is not defined"
 PASS AbstractRange interface: existence and properties of interface object
 PASS Range interface: existence and properties of interface object
 FAIL Range interface: new Range() must not have property "createContextualFragment" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Range is not defined"
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/document-write.tentative.html b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/document-write.tentative.html
index f0148783..7e09ef7e7 100644
--- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/document-write.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/document-write.tentative.html
@@ -9,10 +9,16 @@
   width: 100%;
 }
 </style>
-<iframe></iframe>
+<body>
 <script>
   "use strict";
 
+  function newIframe() {
+    var i = document.createElement("iframe");
+    document.body.appendChild(i);
+    return i;
+  }
+
   let iframeElement = document.querySelector("iframe");
   let url = url_base + "document-write.html";
 
@@ -42,6 +48,7 @@
   // is enabled, all dynamic markup insertion API work as intended.
   test_cases.forEach((tc) => {
     promise_test(async() => {
+      let iframeElement = newIframe();
       await loadUrlInIframe(iframeElement, url);
       await sendMessageAndGetResponse(iframeElement.contentWindow, tc).then((response) => {
         assert_false(
@@ -62,6 +69,7 @@
   // Disabling 'document-write' throws exception on the included API.
   test_cases.forEach((tc) => {
     promise_test(async() => {
+      let iframeElement = newIframe();
       setFeatureState(iframeElement, "document-write", "'none'");
       await loadUrlInIframe(iframeElement, url);
       await sendMessageAndGetResponse(iframeElement.contentWindow, tc).then((response) => {
@@ -80,3 +88,4 @@
   });
 
 </script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1-1.html b/third_party/blink/web_tests/external/wpt/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1-1.html
index af0118a0..945c8d8 100644
--- a/third_party/blink/web_tests/external/wpt/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1-1.html
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1-1.html
@@ -5,11 +5,8 @@
   opener.pages.push(2);
   onload = function() {
     setTimeout(function() {
-      document.write("<!doctype html>3<script>opener.pages.push(3); if(!opener.started) {opener.started = true; history.go(-1);} opener.start_test_wait();<\/script>");
+      document.write("<!doctype html>3<script>opener.pages.push(3); if(!opener.started) {opener.started = true; history.go(-1);}<\/script>");
       document.close();
-      if (opener.started) {
-        opener.start_test_wait();
-      }
     }, 100);
   }
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write-1.html b/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write-1.html
index 1c5a1db..e1a2e81 100644
--- a/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write-1.html
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write-1.html
@@ -3,11 +3,16 @@
 <script>
 function f() {
   opener.postMessage("original", "*");
+  if (opener.data.length >= 2) {
+    // If we proceed here, then our document.write will be racing with the
+    // setTimeout in our opener.  Just stop.
+    return;
+  }
   setTimeout(function () {
     document.open();
     document.write("<!doctype html>2<script>opener.postMessage('written', '*');<\/script>");
     document.close();
-  }), 100;
+  });
 }
 
 window.onload = f
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write-expected.txt b/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write-expected.txt
deleted file mode 100644
index 5dd39b7..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Reload document with document.open and document.written content assert_array_equals: lengths differ, expected 3 got 4
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write.html b/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write.html
index 0fc2a2c3..905ef8874 100644
--- a/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write.html
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/history/the-location-interface/reload_document_open_write.html
@@ -11,11 +11,11 @@
 
 window.onmessage = t.step_func(function(e) {
   data.push(e.data);
-  if (data.length < 3) {
+  if (data.length == 2) {
     win.location.reload();
-  } else {
+  } else if (data.length >= 3) {
     setTimeout(t.step_func(function() {
-      assert_array_equals(data, ["original", "written", "written"]);
+      assert_array_equals(data, ["original", "written", "original"]);
       t.done();
     }), 500);
   }
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/BarProp.window.js b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/BarProp.window.js
new file mode 100644
index 0000000..27a357c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/BarProp.window.js
@@ -0,0 +1,59 @@
+function assert_barProps(barPropObjects, visible) {
+  let lastBarProp = undefined;
+  for (const currentBarProp of barPropObjects) {
+    assert_not_equals(currentBarProp, lastBarProp, "BarBrop objects of different properties are identical");
+    assert_equals(currentBarProp.visible, visible, "a BarProp's visible is wrong");
+    lastBarProp = currentBarProp;
+  }
+}
+
+function assert_identical_barProps(barProps, w, oldBarPropObjects, visible) {
+  barProps.map(val => w[val]).map((val, index) => {
+    assert_equals(val, oldBarPropObjects[index], "BarProp identity not preserved");
+  });
+  assert_barProps(oldBarPropObjects, visible);
+}
+
+async_test(t => {
+  const frame = document.body.appendChild(document.createElement("iframe")),
+        frameW = frame.contentWindow,
+        barProps = ["locationbar", "menubar", "personalbar", "scrollbars", "statusbar", "toolbar"],
+        barPropObjects = barProps.map(val => frameW[val]);
+
+  assert_barProps(barPropObjects, true);
+  frame.remove();
+  assert_identical_barProps(barProps, frameW, barPropObjects, false);
+  t.step_timeout(() => {
+    assert_identical_barProps(barProps, frameW, barPropObjects, false);
+    t.done();
+  }, 0);
+}, "BarBrop objects of a nested Window");
+
+async_test(t => {
+  const openee = window.open("/common/blank.html"),
+        barProps = ["locationbar", "menubar", "personalbar", "scrollbars", "statusbar", "toolbar"],
+        barPropObjects = barProps.map(val => openee[val]);
+
+  // This is used to demonstrate that the Document is replaced while the global object (not the
+  // global this object) stays the same
+  openee.tiedToGlobalObject = openee.document;
+
+  assert_barProps(barPropObjects, true);
+  openee.onload = t.step_func(() => {
+    assert_own_property(openee, "tiedToGlobalObject");
+    assert_not_equals(openee.tiedToGlobalObject, openee.document);
+
+    assert_identical_barProps(barProps, openee, barPropObjects, true);
+
+    openee.onunload = t.step_func(() => {
+      assert_identical_barProps(barProps, openee, barPropObjects, true);
+      t.step_timeout(() => {
+        assert_identical_barProps(barProps, openee, barPropObjects, false);
+        t.done();
+      }, 0);
+    });
+
+    openee.close();
+    assert_identical_barProps(barProps, openee, barPropObjects, true);
+  });
+}, "BarProp objects of an auxiliary Window");
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-locationbar-manual.html b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-locationbar-manual.html
deleted file mode 100644
index 4331b3b..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-locationbar-manual.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="utf-8">
-    <title>Window Proxy locationbar visible flag Test</title>
-    <link rel="author" title='JuneyoungOh' href="juneyoung85@gmail.com">
-    <script src="/resources/testharness.js"></script>
-    <script src="/resources/testharnessreport.js"></script>
-</head>
-<body>
-    <h1>Description</h1>
-    <p>WindowProxy.locationbar Test</p>
-
-    <h1>Manual Test Steps:</h1>
-    <ol>
-        <li>Make the locationbar visible in the user agent before executing this test.</li>
-        <li>You may need to manually reload afterwards.</li>
-    </ol>
-
-    <div id="log"></div>
-
-    <script>
-    test(function() {
-        assert_not_equals(typeof window.locationbar, undefined, 'window.locationbar is undefined');
-        assert_true(window.locationbar.visible)
-    }, "window.locationbar.visible");
-    </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-menubar-manual.html b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-menubar-manual.html
deleted file mode 100644
index 4334593..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-menubar-manual.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="utf-8">
-    <title>Window Proxy menubar visible flag Test</title>
-    <link rel="author" title='JuneyoungOh' href="juneyoung85@gmail.com">
-    <script src="/resources/testharness.js"></script>
-    <script src="/resources/testharnessreport.js"></script>
-</head>
-<body>
-    <h1>Description</h1>
-    <p>WindowProxy.menubar Test</p>
-
-    <h1>Manual Test Steps:</h1>
-    <ol>
-        <li>Make the menubar visible in the user agent before executing this test.</li>
-        <li>You may need to manually reload afterwards.</li>
-    </ol>
-
-    <div id="log"></div>
-
-    <script>
-    test(function() {
-        assert_not_equals(typeof window.menubar, undefined, 'window.menubar is undefined');
-        assert_true(window.menubar.visible);
-    }, "window.menubar.visible");
-    </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-personalbar-manual.html b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-personalbar-manual.html
deleted file mode 100644
index d7f10984..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-personalbar-manual.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
-    <meta charset="utf-8" />
-    <title>Window Proxy personalbar visible flag Test</title>
-    <link rel="author" title="vanessa" href="mailto:vanessaohsy@gmail.com">
-    <script type="text/javascript" src="/resources/testharness.js"></script>
-    <script type="text/javascript" src="/resources/testharnessreport.js"></script>
-</head>
-<body>
-    <h1>Description</h1>
-    <p>WindowProxy.personalbar Test</p>
-
-    <h1>Manual Test Steps:</h1>
-    <ol>
-        <li>Make the personalbar visible in the user agent before executing this test.</li>
-        <li>You may need to manually reload afterwards.</li>
-    </ol>
-
-    <div id="log"></div>
-
-    <script type="text/javascript" >
-    test(function () {
-        assert_not_equals(window.personalbar, undefined, "window.personalbar is undefined");
-        assert_true(window.personalbar.visible, "window.personalbar.visible");
-    });
-    </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-scrollbars-manual.html b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-scrollbars-manual.html
deleted file mode 100644
index c412bdb..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-scrollbars-manual.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
-    <meta charset="utf-8" />
-    <title>Window Proxy scrollbars visible flag Test</title>
-    <link rel="author" title="vanessa" href="vanessaohsy@gmail.com">
-    <script type="text/javascript" src="/resources/testharness.js"></script>
-    <script type="text/javascript" src="/resources/testharnessreport.js"></script>
-</head>
-<body>
-    <h1>Description</h1>
-    <p>WindowProxy.scrollbars Test</p>
-
-    <h1>Manual Test Steps:</h1>
-    <ol>
-        <li>Make the scrollbars visible in the user agent before executing this test.</li>
-        <li>You may need to manually reload afterwards.</li>
-    </ol>
-
-    <div id="log"></div>
-
-    <script type="text/javascript" >
-    test(function () {
-        assert_not_equals(window.scrollbars, undefined, "window.scrollbars is undefined");
-        assert_true(window.scrollbars.visible, "window.scrollbars.visible");
-    });
-    </script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-statusbar-manual.html b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-statusbar-manual.html
deleted file mode 100644
index b09fcc0..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-statusbar-manual.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!doctype html>
-<html>
-<head>
-    <meta charset="utf-8" />
-    <title>WindowProxy statusbar visible flag Test</title>
-    <link rel="author" title="dokenzy" href="dokenzy@gmail.com">
-    <script type="text/javascript" src="/resources/testharness.js"></script>
-    <script type="text/javascript" src="/resources/testharnessreport.js"></script>
-</head>
-<body>
-    <h1>Description</h1>
-    <p>WindowProxy.statusbar Test</p>
-
-    <h1>Manual Test Steps:</h1>
-    <ol>
-        <li>Make the statusbar visible in the user agent before executing this test.</li>
-        <li>You may need to manually reload afterwards.</li>
-    </ol>
-
-    <div id="log"></div>
-
-    <script type="text/javascript" >
-    test(function () {
-        assert_not_equals(typeof window.statusbar.visible, undefined, 'window.statusbar.visible');
-        assert_true(window.statusbar.visible, 'window.statusbar.visible');
-    }, "BarProp attribute: window.statusbar.visible");
-    </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-toolbar-manual.html b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-toolbar-manual.html
deleted file mode 100644
index ba46544..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-toolbar-manual.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!doctype html>
-<html>
-<head>
-    <meta charset="utf-8" />
-    <title>WindowProxy toolbar visible flag Test</title>
-    <link rel="author" title="dokenzy" href="dokenzy@gmail.com">
-    <script type="text/javascript" src="/resources/testharness.js"></script>
-    <script type="text/javascript" src="/resources/testharnessreport.js"></script>
-</head>
-<body>
-    <h1>Description</h1>
-    <p>WindowProxy.toolbar Test</p>
-
-    <h1>Manual Test Steps:</h1>
-    <ol>
-        <li>Make the toolbar visible in the user agent before executing this test.</li>
-        <li>You may need to manually reload afterwards.</li>
-    </ol>
-
-    <div id="log"></div>
-
-    <script type="text/javascript" >
-    test(function () {
-        assert_not_equals(typeof window.toolbar.visible, undefined, 'window.toolbar.visible');
-        assert_true(window.toolbar.visible, 'window.toolbar.visible');
-    }, "BarProp attribute: window.toolbar.visible");
-    </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3-ref.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3-ref.html
new file mode 100644
index 0000000..e465fd43
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3-ref.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<head>
+  <title>Reference for default 'border-color' on table (with 'color' set)</title>
+  <meta charset="utf-8">
+  <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+  <style>
+    * {
+      border-color: teal;
+      /* This only affects the elements that we specify 'border-style' on: */
+      border-width: 6px;
+    }
+
+    table {
+      height: 30px;
+      width: 30px;
+      border-spacing: 0;
+
+      /* To test in "rows": */
+      float: left;
+      margin: 1px;
+    }
+    br {
+      clear: both;
+    }
+
+    .dotted {
+      border-style: dotted;
+    }
+    .dashed {
+      border-style: dashed;
+    }
+    .solid {
+      border-style: solid;
+    }
+    .double {
+      border-style: double;
+    }
+    .groove {
+      border-style: groove;
+    }
+    .ridge {
+      border-style: ridge;
+    }
+    .inset {
+      border-style: inset;
+    }
+    .outset {
+      border-style: outset;
+    }
+  </style>
+</head>
+
+<table class="dotted"><td></td></table>
+<table><th class="dotted"></th></table>
+<table><td class="dotted"></td></table>
+<br>
+
+<table class="dashed"><td></td></table>
+<table><th class="dashed"></th></table>
+<table><td class="dashed"></td></table>
+<br>
+
+<table class="solid"><td></td></table>
+<table><th class="solid"></th></table>
+<table><td class="solid"></td></table>
+<br>
+
+<table class="double"><td></td></table>
+<table><th class="double"></th></table>
+<table><td class="double"></td></table>
+<br>
+
+<table class="groove"><td></td></table>
+<table><th class="groove"></th></table>
+<table><td class="groove"></td></table>
+<br>
+
+<table class="ridge"><td></td></table>
+<table><th class="ridge"></th></table>
+<table><td class="ridge"></td></table>
+<br>
+
+<table class="inset"><td></td></table>
+<table><th class="inset"></th></table>
+<table><td class="inset"></td></table>
+<br>
+
+<table class="outset"><td></td></table>
+<table><th class="outset"></th></table>
+<table><td class="outset"></td></table>
+<br>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3q.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3q.html
new file mode 100644
index 0000000..4b481194
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3q.html
@@ -0,0 +1,95 @@
+<!-- Intentionally omitting doctype, to test quirks mode. -->
+<head>
+  <title>Testing default 'border-color' on table (with 'color' set), in quirks mode</title>
+  <meta charset="utf-8">
+  <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+  <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+  <link rel="match" href="table-border-3-ref.html">
+  <style>
+    * {
+      /* This sets the used value of 'currentColor', which is what should be
+         used for all border-coloring in this test: */
+      color: teal;
+      /* This only affects the elements that we specify 'border-style' on: */
+      border-width: 6px;
+    }
+
+    table {
+      height: 30px;
+      width: 30px;
+      border-spacing: 0;
+
+      /* To test in "rows": */
+      float: left;
+      margin: 1px;
+    }
+    br {
+      clear: both;
+    }
+
+    .dotted {
+      border-style: dotted;
+    }
+    .dashed {
+      border-style: dashed;
+    }
+    .solid {
+      border-style: solid;
+    }
+    .double {
+      border-style: double;
+    }
+    .groove {
+      border-style: groove;
+    }
+    .ridge {
+      border-style: ridge;
+    }
+    .inset {
+      border-style: inset;
+    }
+    .outset {
+      border-style: outset;
+    }
+  </style>
+</head>
+
+<table class="dotted"><td></td></table>
+<table><th class="dotted"></th></table>
+<table><td class="dotted"></td></table>
+<br>
+
+<table class="dashed"><td></td></table>
+<table><th class="dashed"></th></table>
+<table><td class="dashed"></td></table>
+<br>
+
+<table class="solid"><td></td></table>
+<table><th class="solid"></th></table>
+<table><td class="solid"></td></table>
+<br>
+
+<table class="double"><td></td></table>
+<table><th class="double"></th></table>
+<table><td class="double"></td></table>
+<br>
+
+<table class="groove"><td></td></table>
+<table><th class="groove"></th></table>
+<table><td class="groove"></td></table>
+<br>
+
+<table class="ridge"><td></td></table>
+<table><th class="ridge"></th></table>
+<table><td class="ridge"></td></table>
+<br>
+
+<table class="inset"><td></td></table>
+<table><th class="inset"></th></table>
+<table><td class="inset"></td></table>
+<br>
+
+<table class="outset"><td></td></table>
+<table><th class="outset"></th></table>
+<table><td class="outset"></td></table>
+<br>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html
new file mode 100644
index 0000000..c4c019c8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<head>
+  <title>Testing default 'border-color' on table (with 'color' set), in standards mode</title>
+  <meta charset="utf-8">
+  <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+  <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+  <link rel="match" href="table-border-3-ref.html">
+  <style>
+    * {
+      /* This sets the used value of 'currentColor', which is what should be
+         used for all border-coloring in this test: */
+      color: teal;
+      /* This only affects the elements that we specify 'border-style' on: */
+      border-width: 6px;
+    }
+
+    table {
+      height: 30px;
+      width: 30px;
+      border-spacing: 0;
+
+      /* To test in "rows": */
+      float: left;
+      margin: 1px;
+    }
+    br {
+      clear: both;
+    }
+
+    .dotted {
+      border-style: dotted;
+    }
+    .dashed {
+      border-style: dashed;
+    }
+    .solid {
+      border-style: solid;
+    }
+    .double {
+      border-style: double;
+    }
+    .groove {
+      border-style: groove;
+    }
+    .ridge {
+      border-style: ridge;
+    }
+    .inset {
+      border-style: inset;
+    }
+    .outset {
+      border-style: outset;
+    }
+  </style>
+</head>
+
+<table class="dotted"><td></td></table>
+<table><th class="dotted"></th></table>
+<table><td class="dotted"></td></table>
+<br>
+
+<table class="dashed"><td></td></table>
+<table><th class="dashed"></th></table>
+<table><td class="dashed"></td></table>
+<br>
+
+<table class="solid"><td></td></table>
+<table><th class="solid"></th></table>
+<table><td class="solid"></td></table>
+<br>
+
+<table class="double"><td></td></table>
+<table><th class="double"></th></table>
+<table><td class="double"></td></table>
+<br>
+
+<table class="groove"><td></td></table>
+<table><th class="groove"></th></table>
+<table><td class="groove"></td></table>
+<br>
+
+<table class="ridge"><td></td></table>
+<table><th class="ridge"></th></table>
+<table><td class="ridge"></td></table>
+<br>
+
+<table class="inset"><td></td></table>
+<table><th class="inset"></th></table>
+<table><td class="inset"></td></table>
+<br>
+
+<table class="outset"><td></td></table>
+<table><th class="outset"></th></table>
+<table><td class="outset"></td></table>
+<br>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html
index a9cd73435..7a17dee2a 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html
@@ -12,7 +12,7 @@
     track.mode = 'showing';
     assert_equals(video.textTracks.length, 1);
 
-    video.textTracks.onchange = t.step_func_done(function() {
+    video.textTracks.onchange = t.step_func_done(function(event) {
         assert_equals(event.target, video.textTracks);
         assert_true(event instanceof Event, 'instanceof');
         assert_false(event.hasOwnProperty('track'), 'unexpected property found: "track"');
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/load-event-after-location-set-during-write.window.js b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/load-event-after-location-set-during-write.window.js
new file mode 100644
index 0000000..d5c8469b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/load-event-after-location-set-during-write.window.js
@@ -0,0 +1,19 @@
+// Make sure that the load event for an iframe doesn't fire at the
+// point when a navigation triggered by document.write() starts in it,
+// but rather when that navigation completes.
+
+async_test(t => {
+  const frame = document.body.appendChild(document.createElement("iframe"));
+  const doc = frame.contentDocument;
+  const url = URL.createObjectURL(new Blob(["PASS"], { type: "text/html"}));
+
+  frame.onload = t.step_func_done(() => {
+    assert_equals(frame.contentDocument.body.textContent, "PASS",
+                  "Why is our load event firing before the new document loaded?");
+  });
+
+  doc.open();
+  doc.write(`FAIL<script>location = "${url}"</` + "script>");
+  doc.close();
+}, "Setting location from document.write() call should not trigger load event until that load completes");
+
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/http-refresh.py b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/http-refresh.py
index d2acd43..d323f967 100644
--- a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/http-refresh.py
+++ b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/http-refresh.py
@@ -1,3 +1,3 @@
 def main(request, response):
     time = request.url_parts.query if request.url_parts.query else '0'
-    return 200, [['Refresh', time]], ''
+    return 200, [('Refresh', time), ('Content-Type', "text/html")], ''
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/DOM-Parsing.idl b/third_party/blink/web_tests/external/wpt/interfaces/DOM-Parsing.idl
index f3a13342..c5de42b 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/DOM-Parsing.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/DOM-Parsing.idl
@@ -18,12 +18,18 @@
 
 [Constructor, Exposed=Window]
 
-  interface XMLSerializer {
+interface XMLSerializer {
   DOMString serializeToString(Node root);
 };
 
-partial interface Element {
+interface mixin InnerHTML {
   [CEReactions, TreatNullAs=EmptyString] attribute DOMString innerHTML;
+};
+
+Element includes InnerHTML;
+ShadowRoot includes InnerHTML;
+
+partial interface Element {
   [CEReactions, TreatNullAs=EmptyString] attribute DOMString outerHTML;
   [CEReactions] void insertAdjacentHTML(DOMString position, DOMString text);
 };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/FileAPI.idl b/third_party/blink/web_tests/external/wpt/interfaces/FileAPI.idl
index 1fd6bac..15b2e55 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/FileAPI.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/FileAPI.idl
@@ -12,8 +12,8 @@
   readonly attribute DOMString type;
 
   // slice Blob into byte-ranged chunks
-  Blob slice([Clamp] optional long long start,
-            [Clamp] optional long long end,
+  Blob slice(optional [Clamp] long long start,
+            optional [Clamp] long long end,
             optional DOMString contentType);
 };
 
@@ -75,7 +75,6 @@
   attribute EventHandler onabort;
   attribute EventHandler onerror;
   attribute EventHandler onloadend;
-
 };
 
 [Constructor, Exposed=(DedicatedWorker,SharedWorker)]
@@ -90,6 +89,6 @@
 
 [Exposed=(Window,DedicatedWorker,SharedWorker)]
 partial interface URL {
-  static DOMString createObjectURL(Blob blob);
+  static DOMString createObjectURL((Blob or MediaSource) obj);
   static void revokeObjectURL(DOMString url);
 };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/IndexedDB.idl b/third_party/blink/web_tests/external/wpt/interfaces/IndexedDB.idl
index 868338b3..21ff252f 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/IndexedDB.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/IndexedDB.idl
@@ -171,6 +171,7 @@
   readonly attribute IDBCursorDirection direction;
   readonly attribute any key;
   readonly attribute any primaryKey;
+  readonly attribute IDBRequest request;
 
   void advance([EnforceRange] unsigned long count);
   void continue(optional any key);
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/clipboard-apis.idl b/third_party/blink/web_tests/external/wpt/interfaces/clipboard-apis.idl
index e48ca6a..99d1155 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/clipboard-apis.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/clipboard-apis.idl
@@ -16,13 +16,42 @@
   [SecureContext, SameObject] readonly attribute Clipboard clipboard;
 };
 
+typedef sequence<ClipboardItem> ClipboardItems;
+
 [SecureContext, Exposed=Window] interface Clipboard : EventTarget {
-  Promise<DataTransfer> read();
+  Promise<ClipboardItems> read();
   Promise<DOMString> readText();
-  Promise<void> write(DataTransfer data);
+  Promise<void> write(ClipboardItems data);
   Promise<void> writeText(DOMString data);
 };
 
+typedef (DOMString or Blob) ClipboardItemDataType;
+typedef Promise<ClipboardItemDataType> ClipboardItemData;
+
+callback ClipboardItemDelayedCallback = ClipboardItemData ();
+
+[Constructor(record<DOMString, ClipboardItemData> items,
+    optional ClipboardItemOptions options),
+ Exposed=Window] interface ClipboardItem {
+  static ClipboardItem createDelayed(
+      record<DOMString, ClipboardItemDelayedCallback> items,
+      optional ClipboardItemOptions options);
+
+  readonly attribute PresentationStyle presentationStyle;
+  readonly attribute long long lastModified;
+  readonly attribute boolean delayed;
+
+  readonly attribute FrozenArray<DOMString> types;
+
+  Promise<Blob> getType(DOMString type);
+};
+
+enum PresentationStyle { "unspecified", "inline", "attachment" };
+
+dictionary ClipboardItemOptions {
+  PresentationStyle presentationStyle = "unspecified";
+};
+
 dictionary ClipboardPermissionDescriptor : PermissionDescriptor {
   boolean allowWithoutGesture = false;
 };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-layout-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-layout-api.idl
index 9440684..31ab6eb4 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/css-layout-api.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/css-layout-api.idl
@@ -134,7 +134,7 @@
     BreakTokenOptions breakToken = null;
 };
 
-[Constructor(FragmentResultOptions)]
+[Constructor(optional FragmentResultOptions options)]
 interface FragmentResult {
     readonly attribute double inlineSize;
     readonly attribute double blockSize;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-pseudo.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-pseudo.idl
index c51f221..2b557e65 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/css-pseudo.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/css-pseudo.idl
@@ -4,24 +4,11 @@
 // Source: CSS Pseudo-Elements Module Level 4 (https://drafts.csswg.org/css-pseudo-4/)
 
 [Exposed=Window]
-interface CSSPseudoElement {
+interface CSSPseudoElement : EventTarget {
     readonly attribute CSSOMString type;
     readonly attribute Element element;
-    readonly attribute CSSStyleDeclaration style;
 };
 
-CSSPseudoElement implements EventTarget;
-
-[Exposed=Window]
-interface CSSPseudoElementList {
-    readonly attribute unsigned long length;
-    CSSPseudoElement item(unsigned long index);
-    CSSPseudoElement getByType(CSSOMString type);
-                     // replies null if no pseudo-element exists for
-                     //     the requested type
-};
-
-partial interface Window {
-  CSSPseudoElementList getPseudoElements(Element elt,
-                                       CSSOMString type);
+partial interface Element {
+  CSSPseudoElement? pseudo(CSSOMString type);
 };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-regions.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-regions.idl
index 1e23960..f7cf3d3 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/css-regions.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/css-regions.idl
@@ -25,11 +25,9 @@
   sequence<Region> getRegionsByContent(Node node);
 };
 
-[Exposed=Window,
- NoInterfaceObject]
-interface Region {
+interface mixin Region {
   readonly attribute CSSOMString regionOverset;
   sequence<Range>? getRegionFlowRanges();
 };
 
-Element implements Region;
+Element includes Region;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-typed-om.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-typed-om.idl
index 02fe7bb..be2946bc 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/css-typed-om.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/css-typed-om.idl
@@ -37,7 +37,7 @@
     [SameObject] readonly attribute StylePropertyMap styleMap;
 };
 
-partial interface ElementCSSInlineStyle {
+partial interface mixin ElementCSSInlineStyle {
     [SameObject] readonly attribute StylePropertyMap attributeStyleMap;
 };
 
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/feature-policy.idl b/third_party/blink/web_tests/external/wpt/interfaces/feature-policy.idl
index 2a04215..3ded1e9b 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/feature-policy.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/feature-policy.idl
@@ -1,7 +1,7 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into reffy-reports
 // (https://github.com/tidoust/reffy-reports)
-// Source: Feature Policy (https://wicg.github.io/feature-policy/)
+// Source: Feature Policy (https://w3c.github.io/webappsec-feature-policy/)
 
 [NoInterfaceObject]
 interface FeaturePolicy {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/generic-sensor.idl b/third_party/blink/web_tests/external/wpt/interfaces/generic-sensor.idl
index 2e7aacbec..2921c50 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/generic-sensor.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/generic-sensor.idl
@@ -3,7 +3,7 @@
 // (https://github.com/tidoust/reffy-reports)
 // Source: Generic Sensor API (https://w3c.github.io/sensors/)
 
-[SecureContext, Exposed=Window]
+[SecureContext, Exposed=(DedicatedWorker, Window)]
 interface Sensor : EventTarget {
   readonly attribute boolean activated;
   readonly attribute boolean hasReading;
@@ -20,7 +20,7 @@
 };
 
 [Constructor(DOMString type, SensorErrorEventInit errorEventInitDict),
- SecureContext, Exposed=Window]
+ SecureContext, Exposed=(DedicatedWorker, Window)]
 interface SensorErrorEvent : Event {
   readonly attribute DOMException error;
 };
@@ -58,63 +58,3 @@
 
 dictionary MockSensorReadingValues {
 };
-
-dictionary AmbientLightReadingValues {
-  required double? illuminance;
-};
-
-dictionary AccelerometerReadingValues {
-  required double? x;
-  required double? y;
-  required double? z;
-};
-
-dictionary LinearAccelerationReadingValues : AccelerometerReadingValues {
-};
-
-dictionary GravityReadingValues : AccelerometerReadingValues {
-};
-
-dictionary GyroscopeReadingValues {
-  required double? x;
-  required double? y;
-  required double? z;
-};
-
-dictionary MagnetometerReadingValues {
-  required double? x;
-  required double? y;
-  required double? z;
-};
-
-dictionary UncalibratedMagnetometerReadingValues {
-  required double? x;
-  required double? y;
-  required double? z;
-  required double? xBias;
-  required double? yBias;
-  required double? zBias;
-};
-
-dictionary AbsoluteOrientationReadingValues {
-  required FrozenArray<double>? quaternion;
-};
-
-dictionary RelativeOrientationReadingValues : AbsoluteOrientationReadingValues {
-};
-
-dictionary GeolocationReadingValues {
-  required double? latitude;
-  required double? longitude;
-  required double? altitude;
-  required double? accuracy;
-  required double? altitudeAccuracy;
-  required double? heading;
-  required double? speed;
-};
-
-dictionary ProximityReadingValues {
-  required double? distance;
-  required double? max;
-  required boolean? near;
-};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/geolocation-sensor.idl b/third_party/blink/web_tests/external/wpt/interfaces/geolocation-sensor.idl
index 41c310a..074d7bb9 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/geolocation-sensor.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/geolocation-sensor.idl
@@ -3,7 +3,9 @@
 // (https://github.com/tidoust/reffy-reports)
 // Source: Geolocation Sensor (https://wicg.github.io/geolocation-sensor/)
 
-[Constructor(optional GeolocationSensorOptions options), SecureContext, Exposed=Window]
+[Constructor(optional GeolocationSensorOptions options),
+ SecureContext,
+ Exposed=(DedicatedWorker, Window)]
 interface GeolocationSensor : Sensor {
   static Promise<GeolocationSensorReading> read(optional ReadOptions readOptions);
   readonly attribute unrestricted double? latitude;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/keyboard-lock.idl b/third_party/blink/web_tests/external/wpt/interfaces/keyboard-lock.idl
index 90812ae8..5990976c 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/keyboard-lock.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/keyboard-lock.idl
@@ -1,7 +1,7 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into reffy-reports
 // (https://github.com/tidoust/reffy-reports)
-// Source: Keyboard Lock (https://w3c.github.io/keyboard-lock/)
+// Source: Keyboard Lock (https://wicg.github.io/keyboard-lock/)
 
 partial interface Navigator {
   [SecureContext, SameObject] readonly attribute Keyboard keyboard;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-depth.idl b/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-depth.idl
index 63e839c..907940a 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-depth.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-depth.idl
@@ -4,76 +4,23 @@
 // Source: Media Capture Depth Stream Extensions (https://w3c.github.io/mediacapture-depth/)
 
 partial dictionary MediaTrackSupportedConstraints {
-    // Apply to both depth stream track and color stream track:
+    // Applies to both depth stream track and color stream track:
     boolean videoKind = true;
-    boolean focalLengthX = false;
-    boolean focalLengthY = false;
-    boolean principalPointX = false;
-    boolean principalPointY = false;
-    boolean deprojectionDistortionCoefficients = false;
-    boolean projectionDistortionCoefficients = false;
-    // Apply to depth stream track:
-    boolean depthNear = false;
-    boolean depthFar = false;
-    boolean depthToVideoTransform = false;
 };
 
 partial dictionary MediaTrackCapabilities {
-    // Apply to both depth stream track and color stream track:
+    // Applies to both depth stream track and color stream track:
     DOMString videoKind;
-    (double or DoubleRange) focalLengthX;
-    (double or DoubleRange) focalLengthY;
-    (double or DoubleRange) principalPointX;
-    (double or DoubleRange) principalPointY;
-    boolean deprojectionDistortionCoefficients;
-    boolean projectionDistortionCoefficients;
-    // Apply to depth stream track:
-    (double or DoubleRange) depthNear;
-    (double or DoubleRange) depthFar;
-    boolean depthToVideoTransform;
 };
 
 partial dictionary MediaTrackConstraintSet {
-    // Apply to both depth stream track and color stream track:
+    // Applies to both depth stream track and color stream track:
     ConstrainDOMString videoKind;
-    ConstrainDouble focalLengthX;
-    ConstrainDouble focalLengthY;
-    ConstrainDouble principalPointX;
-    ConstrainDouble principalPointY;
-    ConstrainBoolean deprojectionDistortionCoefficients;
-    ConstrainBoolean projectionDistortionCoefficients;
-    // Apply to depth stream track:
-    ConstrainDouble depthNear;
-    ConstrainDouble depthFar;
-    ConstrainBoolean depthToVideoTransform;
 };
 
 partial dictionary MediaTrackSettings {
-    // Apply to both depth stream track and color stream track:
+    // Applies to both depth stream track and color stream track:
     DOMString videoKind;
-    double focalLengthX;
-    double focalLengthY;
-    double principalPointX;
-    double principalPointY;
-    DistortionCoefficients deprojectionDistortionCoefficients;
-    DistortionCoefficients projectionDistortionCoefficients;
-    // Apply to depth stream track:
-    double depthNear;
-    double depthFar;
-    Transformation depthToVideoTransform;
-};
-
-dictionary DistortionCoefficients {
-    double k1;
-    double k2;
-    double p1;
-    double p2;
-    double k3;
-};
-
-dictionary Transformation {
-  Float32Array transformationMatrix;
-  DOMString videoDeviceId;
 };
 
 enum VideoKindEnum {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-streams.idl b/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-streams.idl
index a66e4734..0feea37 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-streams.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-streams.idl
@@ -164,14 +164,13 @@
     readonly        attribute MediaDevices mediaDevices;
 };
 
-[Exposed=Window,
-SecureContext]
+[Exposed=Window, SecureContext]
 interface MediaDevices : EventTarget {
                     attribute EventHandler ondevicechange;
     Promise<sequence<MediaDeviceInfo>> enumerateDevices();
 };
 
-[Exposed=Window]
+[Exposed=Window, SecureContext]
 interface MediaDeviceInfo {
     readonly        attribute DOMString deviceId;
     readonly        attribute MediaDeviceKind kind;
@@ -211,15 +210,6 @@
 
 typedef object MediaStreamError;
 
-[NoInterfaceObject]
-interface ConstrainablePattern {
-    Capabilities getCapabilities();
-    Constraints getConstraints();
-    Settings getSettings();
-    Promise<void> applyConstraints(optional Constraints constraints);
-                    attribute EventHandler onoverconstrained;
-};
-
 dictionary DoubleRange {
              double max;
              double min;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/pointerevents.idl b/third_party/blink/web_tests/external/wpt/interfaces/pointerevents.idl
index da822bba0..fd368bf5 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/pointerevents.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/pointerevents.idl
@@ -36,7 +36,7 @@
   boolean hasPointerCapture(long pointerId);
 };
 
-partial interface GlobalEventHandlers {
+partial interface mixin GlobalEventHandlers {
     attribute EventHandler ongotpointercapture;
     attribute EventHandler onlostpointercapture;
     attribute EventHandler onpointerdown;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/ResizeObserver.idl b/third_party/blink/web_tests/external/wpt/interfaces/resize-observer.idl
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/interfaces/ResizeObserver.idl
rename to third_party/blink/web_tests/external/wpt/interfaces/resize-observer.idl
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/screen-orientation.idl b/third_party/blink/web_tests/external/wpt/interfaces/screen-orientation.idl
index 2304cc2..b548121 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/screen-orientation.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/screen-orientation.idl
@@ -16,18 +16,18 @@
   attribute EventHandler onchange;
 };
 
-enum OrientationType {
+enum OrientationLockType {
+  "any",
+  "natural",
+  "landscape",
+  "portrait",
   "portrait-primary",
   "portrait-secondary",
   "landscape-primary",
   "landscape-secondary"
 };
 
-enum OrientationLockType {
-  "any",
-  "natural",
-  "landscape",
-  "portrait",
+enum OrientationType {
   "portrait-primary",
   "portrait-secondary",
   "landscape-primary",
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/service-workers.idl b/third_party/blink/web_tests/external/wpt/interfaces/service-workers.idl
index fb2e033..99f55ab 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/service-workers.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/service-workers.idl
@@ -1,13 +1,14 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into reffy-reports
 // (https://github.com/tidoust/reffy-reports)
-// Source: Service Workers 1 (https://w3c.github.io/ServiceWorker/v1/)
+// Source: Service Workers Nightly (https://w3c.github.io/ServiceWorker/)
 
 [SecureContext, Exposed=(Window,Worker)]
 interface ServiceWorker : EventTarget {
   readonly attribute USVString scriptURL;
   readonly attribute ServiceWorkerState state;
-  void postMessage(any message, optional sequence<object> transfer = []);
+  void postMessage(any message, sequence<object> transfer);
+  void postMessage(any message, optional PostMessageOptions options);
 
   // event
   attribute EventHandler onstatechange;
@@ -27,6 +28,7 @@
   readonly attribute ServiceWorker? installing;
   readonly attribute ServiceWorker? waiting;
   readonly attribute ServiceWorker? active;
+  [SameObject] readonly attribute NavigationPreloadManager navigationPreload;
 
   readonly attribute USVString scope;
   readonly attribute ServiceWorkerUpdateViaCache updateViaCache;
@@ -76,6 +78,19 @@
   ServiceWorkerUpdateViaCache updateViaCache = "imports";
 };
 
+[SecureContext, Exposed=(Window,Worker)]
+interface NavigationPreloadManager {
+  Promise<void> enable();
+  Promise<void> disable();
+  Promise<void> setHeaderValue(ByteString value);
+  Promise<NavigationPreloadState> getState();
+};
+
+dictionary NavigationPreloadState {
+  boolean enabled = false;
+  ByteString headerValue;
+};
+
 [Global=(Worker,ServiceWorker), Exposed=ServiceWorker]
 interface ServiceWorkerGlobalScope : WorkerGlobalScope {
   [SameObject] readonly attribute Clients clients;
@@ -98,7 +113,8 @@
   readonly attribute FrameType frameType;
   readonly attribute DOMString id;
   readonly attribute ClientType type;
-  void postMessage(any message, optional sequence<object> transfer = []);
+  void postMessage(any message, sequence<object> transfer);
+  void postMessage(any message, optional PostMessageOptions options);
 };
 
 [Exposed=ServiceWorker]
@@ -150,14 +166,20 @@
 [Constructor(DOMString type, FetchEventInit eventInitDict), Exposed=ServiceWorker]
 interface FetchEvent : ExtendableEvent {
   [SameObject] readonly attribute Request request;
+  readonly attribute Promise<any> preloadResponse;
   readonly attribute DOMString clientId;
+  readonly attribute DOMString resultingClientId;
+  readonly attribute DOMString replacesClientId;
 
   void respondWith(Promise<Response> r);
 };
 
 dictionary FetchEventInit : ExtendableEventInit {
   required Request request;
+  Promise<any> preloadResponse;
   DOMString clientId = "";
+  DOMString resultingClientId = "";
+  DOMString replacesClientId = "";
 };
 
 [Constructor(DOMString type, optional ExtendableMessageEventInit eventInitDict), Exposed=ServiceWorker]
@@ -177,7 +199,7 @@
   sequence<MessagePort> ports = [];
 };
 
-partial interface WindowOrWorkerGlobalScope {
+partial interface mixin WindowOrWorkerGlobalScope {
   [SecureContext, SameObject] readonly attribute CacheStorage caches;
 };
 
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl
index f94637a8d..ba86d50 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl
@@ -155,6 +155,7 @@
 interface SpeechSynthesisEvent : Event {
     readonly attribute SpeechSynthesisUtterance utterance;
     readonly attribute unsigned long charIndex;
+    readonly attribute unsigned long charLength;
     readonly attribute float elapsedTime;
     readonly attribute DOMString name;
 };
@@ -162,6 +163,7 @@
 dictionary SpeechSynthesisEventInit : EventInit {
     required SpeechSynthesisUtterance utterance;
     unsigned long charIndex = 0;
+    unsigned long charLength = 0;
     float elapsedTime = 0;
     DOMString name = "";
 };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/touch-events.idl b/third_party/blink/web_tests/external/wpt/interfaces/touch-events.idl
index 5e341bd7..17be1b46 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/touch-events.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/touch-events.idl
@@ -67,7 +67,7 @@
     readonly        attribute boolean shiftKey;
 };
 
-partial interface GlobalEventHandlers {
+partial interface mixin GlobalEventHandlers {
                     attribute EventHandler ontouchstart;
                     attribute EventHandler ontouchend;
                     attribute EventHandler ontouchmove;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/user-timing.idl b/third_party/blink/web_tests/external/wpt/interfaces/user-timing.idl
index da8a0acd..cd2e1446 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/user-timing.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/user-timing.idl
@@ -10,15 +10,15 @@
 
 dictionary PerformanceMeasureOptions {
     any detail = null;
-    (DOMString or DOMHighResTimeStamp) startTime;
+    (DOMString or DOMHighResTimeStamp) start;
     DOMHighResTimeStamp duration;
-    (DOMString or DOMHighResTimeStamp) endTime;
+    (DOMString or DOMHighResTimeStamp) end;
 };
 
 partial interface Performance {
     PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions);
     void clearMarks(optional DOMString markName);
-    PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions) startOrMeasureOptions, optional DOMString endMark);
+    PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions)? startOrMeasureOptions, optional DOMString endMark);
     void clearMeasures(optional DOMString measureName);
 };
 
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl b/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl
index 89da0b8d..10e7148 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl
@@ -5,7 +5,7 @@
 
 enum WakeLockType { "screen", "system" };
 
-[Constructor(WakeLockType type), SecureContext, Exposed=(DedicatedWorker, Window)]
+[Constructor(WakeLockType type), SecureContext, Exposed=(DedicatedWorker,Window)]
 interface WakeLock : EventTarget {
   readonly attribute WakeLockType type;
   readonly attribute boolean active;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl b/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl
index becf8dd..be8d0c10 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl
@@ -1,7 +1,7 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into reffy-reports
 // (https://github.com/tidoust/reffy-reports)
-// Source: Web Authentication: An API for accessing Public Key Credentials - Level 1 (https://w3c.github.io/webauthn/)
+// Source: Web Authentication: An API for accessing Public Key Credentials - Level 2 (https://w3c.github.io/webauthn/)
 
 [SecureContext, Exposed=Window]
 interface PublicKeyCredential : Credential {
@@ -30,6 +30,7 @@
 [SecureContext, Exposed=Window]
 interface AuthenticatorAttestationResponse : AuthenticatorResponse {
     [SameObject] readonly attribute ArrayBuffer      attestationObject;
+    sequence<AuthenticatorTransport>                 getTransports();
 };
 
 [SecureContext, Exposed=Window]
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl
index c86097b..e528928 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl
@@ -20,7 +20,8 @@
 "candidate-pair",
 "local-candidate",
 "remote-candidate",
-"certificate"
+"certificate",
+"stunserverconnection"
 };
 
 dictionary RTCRtpStreamStats : RTCStats {
@@ -28,11 +29,6 @@
              DOMString kind;
              DOMString transportId;
              DOMString codecId;
-             unsigned long firCount;
-             unsigned long pliCount;
-             unsigned long nackCount;
-             unsigned long sliCount;
-             unsigned long long qpSum;
 };
 
 dictionary RTCCodecStats : RTCStats {
@@ -72,6 +68,7 @@
              DOMString receiverId;
              DOMString remoteId;
              unsigned long framesDecoded;
+             unsigned long long qpSum;
              DOMHighResTimeStamp lastPacketReceivedTimestamp;
              double averageRtcpInterval;
              unsigned long fecPacketsReceived;
@@ -79,6 +76,10 @@
              unsigned long packetsFailedDecryption;
              unsigned long packetsDuplicated;
              record<USVString, unsigned long> perDscpPacketsReceived;
+             unsigned long nackCount;
+             unsigned long firCount;
+             unsigned long pliCount;
+             unsigned long sliCount;
             };
 
 dictionary RTCRemoteInboundRtpStreamStats : RTCReceivedRtpStreamStats {
@@ -102,11 +103,16 @@
              DOMHighResTimeStamp lastPacketSentTimestamp;
              double targetBitrate;
              unsigned long framesEncoded;
+             unsigned long long qpSum;
              double totalEncodeTime;
              double averageRtcpInterval;
              RTCQualityLimitationReason qualityLimitationReason;
              record<DOMString, double> qualityLimitationDurations;
              record<USVString, unsigned long> perDscpPacketsSent;
+             unsigned long nackCount;
+             unsigned long firCount;
+             unsigned long pliCount;
+             unsigned long sliCount;
 };
 
 enum RTCQualityLimitationReason {
@@ -298,6 +304,16 @@
              DOMString issuerCertificateId;
 };
 
+dictionary RTCStunServerConnectionStats : RTCStats {
+             DOMString url;
+             long port;
+             DOMString protocol;
+             RTCNetworkType networkType;
+             unsigned long totalRequestsSent;
+             unsigned long totalResponsesReceived;
+             double totalRoundTripTime;
+  };
+
 partial dictionary RTCIceCandidateStats {
            boolean isRemote;
         };
@@ -312,3 +328,7 @@
              DOMString mediaType;
              double averageRTCPInterval;
 };
+
+partial dictionary RTCInboundRtpStreamStats {
+          double fractionLost;
+};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
index d60139a..413a96a 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
@@ -105,7 +105,7 @@
     readonly        attribute RTCSessionDescription? remoteDescription;
     readonly        attribute RTCSessionDescription? currentRemoteDescription;
     readonly        attribute RTCSessionDescription? pendingRemoteDescription;
-    Promise<void> addIceCandidate(RTCIceCandidateInit candidate);
+    Promise<void> addIceCandidate(optional RTCIceCandidateInit candidate);
     readonly        attribute RTCSignalingState signalingState;
     readonly        attribute RTCIceGatheringState iceGatheringState;
     readonly        attribute RTCIceConnectionState iceConnectionState;
@@ -609,6 +609,26 @@
             required RTCStatsReport report;
           };
 
+[
+    Exposed=Window,
+    Constructor(RTCErrorInit init, optional DOMString message = "")] interface RTCError {
+    readonly attribute RTCErrorDetailType errorDetail;
+    readonly attribute long? sdpLineNumber;
+    readonly attribute long? httpRequestStatusCode;
+    readonly attribute long? sctpCauseCode;
+    readonly attribute unsigned long? receivedAlert;
+    readonly attribute unsigned long? sentAlert;
+};
+
+dictionary RTCErrorInit {
+    required RTCErrorDetailType errorDetail;
+    long sdpLineNumber;
+    long httpRequestStatusCode;
+    long sctpCauseCode;
+    unsigned long receivedAlert;
+    unsigned long sentAlert;
+};
+
 enum RTCErrorDetailType {
               "data-channel-failure",
               "dtls-failure",
@@ -627,12 +647,12 @@
               "hardware-encoder-error"
           };
 
-[Exposed=Window,
- Constructor(DOMString type, optional RTCErrorEventInit eventInitDict)]
-interface RTCErrorEvent : Event {
-    readonly        attribute RTCError? error;
+[
+    Exposed=Window,
+    Constructor(DOMString type, RTCErrorEventInit eventInitDict)] interface RTCErrorEvent : Event {
+    [SameObject] readonly attribute RTCError error;
 };
 
 dictionary RTCErrorEventInit : EventInit {
-             RTCError? error = null;
+     required RTCError error;
 };
diff --git a/third_party/blink/web_tests/external/wpt/lint.whitelist b/third_party/blink/web_tests/external/wpt/lint.whitelist
index fd4d404..96fd7ed0 100644
--- a/third_party/blink/web_tests/external/wpt/lint.whitelist
+++ b/third_party/blink/web_tests/external/wpt/lint.whitelist
@@ -804,4 +804,5 @@
 
 # Signed Exchange files have hard-coded URLs in the certUrl field
 WEB-PLATFORM.TEST:signed-exchange/resources/*.sxg
+WEB-PLATFORM.TEST:signed-exchange/appcache/resources/*.sxg
 WEB-PLATFORM.TEST:signed-exchange/resources/generate-test-sxgs.sh
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/META.yml b/third_party/blink/web_tests/external/wpt/payment-request/META.yml
index 558db3e..5897c26 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/META.yml
+++ b/third_party/blink/web_tests/external/wpt/payment-request/META.yml
@@ -2,7 +2,6 @@
 suggested_reviewers:
   - marcoscaceres
   - rsolomakhin
-  - domenic
   - zouhir
   - romandev
   - edenchuang
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/PaymentRequestUpdateEvent/updateWith-method-abort-update-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/PaymentRequestUpdateEvent/updateWith-method-abort-update-manual.https.html
index 70621c8..99b7a28 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/PaymentRequestUpdateEvent/updateWith-method-abort-update-manual.https.html
+++ b/third_party/blink/web_tests/external/wpt/payment-request/PaymentRequestUpdateEvent/updateWith-method-abort-update-manual.https.html
@@ -141,7 +141,7 @@
 Object.freeze(recursiveData);
 
 const modifierWithRecursiveData = Object.freeze({
-  supportedMethods: validMethodBasicCard,
+  supportedMethods: "basic-card",
   total: validTotal,
   data: recursiveData,
 });
@@ -186,7 +186,7 @@
 <ol>
   <li>
     <button onclick="
-      const rejectedPromise = Promise.reject(new SyntaxError('test')).catch(err => err);
+      const rejectedPromise = Promise.reject(new SyntaxError('test'));
       testBadUpdate(this, rejectedPromise, 'AbortError');
     ">
       Rejection of detailsPromise must abort the update with an "AbortError" DOMException.
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/updateWith-method-pmi-handling-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/updateWith-method-pmi-handling-manual.https.html
index 8bab882..6cddeb9 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/updateWith-method-pmi-handling-manual.https.html
+++ b/third_party/blink/web_tests/external/wpt/payment-request/updateWith-method-pmi-handling-manual.https.html
@@ -1,5 +1,4 @@
 <!DOCTYPE html>
-<!-- Copyright © 2017 Mozilla and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
 <meta charset="utf-8">
 <title>Test for validity of payment method identifiers when calling updateWith() method</title>
 <link rel="help" href="https://www.w3.org/TR/payment-request/#updatewith()-method">
@@ -7,7 +6,11 @@
 <script src="/resources/testharnessreport.js"></script>
 <script>
 "use strict";
-setup({ explicit_done: true, explicit_timeout: true });
+setup({
+  explicit_done: true,
+  explicit_timeout: true,
+  allow_uncaught_exception: true,
+});
 const applePay = Object.freeze({
   supportedMethods: "https://apple.com/apple-pay",
   data: {
@@ -16,13 +19,17 @@
     countryCode: "US",
     merchantCapabilities: ["supports3DS"],
     supportedNetworks: ["visa"],
-  }
+  },
 });
 const validMethod = Object.freeze({
   supportedMethods: "https://:@wpt.fyi:443/payment-request",
 });
 
-const validMethods = Object.freeze([validMethod, applePay]);
+const validMethods = Object.freeze([
+  validMethod,
+  applePay,
+  { supportedMethods: "basic-card" },
+]);
 
 const validAmount = Object.freeze({
   currency: "USD",
@@ -51,23 +58,12 @@
   total: validTotal,
 });
 
-test(() => {
-  try {
-    new PaymentRequest(validMethods, validDetails);
-  } catch (err) {
-    done();
-    throw err;
-  }
-}, "smoke test");
-
 function manualTest(button, { invalidMethod }) {
   button.disabled = true;
   promise_test(async t => {
-    const request = new PaymentRequest(
-      [{ supportedMethods: "basic-card" }],
-      validDetails,
-      { requestShipping: true }
-    );
+    const request = new PaymentRequest(validMethods, validDetails, {
+      requestShipping: true,
+    });
     const listener = ev => {
       const invalidModifier = Object.assign({}, validModifier, {
         supportedMethods: invalidMethod,
@@ -130,10 +126,13 @@
     </button>
   </li>
   <li>
-    <button onclick="manualTest(this, {invalidMethod: 'Basic-Card'}); done();">
+    <button onclick="manualTest(this, {invalidMethod: 'Basic-Card'});">
       Must throw if standardized PMI has uppercase characters.
     </button>
   </li>
+  <li>
+    <button onclick="done();">Done!</button>
+  </li>
 </ol>
 <small>
   If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/idlharness.window-expected.txt b/third_party/blink/web_tests/external/wpt/pointerevents/idlharness.window-expected.txt
index a7b5fb5..e0ed9cea 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/idlharness.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/idlharness.window-expected.txt
@@ -1,7 +1,7 @@
 This is a testharness.js-based test.
 FAIL idl_test setup promise_test: Unhandled rejection with value: "Document includes GlobalEventHandlers, but Document is undefined."
 PASS Partial interface Element: original interface defined
-PASS Partial interface GlobalEventHandlers: original interface defined
+PASS Partial interface mixin GlobalEventHandlers: original interface mixin defined
 PASS Partial interface Navigator: original interface defined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/resize-observer/idlharness.window.js b/third_party/blink/web_tests/external/wpt/resize-observer/idlharness.window.js
index 592af2e..2d459b0b 100644
--- a/third_party/blink/web_tests/external/wpt/resize-observer/idlharness.window.js
+++ b/third_party/blink/web_tests/external/wpt/resize-observer/idlharness.window.js
@@ -7,7 +7,7 @@
 // https://wicg.github.io/ResizeObserver/
 
 idl_test(
-  ['ResizeObserver'],
+  ['resize-observer'],
   ['dom', 'geometry'],
   async idl_array => {
     idl_array.add_objects({
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
index 15c9fb80..5e51cf62 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 167 tests; 153 PASS, 14 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 181 tests; 166 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Interfaces and attributes in ServiceWorkerGlobalScope
 PASS test setup (cache creation)
 FAIL Event constructors assert_equals: FetchEvent.isReload should not exist expected (undefined) undefined but got (boolean) false
@@ -14,6 +14,7 @@
 FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
 FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
 FAIL ServiceWorker interface: operation postMessage(any, [object Object]) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+FAIL ServiceWorker interface: operation postMessage(any, PostMessageOptions) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
 FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
 PASS ServiceWorkerRegistration interface: existence and properties of interface object
 PASS ServiceWorkerRegistration interface object length
@@ -24,6 +25,7 @@
 PASS ServiceWorkerRegistration interface: attribute installing
 PASS ServiceWorkerRegistration interface: attribute waiting
 PASS ServiceWorkerRegistration interface: attribute active
+PASS ServiceWorkerRegistration interface: attribute navigationPreload
 PASS ServiceWorkerRegistration interface: attribute scope
 PASS ServiceWorkerRegistration interface: attribute updateViaCache
 PASS ServiceWorkerRegistration interface: operation update()
@@ -34,11 +36,22 @@
 PASS ServiceWorkerRegistration interface: self.registration must inherit property "installing" with the proper type
 PASS ServiceWorkerRegistration interface: self.registration must inherit property "waiting" with the proper type
 PASS ServiceWorkerRegistration interface: self.registration must inherit property "active" with the proper type
+PASS ServiceWorkerRegistration interface: self.registration must inherit property "navigationPreload" with the proper type
 PASS ServiceWorkerRegistration interface: self.registration must inherit property "scope" with the proper type
 PASS ServiceWorkerRegistration interface: self.registration must inherit property "updateViaCache" with the proper type
 PASS ServiceWorkerRegistration interface: self.registration must inherit property "update()" with the proper type
 PASS ServiceWorkerRegistration interface: self.registration must inherit property "unregister()" with the proper type
 PASS ServiceWorkerRegistration interface: self.registration must inherit property "onupdatefound" with the proper type
+PASS NavigationPreloadManager interface: existence and properties of interface object
+PASS NavigationPreloadManager interface object length
+PASS NavigationPreloadManager interface object name
+PASS NavigationPreloadManager interface: existence and properties of interface prototype object
+PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
+PASS NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property
+PASS NavigationPreloadManager interface: operation enable()
+PASS NavigationPreloadManager interface: operation disable()
+PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
+PASS NavigationPreloadManager interface: operation getState()
 PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
 PASS ServiceWorkerGlobalScope interface object length
 PASS ServiceWorkerGlobalScope interface object name
@@ -86,6 +99,7 @@
 PASS Client interface: attribute id
 PASS Client interface: attribute type
 PASS Client interface: operation postMessage(any, [object Object])
+PASS Client interface: operation postMessage(any, PostMessageOptions)
 PASS WindowClient interface: existence and properties of interface object
 PASS WindowClient interface object length
 PASS WindowClient interface object name
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/appcache.manifest b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/appcache.manifest
new file mode 100644
index 0000000..adc0409be
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/appcache.manifest
@@ -0,0 +1,3 @@
+CACHE MANIFEST
+resources/appcached-url.html
+resources/sxg/sxg-location.sxg
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/appcached-url-in-sxg.html b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/appcached-url-in-sxg.html
new file mode 100644
index 0000000..5f5defb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/appcached-url-in-sxg.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>Content of appcached URL</title>
+<script>
+window.addEventListener('message', (event) => {
+  event.data.port.postMessage({
+      location: document.location.href,
+      referrer: document.referrer,
+      appcacheContent: false});
+}, false);
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/appcached-url.html b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/appcached-url.html
new file mode 100644
index 0000000..d58617b6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/appcached-url.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>Content of appcached URL</title>
+<script>
+window.addEventListener('message', (event) => {
+  event.data.port.postMessage({
+      location: document.location.href,
+      referrer: document.referrer,
+      appcacheContent: true});
+}, false);
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/inner-url.html b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/inner-url.html
new file mode 100644
index 0000000..5b247bb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/inner-url.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>Content of fallback URL</title>
+<script>
+window.addEventListener('message', (event) => {
+  event.data.port.postMessage({
+      location: document.location.href,
+      referrer: document.referrer,
+      is_fallback: true});
+}, false);
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/sxg/__dir__.headers b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/sxg/__dir__.headers
new file mode 100644
index 0000000..83a3c12
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/sxg/__dir__.headers
@@ -0,0 +1,2 @@
+Content-Type: application/signed-exchange;v=b3
+X-Content-Type-Options: nosniff
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/sxg/sxg-appcached.sxg b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/sxg/sxg-appcached.sxg
new file mode 100644
index 0000000..673adc20
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/sxg/sxg-appcached.sxg
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/sxg/sxg-location.sxg b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/sxg/sxg-location.sxg
new file mode 100644
index 0000000..624e673
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/resources/sxg/sxg-location.sxg
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/sxg-inner-resp-over-appcache.tentative.https.html b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/sxg-inner-resp-over-appcache.tentative.https.html
new file mode 100644
index 0000000..68edbed
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/sxg-inner-resp-over-appcache.tentative.https.html
@@ -0,0 +1,21 @@
+<html manifest="appcache.manifest">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="../resources/sxg-util.js"></script>
+<script>
+const cache_ready = new Promise(resolve => {
+  ['cached','noupdate'].forEach(event_name => {
+    window.applicationCache.addEventListener(event_name, resolve);
+  });
+});
+
+promise_test(async (t) => {
+  await cache_ready;
+
+  const sxgUrl = get_host_info().HTTPS_ORIGIN + '/signed-exchange/appcache/resources/sxg/sxg-appcached.sxg';
+  const message = await openSXGInIframeAndWaitForMessage(t, sxgUrl);
+  assert_equals(message.location, innerURLOrigin() + '/signed-exchange/appcache/resources/appcached-url.html');
+  assert_false(message.appcacheContent);
+}, 'SignedHTTPExchange inner resp should take precedence to appcache.');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html
new file mode 100644
index 0000000..b9ca0ff
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html
@@ -0,0 +1,21 @@
+<html manifest="appcache.manifest">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="../resources/sxg-util.js"></script>
+<script>
+const cache_ready = new Promise(resolve => {
+  ['cached','noupdate'].forEach(event_name => {
+    window.applicationCache.addEventListener(event_name, resolve);
+  });
+});
+
+promise_test(async (t) => {
+  await cache_ready;
+
+  const sxgUrl = get_host_info().HTTPS_ORIGIN + '/signed-exchange/appcache/resources/sxg/sxg-location.sxg';
+  const message = await openSXGInIframeAndWaitForMessage(t, sxgUrl);
+  assert_equals(message.location, innerURLOrigin() + '/signed-exchange/appcache/resources/inner-url.html');
+  assert_false(message.is_fallback);
+}, 'SignedHTTPExchange cached in appcache should work.');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/generate-test-sxgs.sh b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/generate-test-sxgs.sh
index e76286be9..64c28325 100755
--- a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/generate-test-sxgs.sh
+++ b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/generate-test-sxgs.sh
@@ -43,6 +43,37 @@
   -o sxg/sxg-location.sxg \
   -miRecordSize 100
 
+# A valid Signed Exchange for appcache test.
+gen-signedexchange \
+  -version $sxg_version \
+  -uri $inner_url_origin/signed-exchange/appcache/resources/inner-url.html \
+  -status 200 \
+  -content sxg-location.html \
+  -certificate $certfile \
+  -certUrl $cert_url_origin/signed-exchange/resources/$certfile.cbor \
+  -validityUrl $inner_url_origin/signed-exchange/resources/resource.validity.msg \
+  -privateKey $keyfile \
+  -date 2018-04-01T00:00:00Z \
+  -expire 168h \
+  -o ../appcache/resources/sxg/sxg-location.sxg \
+  -miRecordSize 100
+
+# A valid Signed Exchange for appcache test
+# - appcache and the sxg inner resp both provide the content for the url
+gen-signedexchange \
+  -version $sxg_version \
+  -uri $inner_url_origin/signed-exchange/appcache/resources/appcached-url.html \
+  -status 200 \
+  -content ../appcache/resources/appcached-url-in-sxg.html \
+  -certificate $certfile \
+  -certUrl $cert_url_origin/signed-exchange/resources/$certfile.cbor \
+  -validityUrl $inner_url_origin/signed-exchange/resources/resource.validity.msg \
+  -privateKey $keyfile \
+  -date 2018-04-01T00:00:00Z \
+  -expire 168h \
+  -o ../appcache/resources/sxg/sxg-appcached.sxg \
+  -miRecordSize 100
+
 # A valid Signed Exchange. The origin of certUrl is the "alt" origin where NEL
 # policy is installed in reporting tests.
 gen-signedexchange \
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-constructor-expected.txt b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-constructor-expected.txt
new file mode 100644
index 0000000..666caa9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-constructor-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+PASS SpeechSynthesisEvent with no arguments throws TypeError
+PASS SpeechSynthesisEvent with no eventInitDict throws TypeError
+PASS SpeechSynthesisEvent with empty eventInitDict throws TypeError (requires
+    utterance)
+PASS SpeechSynthesisEvent with eventInitDict not having utterance throws
+    TypeError
+FAIL SpeechSynthesisEvent with eventInitDict having an utterance assert_equals: expected (number) 0 but got (undefined) undefined
+FAIL SpeechSynthesisEvent with custom eventInitDict assert_equals: expected (number) 3 but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-constructor.html b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-constructor.html
index 47a37d25..3ad6886b 100644
--- a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-constructor.html
+++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-constructor.html
@@ -44,6 +44,7 @@
   const event = new SpeechSynthesisEvent("type", {utterance: utterance});
   assert_equals(event.utterance, utterance);
   assert_equals(event.charIndex, 0);
+  assert_equals(event.charLength, 0);
   assert_equals(event.elapsedTime, 0);
   assert_equals(event.name, "");
 }, "SpeechSynthesisEvent with eventInitDict having an utterance");
@@ -53,6 +54,7 @@
   const event = new SpeechSynthesisEvent("type", {
     utterance: utterance,
     charIndex: 5,
+    charLength: 3,
     elapsedTime: 100,
     name: "foo"
   });
@@ -61,6 +63,7 @@
   assert_equals(event.type, "type");
   assert_equals(event.utterance, utterance);
   assert_equals(event.charIndex, 5);
+  assert_equals(event.charLength, 3);
   assert_equals(event.elapsedTime, 100);
   assert_equals(event.name, "foo");
 }, "SpeechSynthesisEvent with custom eventInitDict");
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/idlharness.window-expected.txt b/third_party/blink/web_tests/external/wpt/speech-api/idlharness.window-expected.txt
index ee63d6d..36527b0 100644
--- a/third_party/blink/web_tests/external/wpt/speech-api/idlharness.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/speech-api/idlharness.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 222 tests; 65 PASS, 157 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 223 tests; 65 PASS, 158 FAIL, 0 TIMEOUT, 0 NOTRUN.
 FAIL idl_test setup promise_test: Unhandled rejection with value: "Timed out waiting for voice"
 PASS Partial interface Window: original interface defined
 FAIL SpeechRecognition interface: existence and properties of interface object assert_own_property: self does not have own property "SpeechRecognition" expected property "SpeechRecognition" missing
@@ -193,6 +193,7 @@
 PASS SpeechSynthesisEvent interface: existence and properties of interface prototype object's @@unscopables property
 PASS SpeechSynthesisEvent interface: attribute utterance
 PASS SpeechSynthesisEvent interface: attribute charIndex
+FAIL SpeechSynthesisEvent interface: attribute charLength assert_true: The prototype object must have a property "charLength" expected true got false
 PASS SpeechSynthesisEvent interface: attribute elapsedTime
 PASS SpeechSynthesisEvent interface: attribute name
 PASS SpeechSynthesisErrorEvent interface: existence and properties of interface object
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-001-ref.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-001-ref.svg
new file mode 100644
index 0000000..b9554bac
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-001-ref.svg
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 001</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <g id="test-body-reference" style="font-size:16px">
+    <g transform="translate(0,0)">
+      <text x="80" y="114.8">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
+    </g>
+    <g transform="translate(0,60)">
+      <text x="48" y="114.8">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
+    </g>
+    <g transform="translate(0,120)">
+      <text x="16" y="114.8">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-001.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-001.svg
new file mode 100644
index 0000000..015b3dd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-001.svg
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 001</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+    <html:link rel="help"
+          href="https://svgwg.org/svg2-draft/text.html#TextAnchoringProperties"/>
+    <html:link rel="match"  href="text-text-anchor-001-ref.svg" />
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <!-- TEMP -->
+  <g id="test-body-reference" style="font-size:16px;fill:red">
+    <g transform="translate(0,0)">
+      <circle cx="80" cy="114.8" r="2" style="fill:red"/>
+      <text x="80" y="114.8">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
+    </g>
+    <g transform="translate(0,60)">
+      <circle cx="240" cy="114.8" r="2" style="fill:red"/>
+      <text x="48" y="114.8">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
+    </g>
+    <g transform="translate(0,120)">
+      <circle cx="400" cy="114.8" r="2" style="fill:red"/>
+      <text x="17" y="114.8">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
+    </g>
+  </g>
+
+  <g id="test-body-content" style="font-size:16px">
+    <g transform="translate(0,0)">
+      <text x="80" y="114.8" style="text-anchor:start">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
+    </g>
+    <g transform="translate(0,60)">
+      <text x="240" y="114.8" style="text-anchor:middle">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
+    </g>
+    <g transform="translate(0,120)">
+      <text x="400" y="114.8" style="text-anchor:end">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-002-ref.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-002-ref.svg
new file mode 100644
index 0000000..5721bc3e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-002-ref.svg
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 002</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <g id="test-body-reference" style="font-size:16px">
+    <g transform="translate(0,0)">
+      <text transform="translate(250,10) rotate(90)">
+        <tspan x="90" y="114.8">Lorem ipsum dolor sit amet,</tspan>
+      </text>
+    </g>
+    <g transform="translate(80,0)">
+      <text transform="translate(250,-40) rotate(90)" style="text-anchor:middle">
+        <tspan x="240" y="114.8">Lorem ipsum dolor sit amet,</tspan>
+      </text>
+    </g>
+    <g transform="translate(160,0)">
+      <text transform="translate(250,-90) rotate(90)" style="text-anchor:end">
+        <tspan x="390" y="114.8">Lorem ipsum dolor sit amet,</tspan>
+      </text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-002.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-002.svg
new file mode 100644
index 0000000..503ce166
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-002.svg
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 002</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+    <html:link rel="help"
+          href="https://svgwg.org/svg2-draft/text.html#TextAnchoringProperties"/>
+    <html:link rel="match"  href="text-text-anchor-002-ref.svg" />
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <g id="test-body-reference" style="font-size:16px;fill:red">
+    <g transform="translate(0,0)">
+      <circle cx="140" cy="100" r="2" style="fill:red"/>
+      <text transform="translate(250,10) rotate(90)">
+        <tspan x="90" y="114.8">Lorem ipsum dolor sit amet,</tspan>
+      </text>
+    </g>
+    <g transform="translate(80,0)">
+      <circle cx="140" cy="200" r="2" style="fill:red"/>
+      <text transform="translate(250,-40) rotate(90)" style="text-anchor:middle">
+        <tspan x="240" y="114.8">Lorem ipsum dolor sit amet,</tspan>
+      </text>
+    </g>
+    <g transform="translate(160,0)">
+      <circle cx="140" cy="300" r="2" style="fill:red"/>
+      <text transform="translate(250,-90) rotate(90)" style="text-anchor:end">
+        <tspan x="390" y="114.8">Lorem ipsum dolor sit amet,</tspan>
+      </text>
+    </g>
+  </g>
+
+  <g id="test-body-content" style="font-size:16px;writing-mode:tb-rl">
+    <g transform="translate(0,0)">
+      <text x="140" y="100" style="text-anchor:start">Lorem ipsum dolor sit amet,</text>
+    </g>
+    <g transform="translate(80,0)">
+      <text x="140" y="200" style="text-anchor:middle">Lorem ipsum dolor sit amet,</text>
+    </g>
+    <g transform="translate(160,0)">
+      <text x="140" y="300" style="text-anchor:end">Lorem ipsum dolor sit amet,</text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-003-ref.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-003-ref.svg
new file mode 100644
index 0000000..797dea3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-003-ref.svg
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 003</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <g id="test-body-reference" style="font-size:16px">
+    <g transform="translate(0,0)">
+      <text style="text-anchor:end">
+        <tspan x="400" y="114.8">لكن لا بد أن أوضح لك أن كل هذه الأفكار</tspan>
+      </text>
+    </g>
+    <g transform="translate(0,60)">
+      <text style="text-anchor:middle">
+        <tspan x="240" y="114.8">لكن لا بد أن أوضح لك أن كل هذه الأفكار</tspan>
+      </text>
+    </g>
+    <g transform="translate(0,120)">
+      <text>
+        <tspan x="80" y="114.8">لكن لا بد أن أوضح لك أن كل هذه الأفكار</tspan>
+      </text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-003.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-003.svg
new file mode 100644
index 0000000..eb5063020
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-003.svg
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 003</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+    <html:link rel="help"
+          href="https://svgwg.org/svg2-draft/text.html#TextAnchoringProperties"/>
+    <html:link rel="match"  href="text-text-anchor-003-ref.svg" />
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <!-- TEMP -->
+  <g id="test-body-reference" style="font-size:16px;fill:red">
+    <g transform="translate(0,0)">
+      <circle cx="400" cy="114.8" r="2" style="fill:red"/>
+      <text style="text-anchor:end">
+        <tspan x="400" y="114.8">لكن لا بد أن أوضح لك أن كل هذه الأفكار</tspan>
+      </text>
+    </g>
+    <g transform="translate(0,60)">
+      <circle cx="240" cy="114.8" r="2" style="fill:red"/>
+      <text style="text-anchor:middle">
+        <tspan x="240" y="114.8">لكن لا بد أن أوضح لك أن كل هذه الأفكار</tspan>
+      </text>
+    </g>
+    <g transform="translate(0,120)">
+      <circle cx="80" cy="114.8" r="2" style="fill:red"/>
+      <text>
+        <tspan x="80" y="114.8">لكن لا بد أن أوضح لك أن كل هذه الأفكار</tspan>
+      </text>
+    </g>
+  </g>
+
+  <g id="test-body-content" style="font-size:16px;direction:rtl">
+    <g transform="translate(0,0)">
+      <text x="400" y="114.8" style="text-anchor:start">لكن لا بد أن أوضح لك أن كل هذه الأفكار</text>
+    </g>
+    <g transform="translate(0,60)">
+      <text x="240" y="114.8" style="text-anchor:middle">لكن لا بد أن أوضح لك أن كل هذه الأفكار</text>
+    </g>
+    <g transform="translate(0,120)">
+      <text x="80" y="114.8" style="text-anchor:end">لكن لا بد أن أوضح لك أن كل هذه الأفكار</text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-102-ref.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-102-ref.svg
new file mode 100644
index 0000000..9c1d98c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-102-ref.svg
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 102</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: IPAMincho;
+      src: url("fonts/IPAMincho.woff") format("woff"),
+           local("IPAMincho");
+    }
+    text { font-family: IPAMincho, sans-serif }
+  </style>
+
+  <g id="test-body-reference" style="font-size:16px">
+    <g transform="translate(0,0)">
+      <text x="132 132 132 132 132 132 132" y="114 130 146 162 178 194 210 ">千利奴流乎和加</text>
+    </g>
+    <g transform="translate(80,0)">
+      <text x="140" y="144" style="writing-mode:tb-rl">千利奴流乎和加</text>
+    </g>
+    <g transform="translate(160,0)">
+      <text x="140" y="188" style="writing-mode:tb-rl">千利奴流乎和加</text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-102.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-102.svg
new file mode 100644
index 0000000..8cdcc98
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-102.svg
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 102</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+    <html:link rel="help"
+          href="https://svgwg.org/svg2-draft/text.html#TextAnchoringProperties"/>
+    <html:link rel="match"  href="text-text-anchor-102-ref.svg" />
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: IPAMincho;
+      src: url("fonts/IPaMincho.woff") format("woff"),
+           local("IPAMincho");
+    }
+    text { font-family: IPAMincho, sans-serif }
+  </style>
+
+  <g id="test-body-reference" style="font-size:16px;fill:red">
+    <g transform="translate(0,0)">
+      <circle cx="140" cy="100" r="2" style="fill:red"/>
+      <text x="132 132 132 132 132 132 132" y="114 130 146 162 178 194 210 ">千利奴流乎和加</text>
+    </g>
+    <g transform="translate(80,0)">
+      <circle cx="140" cy="200" r="2" style="fill:red"/>
+      <text x="140" y="144" style="writing-mode:tb-rl">千利奴流乎和加</text>
+    </g>
+    <g transform="translate(160,0)">
+      <circle cx="140" cy="300" r="2" style="fill:red"/>
+      <text x="140" y="188" style="writing-mode:tb-rl">千利奴流乎和加</text>
+    </g>
+  </g>
+
+  <g id="test-body-content" style="font-size:16px;writing-mode:tb-rl">
+    <g transform="translate(0,0)">
+      <text x="140" y="100" style="text-anchor:start">千利奴流乎和加</text>
+    </g>
+    <g transform="translate(80,0)">
+      <text x="140" y="200" style="text-anchor:middle">千利奴流乎和加</text>
+    </g>
+    <g transform="translate(160,0)">
+      <text x="140" y="300" style="text-anchor:end">千利奴流乎和加</text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-201-ref.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-201-ref.svg
new file mode 100644
index 0000000..d8b6cc4e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-201-ref.svg
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 201</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <g id="test-body-reference" style="font-size:16px">
+    <g transform="translate(0,0)">
+      <text x="200" y="114.8">Lorem ipsum dolor</text>
+    </g>
+    <g transform="translate(0,60)">
+      <text x="200" y="114.8" style="text-anchor:middle">sit amet, consectetur</text>
+    </g>
+    <g transform="translate(0,120)">
+      <text x="200" y="114.8" style="text-anchor:end">adipisicing elit,</text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-201.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-201.svg
new file mode 100644
index 0000000..84b644cd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-201.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 201</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+    <html:link rel="help"
+          href="https://svgwg.org/svg2-draft/text.html#TextAnchoringProperties"/>
+    <html:link rel="match"  href="text-text-anchor-201-ref.svg" />
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <!-- TEMP -->
+  <g id="test-body-reference" style="font-size:16px;fill:red">
+    <g transform="translate(0,0)">
+      <circle cx="200" cy="114.8" r="2" style="fill:red"/>
+      <text x="200" y="114.8">Lorem ipsum dolor</text>
+    </g>
+    <g transform="translate(0,60)">
+      <circle cx="200" cy="114.8" r="2" style="fill:red"/>
+      <text x="200" y="114.8" style="text-anchor:middle">sit amet, consectetur</text>
+    </g>
+    <g transform="translate(0,120)">
+      <circle cx="200" cy="114.8" r="2" style="fill:red"/>
+      <text x="200" y="114.8" style="text-anchor:end">adipisicing elit,</text>
+    </g>
+  </g>
+
+  <g id="test-body-content" style="font-size:16px">
+      <text>
+        <tspan x="200" y="114.8" style="text-anchor:start">Lorem ipsum dolor</tspan>
+        <tspan x="200" y="174.8" style="text-anchor:middle">sit amet, consectetur</tspan>
+        <tspan x="200" y="234.8" style="text-anchor:end">adipisicing elit,</tspan>
+      </text>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-202-ref.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-202-ref.svg
new file mode 100644
index 0000000..72a8ee1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-202-ref.svg
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 202</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <g id="test-body-reference" style="font-size:16px;writing-mode:tb-rl">
+    <g transform="translate(0,0)">
+      <text x="140" y="200">Lorem ipsum dolor</text>
+    </g>
+    <g transform="translate(80,0)">
+      <text x="140" y="200" style="text-anchor:middle">sit amet, consectetur</text>
+    </g>
+    <g transform="translate(160,0)">
+      <text x="140" y="200" style="text-anchor:end">adipisicing elit,</text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-202.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-202.svg
new file mode 100644
index 0000000..79792ed
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-202.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 202</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+    <html:link rel="help"
+          href="https://svgwg.org/svg2-draft/text.html#TextAnchoringProperties"/>
+    <html:link rel="match"  href="text-text-anchor-202-ref.svg" />
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <!-- TEMP -->
+  <g id="test-body-reference" style="font-size:16px;writing-mode:tb-rl;fill:red">
+    <g transform="translate(0,0)">
+      <circle cx="140" cy="200" r="2" style="fill:red"/>
+      <text x="140" y="200">Lorem ipsum dolor</text>
+    </g>
+    <g transform="translate(80,0)">
+      <circle cx="140" cy="200" r="2" style="fill:red"/>
+      <text x="140" y="200" style="text-anchor:middle">sit amet, consectetur</text>
+    </g>
+    <g transform="translate(160,0)">
+      <circle cx="140" cy="200" r="2" style="fill:red"/>
+      <text x="140" y="200" style="text-anchor:end">adipisicing elit,</text>
+    </g>
+  </g>
+
+  <g id="test-body-content" style="font-size:16px;writing-mode:tb-rl">
+      <text>
+        <tspan x="140" y="200" style="text-anchor:start">Lorem ipsum dolor</tspan>
+        <tspan x="220" y="200" style="text-anchor:middle">sit amet, consectetur</tspan>
+        <tspan x="300" y="200" style="text-anchor:end">adipisicing elit,</tspan>
+      </text>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-203-ref.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-203-ref.svg
new file mode 100644
index 0000000..7ee99a2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-203-ref.svg
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 203</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <g id="test-body-reference" style="font-size:16px">
+    <g transform="translate(0,0)">
+      <text style="text-anchor:end">
+        <tspan x="200" y="114.8">لكن لا بد أن</tspan>
+      </text>
+    </g>
+    <g transform="translate(0,60)">
+      <text style="text-anchor:middle">
+        <tspan x="200" y="114.8" style="text-anchor:middle">أوضح لك أن</tspan>
+      </text>
+    </g>
+    <g transform="translate(0,120)">
+      <text>
+        <tspan x="200" y="114.8" style="text-anchor:start">كل هذه الأفكار</tspan>
+      </text>
+    </g>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-203.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-203.svg
new file mode 100644
index 0000000..bb7c8206
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-text-anchor-203.svg
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:html="http://www.w3.org/1999/xhtml">
+  <g id="testmeta">
+    <title>Text: Text Anchor — 203</title>
+    <html:link rel="author"
+          title="Tavmjong Bah"
+          href="mailto:tavmjong@free.fr"/>
+    <html:link rel="help"
+          href="https://svgwg.org/svg2-draft/text.html#TextAnchoringProperties"/>
+    <html:link rel="match"  href="text-text-anchor-003-ref.svg" />
+  </g>
+
+  <style id="test-font" type="text/css">
+    /* Standard Font (if needed). */
+    @font-face {
+      font-family: FreeSans;
+      src: url("fonts/FreeSans.woff") format("woff"),
+           local("FreeSans");
+    }
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <style id="test-style" type="text/css">
+    /* Style that is being tested (if needed). */
+    text { font-family: FreeSans, sans-serif }
+  </style>
+
+  <!-- TEMP -->
+  <g id="test-body-reference" style="font-size:16px;fill:red">
+    <g transform="translate(0,0)">
+      <circle cx="200" cy="114.8" r="2" style="fill:red"/>
+      <text style="text-anchor:end">
+        <tspan x="200" y="114.8">لكن لا بد أن</tspan>
+      </text>
+    </g>
+    <g transform="translate(0,60)">
+      <circle cx="200" cy="114.8" r="2" style="fill:red"/>
+      <text style="text-anchor:middle">
+        <tspan x="200" y="114.8" style="text-anchor:middle">أوضح لك أن</tspan>
+      </text>
+    </g>
+    <g transform="translate(0,120)">
+      <circle cx="200" cy="114.8" r="2" style="fill:red"/>
+      <text>
+        <tspan x="200" y="114.8" style="text-anchor:start">كل هذه الأفكار</tspan>
+      </text>
+    </g>
+  </g>
+
+  <g id="test-body-content" style="font-size:16px;direction:rtl">
+    <text>
+      <tspan x="200" y="114.8" style="text-anchor:start">لكن لا بد أن</tspan>
+      <tspan x="200" y="174.8" style="text-anchor:middle">أوضح لك أن</tspan>
+      <tspan x="200" y="234.8" style="text-anchor:end">كل هذه الأفكار</tspan>
+    </text>
+  </g>
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/azure/affected_tests.yml b/third_party/blink/web_tests/external/wpt/tools/ci/azure/affected_tests.yml
index 8076bc3..17fca51 100644
--- a/third_party/blink/web_tests/external/wpt/tools/ci/azure/affected_tests.yml
+++ b/third_party/blink/web_tests/external/wpt/tools/ci/azure/affected_tests.yml
@@ -16,7 +16,7 @@
 - template: install_safari.yml
 - template: update_hosts.yml
 - template: update_manifest.yml
-- script: no_proxy='*' ./wpt run --yes --no-pause --no-fail-on-unexpected --no-restart-on-unexpected --affected ${{ parameters.affectedRange }} --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report.json --log-wptscreenshot $(Build.ArtifactStagingDirectory)/wpt_screenshot.txt --channel preview safari
+- script: no_proxy='*' ./wpt run --yes --no-pause --no-fail-on-unexpected --no-restart-on-unexpected --affected ${{ parameters.affectedRange }} --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report.json --channel preview safari
   displayName: 'Run tests'
 - task: PublishBuildArtifacts@1
   displayName: 'Publish results'
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/azure/fyi_hook.yml b/third_party/blink/web_tests/external/wpt/tools/ci/azure/fyi_hook.yml
index ddfbe3d..5af16af 100644
--- a/third_party/blink/web_tests/external/wpt/tools/ci/azure/fyi_hook.yml
+++ b/third_party/blink/web_tests/external/wpt/tools/ci/azure/fyi_hook.yml
@@ -12,7 +12,7 @@
   pool:
     vmImage: 'ubuntu-16.04'
   steps:
-  - script: curl -s -S -d "artifact=${{ parameters.artifactName }}" -X POST https://wpt.fyi/api/checks/azure/$(Build.BuildId)
+  - script: curl -f -s -S -d "artifact=${{ parameters.artifactName }}" -X POST https://wpt.fyi/api/checks/azure/$(Build.BuildId)
     displayName: 'Invoke wpt.fyi hook'
-  - script: curl -s -S -d "artifact=${{ parameters.artifactName }}" -X POST https://staging.wpt.fyi/api/checks/azure/$(Build.BuildId)
+  - script: curl -f -s -S -d "artifact=${{ parameters.artifactName }}" -X POST https://staging.wpt.fyi/api/checks/azure/$(Build.BuildId)
     displayName: 'Invoke staging.wpt.fyi hook'
diff --git a/third_party/blink/web_tests/external/wpt/tools/manifest/manifest.py b/third_party/blink/web_tests/external/wpt/tools/manifest/manifest.py
index dc57c24d..e2e35d7 100644
--- a/third_party/blink/web_tests/external/wpt/tools/manifest/manifest.py
+++ b/third_party/blink/web_tests/external/wpt/tools/manifest/manifest.py
@@ -162,6 +162,21 @@
         self.tests_root = tests_root
         self.json_data = data
 
+    def to_json(self):
+        data = {
+            from_os_path(path):
+            [t for t in sorted(test.to_json() for test in tests)]
+            for path, tests in iteritems(self.data)
+        }
+
+        if self.json_data is not None:
+            if not data:
+                # avoid copying if there's nothing here yet
+                return self.json_data
+            data.update(self.json_data)
+
+        return data
+
     def paths(self):
         """Get a list of all paths containing items of this type,
         without actually constructing all the items"""
@@ -363,11 +378,7 @@
 
     def to_json(self):
         out_items = {
-            test_type: {
-                from_os_path(path):
-                [t for t in sorted(test.to_json() for test in tests)]
-                for path, tests in iteritems(type_paths)
-            }
+            test_type: type_paths.to_json()
             for test_type, type_paths in iteritems(self._data) if type_paths
         }
         rv = {"url_base": self.url_base,
diff --git a/third_party/blink/web_tests/external/wpt/tools/manifest/vcs.py b/third_party/blink/web_tests/external/wpt/tools/manifest/vcs.py
index ecd565c..676e53f6 100644
--- a/third_party/blink/web_tests/external/wpt/tools/manifest/vcs.py
+++ b/third_party/blink/web_tests/external/wpt/tools/manifest/vcs.py
@@ -69,25 +69,23 @@
                        manifest_path=manifest_path, rebuild=rebuild)
 
     def _local_changes(self):
-        changes = {}
+        """get a set of files which have changed between HEAD and working copy"""
+        changes = set()
+
         cmd = ["status", "-z", "--ignore-submodules=all"]
         data = self.git(*cmd)
 
-        if data == "":
-            return changes
-
-        rename_data = None
-        for entry in data.split("\0")[:-1]:
-            if rename_data is not None:
-                status, rel_path = entry.split(" ")
-                if status[0] == "R":
-                    rename_data = (rel_path, status)
-                else:
-                    changes[rel_path] = (status, None)
+        in_rename = False
+        for line in data.split(b"\0")[:-1]:
+            if in_rename:
+                changes.add(line)
+                in_rename = False
             else:
-                rel_path = entry
-                changes[rel_path] = rename_data
-                rename_data = None
+                status = line[:2]
+                if b"R" in status or b"C" in status:
+                    in_rename = True
+                changes.add(line[3:])
+
         return changes
 
     def _show_file(self, path):
@@ -98,8 +96,8 @@
         cmd = ["ls-tree", "-r", "-z", "HEAD"]
         local_changes = self._local_changes()
         for result in self.git(*cmd).split("\0")[:-1]:
-            rel_path = result.split("\t")[-1]
-            hash = result.split()[2]
+            data, rel_path = result.rsplit("\t", 1)
+            hash = data.split(" ", 3)[2]
             if rel_path in local_changes:
                 contents = self._show_file(rel_path)
             else:
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/run.py b/third_party/blink/web_tests/external/wpt/tools/wpt/run.py
index a19851d1..ea4bd1c 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wpt/run.py
+++ b/third_party/blink/web_tests/external/wpt/tools/wpt/run.py
@@ -284,6 +284,9 @@
         # Allow WebRTC tests to call getUserMedia.
         kwargs["binary_args"] += ["--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream"]
 
+        # Shorten delay for Reporting <https://w3c.github.io/reporting/>.
+        kwargs["binary_args"].append("--short-reporting-delay")
+
 
 class ChromeAndroid(BrowserSetup):
     name = "chrome_android"
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/chromium.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/chromium.py
new file mode 100644
index 0000000..f54f23e5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/chromium.py
@@ -0,0 +1,97 @@
+import json
+import time
+
+from collections import defaultdict
+from mozlog.formatters import base
+
+
+class ChromiumFormatter(base.BaseFormatter):
+    """Formatter to produce results matching the Chromium JSON Test Results format.
+    https://chromium.googlesource.com/chromium/src/+/master/docs/testing/json_test_results_format.md
+    """
+
+    def __init__(self):
+        # Whether the run was interrupted, either by the test runner or user.
+        self.interrupted = False
+
+        # A map of test status to the number of tests that had that status.
+        self.num_failures_by_status = defaultdict(int)
+
+        # Start time, expressed as offset since UNIX epoch in seconds.
+        self.start_timestamp_seconds = None
+
+        # Trie of test results. Each directory in the test name is a node in
+        # the trie and the leaf contains the dict of per-test data.
+        self.tests = {}
+
+    def _store_test_result(self, name, actual, expected):
+        """
+        Stores the result of a single test in |self.tests|
+        :param str name: name of the test.
+        :param str actual: actual status of the test.
+        :param str expected: expected status of the test.
+        """
+        # The test name can contain a leading / which will produce an empty
+        # string in the first position of the list returned by split. We use
+        # filter(None) to remove such entries.
+        name_parts = filter(None, name.split("/"))
+        cur_dict = self.tests
+        for name_part in name_parts:
+            cur_dict = cur_dict.setdefault(name_part, {})
+        cur_dict["actual"] = actual
+        cur_dict["expected"] = expected
+
+    def _map_status_name(self, status):
+        """
+        Maps a WPT status to a Chromium status.
+
+        Chromium has five main statuses that we have to map to:
+        CRASH: the test harness crashed
+        FAIL: the test did not run as expected
+        PASS: the test ran as expected
+        SKIP: the test was not run
+        TIMEOUT: the did not finish in time and was aborted
+
+        :param str status: the string status of a test from WPT
+        :return: a corresponding string status for Chromium
+        """
+        if status == "OK":
+            return "PASS"
+        if status == "NOTRUN":
+            return "SKIP"
+        if status == "EXTERNAL-TIMEOUT":
+            return "TIMEOUT"
+        if status in ("ERROR", "CRASH"):
+            # CRASH in WPT means a browser crash, which Chromium treats as a
+            # test failure.
+            return "FAIL"
+        if status == "INTERNAL-ERROR":
+            # CRASH in Chromium refers to an error in the test runner not the
+            # browser.
+            return "CRASH"
+        # Any other status just gets returned as-is.
+        return status
+
+    def suite_start(self, data):
+        self.start_timestamp_seconds = data["time"] if "time" in data else time.time()
+
+    def test_end(self, data):
+        actual_status = self._map_status_name(data["status"])
+        expected_status = self._map_status_name(data["expected"]) if "expected" in data else "PASS"
+        self._store_test_result(data["test"], actual_status, expected_status)
+
+        # Update the count of how many tests ran with each status.
+        self.num_failures_by_status[actual_status] += 1
+
+    def suite_end(self, data):
+        # Create the final result dictionary
+        final_result = {
+            # There are some required fields that we just hard-code.
+            "interrupted": False,
+            "path_delimeter": "/",
+            "version": 3,
+            "seconds_since_epoch": self.start_timestamp_seconds,
+            "num_failures_by_type": self.num_failures_by_status,
+            "tests": self.tests
+        }
+        return json.dumps(final_result)
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py
new file mode 100644
index 0000000..a6e6c2e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py
@@ -0,0 +1,118 @@
+import json
+import sys
+from os.path import dirname, join
+from StringIO import StringIO
+
+from mozlog import handlers, structuredlog
+
+sys.path.insert(0, join(dirname(__file__), "..", ".."))
+from formatters import chromium
+
+
+def test_chromium_required_fields(capfd):
+    # Test that the test results contain a handful of required fields.
+
+    # Set up the handler.
+    output = StringIO()
+    logger = structuredlog.StructuredLogger("test_a")
+    logger.add_handler(handlers.StreamHandler(output, chromium.ChromiumFormatter()))
+
+    # output a bunch of stuff
+    logger.suite_start(["test-id-1"], run_info={}, time=123)
+    logger.test_start("test-id-1")
+    logger.test_end("test-id-1", status="PASS", expected="PASS")
+    logger.suite_end()
+
+    # check nothing got output to stdout/stderr
+    # (note that mozlog outputs exceptions during handling to stderr!)
+    captured = capfd.readouterr()
+    assert captured.out == ""
+    assert captured.err == ""
+
+    # check the actual output of the formatter
+    output.seek(0)
+    output_obj = json.load(output)
+
+    # Check for existence of required fields
+    assert "interrupted" in output_obj
+    assert "path_delimeter" in output_obj
+    assert "version" in output_obj
+    assert "num_failures_by_type" in output_obj
+    assert "tests" in output_obj
+
+    test_obj = output_obj["tests"]["test-id-1"]
+    assert "actual" in test_obj
+    assert "expected" in test_obj
+
+def test_chromium_test_name_trie(capfd):
+    # Ensure test names are broken into directories and stored in a trie with
+    # test results at the leaves.
+
+    # Set up the handler.
+    output = StringIO()
+    logger = structuredlog.StructuredLogger("test_a")
+    logger.add_handler(handlers.StreamHandler(output, chromium.ChromiumFormatter()))
+
+    # output a bunch of stuff
+    logger.suite_start(["/foo/bar/test-id-1", "/foo/test-id-2"], run_info={}, time=123)
+    logger.test_start("/foo/bar/test-id-1")
+    logger.test_end("/foo/bar/test-id-1", status="TIMEOUT", expected="FAIL")
+    logger.test_start("/foo/test-id-2")
+    logger.test_end("/foo/test-id-2", status="ERROR", expected="TIMEOUT")
+    logger.suite_end()
+
+    # check nothing got output to stdout/stderr
+    # (note that mozlog outputs exceptions during handling to stderr!)
+    captured = capfd.readouterr()
+    assert captured.out == ""
+    assert captured.err == ""
+
+    # check the actual output of the formatter
+    output.seek(0)
+    output_obj = json.load(output)
+
+    # Ensure that the test names are broken up by directory name and that the
+    # results are stored at the leaves.
+    test_obj = output_obj["tests"]["foo"]["bar"]["test-id-1"]
+    assert test_obj["actual"] == "TIMEOUT"
+    assert test_obj["expected"] == "FAIL"
+
+    test_obj = output_obj["tests"]["foo"]["test-id-2"]
+    # The ERROR status is mapped to FAIL for Chromium
+    assert test_obj["actual"] == "FAIL"
+    assert test_obj["expected"] == "TIMEOUT"
+
+def test_num_failures_by_type(capfd):
+    # Test that the number of failures by status type is correctly calculated.
+
+    # Set up the handler.
+    output = StringIO()
+    logger = structuredlog.StructuredLogger("test_a")
+    logger.add_handler(handlers.StreamHandler(output, chromium.ChromiumFormatter()))
+
+    # Run some tests with different statuses: 3 passes, 1 timeout
+    logger.suite_start(["t1", "t2", "t3", "t4"], run_info={}, time=123)
+    logger.test_start("t1")
+    logger.test_end("t1", status="PASS", expected="PASS")
+    logger.test_start("t2")
+    logger.test_end("t2", status="PASS", expected="PASS")
+    logger.test_start("t3")
+    logger.test_end("t3", status="PASS", expected="FAIL")
+    logger.test_start("t4")
+    logger.test_end("t4", status="TIMEOUT", expected="CRASH")
+    logger.suite_end()
+
+    # check nothing got output to stdout/stderr
+    # (note that mozlog outputs exceptions during handling to stderr!)
+    captured = capfd.readouterr()
+    assert captured.out == ""
+    assert captured.err == ""
+
+    # check the actual output of the formatter
+    output.seek(0)
+    num_failures_by_type = json.load(output)["num_failures_by_type"]
+
+    # We expect 3 passes and 1 timeout, nothing else.
+    assert sorted(num_failures_by_type.keys()) == ["PASS", "TIMEOUT"]
+    assert num_failures_by_type["PASS"] == 3
+    assert num_failures_by_type["TIMEOUT"] == 1
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/testharness_runner.html b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/testharness_runner.html
new file mode 100644
index 0000000..1cc80a2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/testharness_runner.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<title></title>
+<script>
+var timeout_multiplier = 1;
+var win = null;
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py
index eb61461..0b5dc82 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py
@@ -8,8 +8,7 @@
 
 import config
 import wpttest
-from formatters import wptreport, wptscreenshot
-
+from formatters import chromium, wptreport, wptscreenshot
 
 def abs_path(path):
     return os.path.abspath(os.path.expanduser(path))
@@ -326,6 +325,7 @@
                         help="List of URLs for tests to run, or paths including tests to run. "
                              "(equivalent to --include)")
 
+    commandline.log_formatters["chromium"] = (chromium.ChromiumFormatter, "Chromium Layout Tests format")
     commandline.log_formatters["wptreport"] = (wptreport.WptreportFormatter, "wptreport format")
     commandline.log_formatters["wptscreenshot"] = (wptscreenshot.WptscreenshotFormatter, "wpt.fyi screenshots")
 
diff --git a/third_party/blink/web_tests/external/wpt/touch-events/idlharness.window-expected.txt b/third_party/blink/web_tests/external/wpt/touch-events/idlharness.window-expected.txt
index 6105362..10ad290 100644
--- a/third_party/blink/web_tests/external/wpt/touch-events/idlharness.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/touch-events/idlharness.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
 FAIL idl_test setup promise_test: Unhandled rejection with value: "Document includes GlobalEventHandlers, but Document is undefined."
-PASS Partial interface GlobalEventHandlers: original interface defined
+PASS Partial interface mixin GlobalEventHandlers: original interface mixin defined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/wasm/webapi/instantiateStreaming.any.js b/third_party/blink/web_tests/external/wpt/wasm/webapi/instantiateStreaming.any.js
index 224b0a3..daec185 100644
--- a/third_party/blink/web_tests/external/wpt/wasm/webapi/instantiateStreaming.any.js
+++ b/third_party/blink/web_tests/external/wpt/wasm/webapi/instantiateStreaming.any.js
@@ -18,3 +18,33 @@
     verify(result.instance);
   }, name);
 }
+
+promise_test(async () => {
+  const builder = new WasmModuleBuilder();
+  builder.addImportedGlobal("module", "global", kWasmI32);
+  const buffer = builder.toBuffer();
+  const response = new Response(buffer, { "headers": { "Content-Type": "application/wasm" } });
+  const order = [];
+
+  const imports = {
+    get module() {
+      order.push("module getter");
+      return {
+        get global() {
+          order.push("global getter");
+          return 0;
+        },
+      }
+    },
+  };
+
+  const expected = [
+    "module getter",
+    "global getter",
+  ];
+  const p = WebAssembly.instantiateStreaming(response, imports);
+  assert_array_equals(order, []);
+  const result = await p;
+  assert_WebAssemblyInstantiatedSource(result, {});
+  assert_array_equals(order, expected);
+}, "Synchronous options handling");
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html
index 4e9568f..59761c4 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html
@@ -27,8 +27,6 @@
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     caller.addTrack(localStream.getTracks()[0]);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
-      assert_equals(e.track.id, localStream.getTracks()[0].id,
-                    'Local and remote track IDs match.');
       assert_equals(e.streams.length, 0, 'No remote stream created.');
     });
     await exchangeOffer(caller, callee);
@@ -45,8 +43,6 @@
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     caller.addTrack(localStream.getTracks()[0], localStream);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
-      assert_equals(e.track.id, localStream.getTracks()[0].id,
-                    'Local and remote track IDs match.');
       assert_equals(e.streams.length, 1, 'Created a single remote stream.');
       assert_equals(e.streams[0].id, localStream.id,
                     'Local and remote stream IDs match.');
@@ -96,18 +92,12 @@
     });
     await exchangeOffer(caller, callee);
     let firstTrackEvent = await ontrackEventResolvers[0];
-    assert_equals(firstTrackEvent.track.id,
-                  localStreams[0].getTracks()[0].id,
-                  'First ontrack\'s track ID matches first local track.');
     assert_equals(firstTrackEvent.streams.length, 1,
                   'First ontrack fires with a single stream.');
     assert_equals(firstTrackEvent.streams[0].id,
                   localStreams[0].id,
                   'First ontrack\'s stream ID matches local stream.');
     let secondTrackEvent = await ontrackEventResolvers[1];
-    assert_equals(secondTrackEvent.track.id,
-                  localStreams[1].getTracks()[0].id,
-                  'Second ontrack\'s track ID matches second local track.');
     assert_equals(secondTrackEvent.streams.length, 1,
                   'Second ontrack fires with a single stream.');
     assert_equals(secondTrackEvent.streams[0].id,
@@ -145,17 +135,16 @@
     exchangeIceCandidates(caller, callee);
     await exchangeOfferAnswer(caller, callee);
     assert_equals(remoteStreams.length, 1, 'One remote stream created.');
-    assert_equals(remoteStreams[0].getTracks()[0].id,
-                  localStreams[0].getTracks()[0].id,
-                  'First local and remote tracks have the same ID.');
-    const onaddtrackPromise =
-        addEventListenerPromise(t, remoteStreams[0], 'addtrack', e => {
-      assert_equals(e.track.id, localStreams[1].getTracks()[0].id,
-                    'Second local and remote tracks have the same ID.');
-    });
+    assert_equals(remoteStreams[0].id, localStreams[0].id,
+                  'First local and remote streams have the same ID.');
+    const firstRemoteTrack = remoteStreams[0].getTracks()[0];
+    const onaddtrackPromise = addEventListenerPromise(t, remoteStreams[0], 'addtrack');
     caller.addTrack(localStreams[1].getTracks()[0], localStreams[0]);
     await exchangeOffer(caller, callee);
-    await onaddtrackPromise;
+    const e = await onaddtrackPromise;
+    assert_equals(remoteStreams[0].getTracks().length, 2, 'stream has two tracks');
+    assert_not_equals(e.track.id, firstRemoteTrack.id,
+                      'addtrack event has a new track');
     assert_equals(remoteStreams.length, 1, 'Still a single remote stream.');
   }, 'addTrack() for an existing stream makes stream.onaddtrack fire.');
 
@@ -206,8 +195,6 @@
     caller.addTrack(localStreams[0].getTracks()[0],
                     localStreams[0], localStreams[1]);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
-      assert_equals(e.track.id, localStreams[0].getTracks()[0].id,
-                    'Local and remote track IDs match.');
       assert_equals(e.streams.length, 2, 'Two remote stream created.');
       assert_array_equals(e.streams[0].getTracks(), [e.track],
                           'First remote stream == [remote track].');
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html
index 8004fec..b5f3c55e 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html
@@ -543,7 +543,7 @@
     const stream = await getNoiseStream({audio: true});
     t.add_cleanup(() => stopTracks(stream));
     const track = stream.getAudioTracks()[0];
-    pc2.getTransceivers()[0].sender.replaceTrack(track);
+    await pc2.getTransceivers()[0].sender.replaceTrack(track);
 
     const offer = await pc1.createOffer();
     const trackEvents = await setRemoteDescriptionReturnTrackEvents(pc2, offer);
@@ -630,7 +630,7 @@
     t.add_cleanup(() => stopTracks(stream));
     const track = stream.getAudioTracks()[0];
     pc2.addTrack(track, stream);
-    pc2.getTransceivers()[0].sender.replaceTrack(null);
+    await pc2.getTransceivers()[0].sender.replaceTrack(null);
 
     const offer = await pc1.createOffer();
     const trackEvents = await setRemoteDescriptionReturnTrackEvents(pc2, offer);
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt
index 3910ac5..be57dd0e 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 494 tests; 412 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 506 tests; 421 PASS, 85 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS Test driver for asyncInitCertificate
 PASS Test driver for asyncInitTransports
@@ -27,7 +27,7 @@
 PASS RTCPeerConnection interface: attribute remoteDescription
 PASS RTCPeerConnection interface: attribute currentRemoteDescription
 PASS RTCPeerConnection interface: attribute pendingRemoteDescription
-PASS RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit)
+FAIL RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit) assert_equals: property has wrong .length expected 0 but got 1
 PASS RTCPeerConnection interface: attribute signalingState
 PASS RTCPeerConnection interface: attribute iceGatheringState
 PASS RTCPeerConnection interface: attribute iceConnectionState
@@ -48,7 +48,7 @@
 PASS RTCPeerConnection interface: operation setLocalDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback)
 PASS RTCPeerConnection interface: operation createAnswer(RTCSessionDescriptionCallback, RTCPeerConnectionErrorCallback)
 PASS RTCPeerConnection interface: operation setRemoteDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback)
-PASS RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit, VoidFunction, RTCPeerConnectionErrorCallback)
+FAIL RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit, VoidFunction, RTCPeerConnectionErrorCallback) assert_equals: property has wrong .length expected 0 but got 1
 PASS RTCPeerConnection interface: operation generateCertificate(AlgorithmIdentifier)
 PASS RTCPeerConnection interface: operation getSenders()
 PASS RTCPeerConnection interface: operation getReceivers()
@@ -492,8 +492,20 @@
 FAIL RTCStatsEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "RTCStatsEvent" expected property "RTCStatsEvent" missing
 FAIL RTCStatsEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "RTCStatsEvent" expected property "RTCStatsEvent" missing
 FAIL RTCStatsEvent interface: attribute report assert_own_property: self does not have own property "RTCStatsEvent" expected property "RTCStatsEvent" missing
+FAIL RTCError interface: existence and properties of interface object assert_equals: prototype of self's property "RTCError" is not Function.prototype expected function "function () { [native code] }" but got function "function DOMException() { [native code] }"
+PASS RTCError interface object length
+PASS RTCError interface object name
+FAIL RTCError interface: existence and properties of interface prototype object assert_equals: prototype of RTCError.prototype is not Object.prototype expected object "[object Object]" but got [stringifying object threw TypeError: Illegal invocation with type object]
+PASS RTCError interface: existence and properties of interface prototype object's "constructor" property
+PASS RTCError interface: existence and properties of interface prototype object's @@unscopables property
+PASS RTCError interface: attribute errorDetail
+PASS RTCError interface: attribute sdpLineNumber
+PASS RTCError interface: attribute httpRequestStatusCode
+PASS RTCError interface: attribute sctpCauseCode
+PASS RTCError interface: attribute receivedAlert
+PASS RTCError interface: attribute sentAlert
 PASS RTCErrorEvent interface: existence and properties of interface object
-FAIL RTCErrorEvent interface object length assert_equals: wrong value for RTCErrorEvent.length expected 1 but got 2
+PASS RTCErrorEvent interface object length
 PASS RTCErrorEvent interface object name
 PASS RTCErrorEvent interface: existence and properties of interface prototype object
 PASS RTCErrorEvent interface: existence and properties of interface prototype object's "constructor" property
diff --git a/third_party/blink/web_tests/external/wpt/xhr/resources/auth10/auth.py b/third_party/blink/web_tests/external/wpt/xhr/resources/auth10/auth.py
new file mode 100644
index 0000000..8b66826
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/xhr/resources/auth10/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+    auth = imp.load_source("", os.path.join(here,
+                                            "..",
+                                            "authentication.py"))
+    return auth.main(request, response)
diff --git a/third_party/blink/web_tests/external/wpt/xhr/resources/auth11/auth.py b/third_party/blink/web_tests/external/wpt/xhr/resources/auth11/auth.py
new file mode 100644
index 0000000..8b66826
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/xhr/resources/auth11/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+    auth = imp.load_source("", os.path.join(here,
+                                            "..",
+                                            "authentication.py"))
+    return auth.main(request, response)
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-authentication-basic-cors-not-enabled.htm b/third_party/blink/web_tests/external/wpt/xhr/send-authentication-basic-cors-not-enabled.htm
index 070b2ba32..68ad5e9 100644
--- a/third_party/blink/web_tests/external/wpt/xhr/send-authentication-basic-cors-not-enabled.htm
+++ b/third_party/blink/web_tests/external/wpt/xhr/send-authentication-basic-cors-not-enabled.htm
@@ -16,7 +16,7 @@
           urlstart = 'www1.'+location.host + location.pathname.replace(/\/[^\/]*$/, '/')
         client.withCredentials = true
         user = token()
-        client.open("GET", location.protocol+'//'+urlstart + "resources/auth1/auth.py", false, user, 'pass')
+        client.open("GET", location.protocol+'//'+urlstart + "resources/auth10/auth.py", false, user, 'pass')
         client.setRequestHeader("x-user", user)
         assert_throws("NetworkError", function(){ client.send(null) })
         assert_equals(client.responseText, '')
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-authentication-basic-repeat-no-args.htm b/third_party/blink/web_tests/external/wpt/xhr/send-authentication-basic-repeat-no-args.htm
index 464d69c..38f1b2070 100644
--- a/third_party/blink/web_tests/external/wpt/xhr/send-authentication-basic-repeat-no-args.htm
+++ b/third_party/blink/web_tests/external/wpt/xhr/send-authentication-basic-repeat-no-args.htm
@@ -15,12 +15,12 @@
         var client = new XMLHttpRequest(),
           urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
           user = token()
-        client.open("GET", location.protocol+'//'+urlstart + "resources/auth1/auth.py", false, user, 'pass')
+        client.open("GET", location.protocol+'//'+urlstart + "resources/auth11/auth.py", false, user, 'pass')
         client.setRequestHeader("x-user", user)
         client.send(null)
         // Repeat request but *without* credentials in the open() call.
         // Is the UA supposed to cache credentials from above request and use them? Yes.
-        client.open("GET", location.protocol+'//'+urlstart + "resources/auth1/auth.py", false)
+        client.open("GET", location.protocol+'//'+urlstart + "resources/auth11/auth.py", false)
         client.setRequestHeader("x-user", user)
         client.send(null)
 
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybuffer.any.js b/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybuffer.any.js
new file mode 100644
index 0000000..71933d0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybuffer.any.js
@@ -0,0 +1,31 @@
+// META: title=XMLHttpRequest.send(arraybuffer)
+
+var test = async_test();
+test.step(function()
+{
+    var xhr = new XMLHttpRequest();
+    var buf = new ArrayBuffer(5);
+    var arr = new Uint8Array(buf);
+    arr[0] = 0x48;
+    arr[1] = 0x65;
+    arr[2] = 0x6c;
+    arr[3] = 0x6c;
+    arr[4] = 0x6f;
+
+    xhr.onreadystatechange = function()
+    {
+        if (xhr.readyState == 4)
+        {
+            test.step(function()
+            {
+                assert_equals(xhr.status, 200);
+                assert_equals(xhr.response, "Hello");
+
+                test.done();
+            });
+        }
+    };
+
+    xhr.open("POST", "./resources/content.py", true);
+    xhr.send(buf);
+});
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybuffer.htm b/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybuffer.htm
deleted file mode 100644
index 25c5d240..0000000
--- a/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybuffer.htm
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method"  data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[4]/dl[1]/dd[1]"/>
-    <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute"  data-tested-assertations="following::ol[1]/li[3]"/>
-    <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute"  data-tested-assertations="following::ol[1]/li[3]"/>
-    <script src="/resources/testharness.js"></script>
-    <script src="/resources/testharnessreport.js"></script>
-    <title>XMLHttpRequest: The send() method: ArrayBuffer data</title>
-</head>
-
-<body>
-    <div id="log"></div>
-
-    <script type="text/javascript">
-        var test = async_test();
-
-        test.step(function()
-        {
-            var xhr = new XMLHttpRequest();
-            var buf = new ArrayBuffer(5);
-            var arr = new Uint8Array(buf);
-            arr[0] = 0x48;
-            arr[1] = 0x65;
-            arr[2] = 0x6c;
-            arr[3] = 0x6c;
-            arr[4] = 0x6f;
-
-            xhr.onreadystatechange = function()
-            {
-                if (xhr.readyState == 4)
-                {
-                    test.step(function()
-                    {
-                        assert_equals(xhr.status, 200);
-                        assert_equals(xhr.response, "Hello");
-
-                        test.done();
-                    });
-                }
-            };
-
-            xhr.open("POST", "./resources/content.py", true);
-            xhr.send(buf);
-        });
-    </script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybufferview.any.js b/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybufferview.any.js
new file mode 100644
index 0000000..a3985b4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybufferview.any.js
@@ -0,0 +1,18 @@
+// META: title=XMLHttpRequest.send(arraybufferview)
+
+var test = async_test();
+test.step(function()
+{
+    var str = "Hello";
+    var bytes = str.split("").map(function(ch) { return ch.charCodeAt(0); });
+    var xhr = new XMLHttpRequest();
+    var arr = new Uint8Array(bytes);
+
+    xhr.onload = test.step_func_done(function() {
+        assert_equals(xhr.status, 200);
+        assert_equals(xhr.response, str);
+    });
+
+    xhr.open("POST", "./resources/content.py", true);
+    xhr.send(arr);
+});
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybufferview.htm b/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybufferview.htm
deleted file mode 100644
index 4de7e9e8..0000000
--- a/third_party/blink/web_tests/external/wpt/xhr/send-data-arraybufferview.htm
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method"  data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[4]/dl[1]/dd[1]"/>
-    <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute"  data-tested-assertations="following::ol[1]/li[3]"/>
-    <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute"  data-tested-assertations="following::ol[1]/li[3]"/>
-    <script src="/resources/testharness.js"></script>
-    <script src="/resources/testharnessreport.js"></script>
-    <title>XMLHttpRequest: The send() method: ArrayBufferView data</title>
-    <link rel="author" title="Ondrej Zara" href="mailto:ondrej.zara@gmail.com">
-</head>
-
-<body>
-    <div id="log"></div>
-
-    <script type="text/javascript">
-        var test = async_test();
-
-        test.step(function()
-        {
-            var str = "Hello";
-            var bytes = str.split("").map(function(ch) { return ch.charCodeAt(0); });
-            var xhr = new XMLHttpRequest();
-            var arr = new Uint8Array(bytes);
-
-            xhr.onload = test.step_func_done(function() {
-                assert_equals(xhr.status, 200);
-                assert_equals(xhr.response, str);
-            });
-
-            xhr.open("POST", "./resources/content.py", true);
-            xhr.send(arr);
-        });
-    </script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-data-es-object.any.js b/third_party/blink/web_tests/external/wpt/xhr/send-data-es-object.any.js
new file mode 100644
index 0000000..d98a4ca
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/xhr/send-data-es-object.any.js
@@ -0,0 +1,50 @@
+// META: title=XMLHttpRequest.send(ES object)
+
+function do_test(obj, expected, name) {
+  var test = async_test(name)
+  test.step(function() {
+    var client = new XMLHttpRequest()
+    client.onload = test.step_func(function () {
+      assert_equals(client.responseText, expected)
+      test.done()
+    });
+    client.open('POST', 'resources/content.py')
+    if (expected.exception) {
+      assert_throws(expected.exception, function(){client.send(obj)})
+      test.done()
+    } else {
+      client.send(obj)
+    }
+  });
+}
+
+do_test({}, '[object Object]', 'sending a plain empty object')
+do_test(Math, '[object Math]', 'sending the ES Math object')
+do_test(new XMLHttpRequest, '[object XMLHttpRequest]', 'sending a new XHR instance')
+do_test({toString:function(){}}, 'undefined', 'sending object that stringifies to undefined')
+do_test({toString:function(){return null}}, 'null', 'sending object that stringifies to null')
+var ancestor = {toString: function(){
+  var ar=[]
+  for (var prop in this) {
+    if (this.hasOwnProperty(prop)) {
+      ar.push(prop+'='+this[prop])
+    }
+  };
+  return ar.join('&')
+}};
+
+var myObj = Object.create(ancestor, {foo:{value:1, enumerable: true},  bar:{value:'foo', enumerable:true}})
+do_test(myObj, 'foo=1&bar=foo', 'object that stringifies to query string')
+
+var myFakeJSON = {a:'a', b:'b', toString:function(){ return JSON.stringify(this, function(key, val){ return key ==='toString'?undefined:val; }) }}
+do_test(myFakeJSON, '{"a":"a","b":"b"}', 'object that stringifies to JSON string')
+
+var myFakeDoc1 = {valueOf:function(){return document}}
+do_test(myFakeDoc1, '[object Object]', 'object whose valueOf() returns a document - ignore valueOf(), stringify')
+
+var myFakeDoc2 = {toString:function(){return document}}
+var expectedError = self.GLOBAL.isWorker() ? new ReferenceError() : new TypeError();
+do_test(myFakeDoc2, {exception:expectedError}, 'object whose toString() returns a document, expected to throw')
+
+var myThrower = {toString:function(){throw {name:'FooError', message:'bar'}}}
+do_test(myThrower, {exception:{name:'FooError'}}, 'object whose toString() throws, expected to throw')
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-data-es-object.htm b/third_party/blink/web_tests/external/wpt/xhr/send-data-es-object.htm
deleted file mode 100644
index 6f77432..0000000
--- a/third_party/blink/web_tests/external/wpt/xhr/send-data-es-object.htm
+++ /dev/null
@@ -1,61 +0,0 @@
-<!doctype html>
-<meta charset=utf-8>
-<title>XMLHttpRequest: passing objects to send()</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol/li[4]" />
-<link rel="help" href="https://heycam.github.io/webidl/#es-union" data-tested-assertations="following::ol/li[16]" />
-
-<div id="log"></div>
-
-<script>
-  function do_test(obj, expected, name) {
-    var test = async_test(name)
-    test.step(function() {
-      var client = new XMLHttpRequest()
-      client.onload = test.step_func(function () {
-        assert_equals(client.responseText, expected)
-        test.done()
-      });
-      client.open('POST', 'resources/content.py')
-      if (expected.exception) {
-        assert_throws(expected.exception, function(){client.send(obj)})
-        test.done()
-      } else {
-        client.send(obj)
-      }
-    });
-  }
-
-  do_test({}, '[object Object]', 'sending a plain empty object')
-  do_test(Math, '[object Math]', 'sending the ES Math object')
-  do_test(new XMLHttpRequest, '[object XMLHttpRequest]', 'sending a new XHR instance')
-  do_test({toString:function(){}}, 'undefined', 'sending object that stringifies to undefined')
-  do_test({toString:function(){return null}}, 'null', 'sending object that stringifies to null')
-  var ancestor = {toString: function(){
-    var ar=[]
-    for (var prop in this) {
-      if (this.hasOwnProperty(prop)) {
-        ar.push(prop+'='+this[prop])
-      }
-    };
-    return ar.join('&')
-  }};
-
-  var myObj = Object.create(ancestor, {foo:{value:1, enumerable: true},  bar:{value:'foo', enumerable:true}})
-  do_test(myObj, 'foo=1&bar=foo', 'object that stringifies to query string')
-
-  var myFakeJSON = {a:'a', b:'b', toString:function(){ return JSON.stringify(this, function(key, val){ return key ==='toString'?undefined:val; }) }}
-  do_test(myFakeJSON, '{"a":"a","b":"b"}', 'object that stringifies to JSON string')
-
-  var myFakeDoc1 = {valueOf:function(){return document}}
-  do_test(myFakeDoc1, '[object Object]', 'object whose valueOf() returns a document - ignore valueOf(), stringify')
-
-  var myFakeDoc2 = {toString:function(){return document}}
-  do_test(myFakeDoc2, {exception:new TypeError()}, 'object whose toString() returns a document, expected to throw')
-
-  var myThrower = {toString:function(){throw {name:'FooError', message:'bar'}}}
-  do_test(myThrower, {exception:{name:'FooError'}}, 'object whose toString() throws, expected to throw')
-
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-data-formdata.any.js b/third_party/blink/web_tests/external/wpt/xhr/send-data-formdata.any.js
new file mode 100644
index 0000000..6ff04793
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/xhr/send-data-formdata.any.js
@@ -0,0 +1,21 @@
+// META: title=XMLHttpRequest.send(formdata)
+
+var test = async_test();
+test.step(function()
+{
+    var xhr = new XMLHttpRequest();
+    var form = new FormData();
+    form.append("id", "0");
+    form.append("value", "zero");
+
+    xhr.onreadystatechange = test.step_func(() => {
+        if (xhr.readyState == 4) {
+            assert_equals(xhr.status, 200);
+            assert_equals(xhr.response, "id:0;value:zero;");
+            test.done();
+        }
+    });
+
+    xhr.open("POST", "./resources/form.py", true);
+    xhr.send(form);
+});
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-data-formdata.htm b/third_party/blink/web_tests/external/wpt/xhr/send-data-formdata.htm
deleted file mode 100644
index 9456aa7..0000000
--- a/third_party/blink/web_tests/external/wpt/xhr/send-data-formdata.htm
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[4]/dl[1]/dd[5]" />
-    <link rel="help" href="https://xhr.spec.whatwg.org/#interface-formdata" data-tested-assertations="following::*[contains(@id,'dom-formdata')]/following::ol[1]/li[1] following::*[contains(@id,'dom-formdata')]/following::ol[1]/li[3] following::*[contains(@id,'dom-formdata-append')]/following::ul[1]/li[1] following::*[contains(@id,'dom-formdata-append')]/following::ul[1]/li[2]" />
-    <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute"  data-tested-assertations="following::ol[1]/li[3]"/>
-    <script src="/resources/testharness.js"></script>
-    <script src="/resources/testharnessreport.js"></script>
-    <title>XMLHttpRequest: The send() method: FormData data</title>
-</head>
-
-<body>
-    <div id="log"></div>
-
-    <script type="text/javascript">
-        var test = async_test();
-
-        test.step(function()
-        {
-            var xhr = new XMLHttpRequest();
-            var form = new FormData();
-            form.append("id", "0");
-            form.append("value", "zero");
-
-            xhr.onreadystatechange = test.step_func(() => {
-                if (xhr.readyState == 4) {
-                    assert_equals(xhr.status, 200);
-                    assert_equals(xhr.response, "id:0;value:zero;");
-                    test.done();
-                }
-            });
-
-            xhr.open("POST", "./resources/form.py", true);
-            xhr.send(form);
-        });
-    </script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/fast/spatial-navigation/resources/snav-testharness.js b/third_party/blink/web_tests/fast/spatial-navigation/resources/snav-testharness.js
index 93f2016c..4a96db9e 100644
--- a/third_party/blink/web_tests/fast/spatial-navigation/resources/snav-testharness.js
+++ b/third_party/blink/web_tests/fast/spatial-navigation/resources/snav-testharness.js
@@ -102,7 +102,8 @@
         internals.runtimeFlags.focuslessSpatialNavigationEnabled = true;
 
       testRunner.overridePreference("WebKitTabToLinksPreferenceKey", 1);
-      testRunner.overridePreference('WebKitSpatialNavigationEnabled', 1);
+      testRunner.overridePreference("WebKitSpatialNavigationEnabled", 1);
+      testRunner.overridePreference("ScrollAnimatorEnabled", 0);
     },
 
     triggerMove: triggerMove,
diff --git a/third_party/blink/web_tests/fast/spatial-navigation/resources/spatial-navigation-utils.js b/third_party/blink/web_tests/fast/spatial-navigation/resources/spatial-navigation-utils.js
index 16092df..db556907 100644
--- a/third_party/blink/web_tests/fast/spatial-navigation/resources/spatial-navigation-utils.js
+++ b/third_party/blink/web_tests/fast/spatial-navigation/resources/spatial-navigation-utils.js
@@ -22,6 +22,9 @@
   gClosureCallback = completedCb;
   gFocusedDocument = 0;
 
+  if (window.testRunner)
+    testRunner.overridePreference("ScrollAnimatorEnabled", 0);
+
   prepareMove();
 }
 
diff --git a/third_party/blink/web_tests/platform/mac-retina/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/mac-retina/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
rename to third_party/blink/web_tests/platform/linux/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-escape-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-escape-expected.png
new file mode 100644
index 0000000..97fcfafc
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-escape-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-device-emulation-change-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-device-emulation-change-expected.png
new file mode 100644
index 0000000..abbe1ac
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-device-emulation-change-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-device-emulation-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-device-emulation-expected.png
new file mode 100644
index 0000000..abbe1ac
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-device-emulation-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-escape-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-escape-expected.png
index a7f2c56..83ea234 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-escape-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-escape-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-device-emulation-change-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-device-emulation-change-expected.png
index 7660613..1bfe35e 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-device-emulation-change-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-device-emulation-change-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-device-emulation-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-device-emulation-expected.png
index 7660613..1bfe35e 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-device-emulation-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/validation-bubble-device-emulation-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win7/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
rename to third_party/blink/web_tests/platform/mac-mac10.12/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
index 39e546e..b88a5245 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
@@ -12,7 +12,7 @@
 PASS Test that iframe refreshes are not observable by the parent
 PASS Test that crossorigin iframe refreshes are not observable by the parent
 FAIL Test that object navigations are not observable by the parent, even after history navigations by the parent promise_test: Unhandled rejection with value: "FAIL - first document not exposed"
-FAIL Test that crossorigin object navigations are not observable by the parent, even after history navigations by the parent promise_test: Unhandled rejection with value: "FAIL - first document not exposed"
+PASS Test that crossorigin object navigations are not observable by the parent, even after history navigations by the parent
 PASS Test that object navigations are not observable by the parent
 PASS Test that crossorigin object navigations are not observable by the parent
 PASS Test that object refreshes are not observable by the parent
diff --git a/third_party/blink/web_tests/platform/win/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt b/third_party/blink/web_tests/platform/win/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
index b88a5245..39e546e 100644
--- a/third_party/blink/web_tests/platform/win/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
+++ b/third_party/blink/web_tests/platform/win/virtual/omt-worker-fetch/external/wpt/resource-timing/nested-context-navigations-expected.txt
@@ -12,7 +12,7 @@
 PASS Test that iframe refreshes are not observable by the parent
 PASS Test that crossorigin iframe refreshes are not observable by the parent
 FAIL Test that object navigations are not observable by the parent, even after history navigations by the parent promise_test: Unhandled rejection with value: "FAIL - first document not exposed"
-PASS Test that crossorigin object navigations are not observable by the parent, even after history navigations by the parent
+FAIL Test that crossorigin object navigations are not observable by the parent, even after history navigations by the parent promise_test: Unhandled rejection with value: "FAIL - first document not exposed"
 PASS Test that object navigations are not observable by the parent
 PASS Test that crossorigin object navigations are not observable by the parent
 PASS Test that object refreshes are not observable by the parent
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt
index def4c146..3ecee00 100644
--- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 494 tests; 354 PASS, 140 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 506 tests; 363 PASS, 143 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS Test driver for asyncInitCertificate
 FAIL Test driver for asyncInitTransports assert_unreached: Failed to run asyncInitTransports: Error: assert_true: Expect pc.sctp to be instance of RTCSctpTransport expected true got false Reached unreachable code
@@ -27,7 +27,7 @@
 PASS RTCPeerConnection interface: attribute remoteDescription
 PASS RTCPeerConnection interface: attribute currentRemoteDescription
 PASS RTCPeerConnection interface: attribute pendingRemoteDescription
-PASS RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit)
+FAIL RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit) assert_equals: property has wrong .length expected 0 but got 1
 PASS RTCPeerConnection interface: attribute signalingState
 PASS RTCPeerConnection interface: attribute iceGatheringState
 PASS RTCPeerConnection interface: attribute iceConnectionState
@@ -48,7 +48,7 @@
 PASS RTCPeerConnection interface: operation setLocalDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback)
 PASS RTCPeerConnection interface: operation createAnswer(RTCSessionDescriptionCallback, RTCPeerConnectionErrorCallback)
 PASS RTCPeerConnection interface: operation setRemoteDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback)
-PASS RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit, VoidFunction, RTCPeerConnectionErrorCallback)
+FAIL RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit, VoidFunction, RTCPeerConnectionErrorCallback) assert_equals: property has wrong .length expected 0 but got 1
 PASS RTCPeerConnection interface: operation generateCertificate(AlgorithmIdentifier)
 PASS RTCPeerConnection interface: operation getSenders()
 PASS RTCPeerConnection interface: operation getReceivers()
@@ -492,8 +492,20 @@
 FAIL RTCStatsEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "RTCStatsEvent" expected property "RTCStatsEvent" missing
 FAIL RTCStatsEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "RTCStatsEvent" expected property "RTCStatsEvent" missing
 FAIL RTCStatsEvent interface: attribute report assert_own_property: self does not have own property "RTCStatsEvent" expected property "RTCStatsEvent" missing
+FAIL RTCError interface: existence and properties of interface object assert_equals: prototype of self's property "RTCError" is not Function.prototype expected function "function () { [native code] }" but got function "function DOMException() { [native code] }"
+PASS RTCError interface object length
+PASS RTCError interface object name
+FAIL RTCError interface: existence and properties of interface prototype object assert_equals: prototype of RTCError.prototype is not Object.prototype expected object "[object Object]" but got [stringifying object threw TypeError: Illegal invocation with type object]
+PASS RTCError interface: existence and properties of interface prototype object's "constructor" property
+PASS RTCError interface: existence and properties of interface prototype object's @@unscopables property
+PASS RTCError interface: attribute errorDetail
+PASS RTCError interface: attribute sdpLineNumber
+PASS RTCError interface: attribute httpRequestStatusCode
+PASS RTCError interface: attribute sctpCauseCode
+PASS RTCError interface: attribute receivedAlert
+PASS RTCError interface: attribute sentAlert
 PASS RTCErrorEvent interface: existence and properties of interface object
-FAIL RTCErrorEvent interface object length assert_equals: wrong value for RTCErrorEvent.length expected 1 but got 2
+PASS RTCErrorEvent interface object length
 PASS RTCErrorEvent interface object name
 PASS RTCErrorEvent interface: existence and properties of interface prototype object
 PASS RTCErrorEvent interface: existence and properties of interface prototype object's "constructor" property
diff --git a/third_party/closure_compiler/externs/file_manager_private.js b/third_party/closure_compiler/externs/file_manager_private.js
index 3874e8ca..0a398b1 100644
--- a/third_party/closure_compiler/externs/file_manager_private.js
+++ b/third_party/closure_compiler/externs/file_manager_private.js
@@ -877,12 +877,6 @@
 chrome.fileManagerPrivate.computeChecksum = function(entry, callback) {};
 
 /**
- * Gets a flag indicating whether user metrics reporting is enabled.
- * @param {function((boolean|undefined))} callback
- */
-chrome.fileManagerPrivate.isUMAEnabled = function(callback) {};
-
-/**
  * Sets a tag on a file or a directory. Only Drive files are supported.
  * @param {!Entry} entry
  * @param {string} visibility 'private' or 'public'
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium
index b487d97..ed992dd 100644
--- a/third_party/harfbuzz-ng/README.chromium
+++ b/third_party/harfbuzz-ng/README.chromium
@@ -1,9 +1,9 @@
 Name: harfbuzz-ng
 Short Name: harfbuzz-ng
 URL: http://harfbuzz.org
-Version: 2.3.1-95
-Date: 20190315
-Revision: 8aaab78efcac81a05ec919be13792c98741ea1b5
+Version: 2.3.1-96
+Date: 20190320
+Revision: bcb4e505d6ffe33e3268a06698e75d6be0e64957
 Security Critical: yes
 License: MIT
 License File: src/COPYING
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py
index 169fe10..8a316f3 100755
--- a/tools/clang/scripts/package.py
+++ b/tools/clang/scripts/package.py
@@ -466,18 +466,6 @@
             filter=PrintTarProgress)
   MaybeUpload(args, objdumpdir, platform)
 
-  # Zip up llvm-cfi-verify for CFI coverage.
-  cfiverifydir = 'llvmcfiverify-' + stamp
-  shutil.rmtree(cfiverifydir, ignore_errors=True)
-  os.makedirs(os.path.join(cfiverifydir, 'bin'))
-  shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', 'llvm-cfi-verify' +
-                           exe_ext),
-              os.path.join(cfiverifydir, 'bin'))
-  with tarfile.open(cfiverifydir + '.tgz', 'w:gz') as tar:
-    tar.add(os.path.join(cfiverifydir, 'bin'), arcname='bin',
-            filter=PrintTarProgress)
-  MaybeUpload(args, cfiverifydir, platform)
-
   # On Mac, lld isn't part of the main zip.  Upload it in a separate zip.
   if sys.platform == 'darwin':
     llddir = 'lld-' + stamp
@@ -494,8 +482,9 @@
               filter=PrintTarProgress)
     MaybeUpload(args, llddir, platform)
 
-    # dsymutil isn't part of the main zip either, and it gets periodically deployed to CIPD
-    # (manually, not as part of clang rolls) for use in the Mac build toolchain.
+    # dsymutil isn't part of the main zip either, and it gets periodically
+    # deployed to CIPD (manually, not as part of clang rolls) for use in the
+    # Mac build toolchain.
     dsymdir = 'dsymutil-' + stamp
     shutil.rmtree(dsymdir, ignore_errors=True)
     os.makedirs(os.path.join(dsymdir, 'bin'))
diff --git a/tools/cygprofile/orderfile_generator_backend.py b/tools/cygprofile/orderfile_generator_backend.py
index 86658f12..471b9e9 100755
--- a/tools/cygprofile/orderfile_generator_backend.py
+++ b/tools/cygprofile/orderfile_generator_backend.py
@@ -552,7 +552,7 @@
       device = self._SetDevice()
       self._profiler = profile_android_startup.AndroidProfileTool(
           output_directory, host_profile_dir, use_wpr, urls, simulate_user,
-          device=device)
+          device, debug=self._options.streamline_for_debugging)
       if options.pregenerated_profiles:
         self._profiler.SetPregeneratedProfiles(
             glob.glob(options.pregenerated_profiles))
@@ -972,6 +972,12 @@
                             'orderfiles (both patched and unpatched) from '
                             'their normal location in the tree to the cloud '
                             'storage. DANGEROUS! USE WITH CARE!'))
+  parser.add_argument('--streamline-for-debugging', action='store_true',
+                      help=('Streamline where possible the run for faster '
+                            'iteration while debugging. The orderfile '
+                            'generated will be valid and nontrivial, but '
+                            'may not be based on a representative profile '
+                            'or other such considerations. Use with caution.'))
   parser.add_argument('--commit-hashes', action='store_true',
                       help=('Commit any orderfile hash files in the current '
                             'checkout; performs no other action'))
diff --git a/tools/cygprofile/profile_android_startup.py b/tools/cygprofile/profile_android_startup.py
index ecb731a..a84bda2 100755
--- a/tools/cygprofile/profile_android_startup.py
+++ b/tools/cygprofile/profile_android_startup.py
@@ -191,7 +191,7 @@
       os.path.dirname(__file__), 'memory_top_10_mobile_000.wprgo')
 
   def __init__(self, output_directory, host_profile_dir, use_wpr, urls,
-               simulate_user, device):
+               simulate_user, device, debug=False):
     """Constructor.
 
     Args:
@@ -203,6 +203,7 @@
       simulate_user: (bool) Whether to simulate a user.
       device: (DeviceUtils) Android device selected to be used to
                             generate orderfile.
+      debug: (bool) Use simpler, non-representative debugging profile.
     """
     assert device, 'Expected a valid device'
     self._device = device
@@ -212,6 +213,7 @@
     self._use_wpr = use_wpr
     self._urls = urls
     self._simulate_user = simulate_user
+    self._debug = debug
     self._SetUpDevice()
     self._pregenerated_profiles = None
 
@@ -305,12 +307,16 @@
       logging.info('Profile files: %s', '\n'.join(self._pregenerated_profiles))
       return self._pregenerated_profiles
     logging.info('Running system health profile')
+    profile_benchmark = 'orderfile_generation.training'
+    if self._debug:
+      logging.info('Using reduced debugging profile')
+      profile_benchmark = 'orderfile_generation.debugging'
     self._SetUpDeviceFolders()
     self._RunCommand(['tools/perf/run_benchmark',
                       '--device={}'.format(self._device.serial),
                       '--browser=exact',
                       '--browser-executable={}'.format(apk),
-                      'orderfile_generation.training'])
+                      profile_benchmark])
     data = self._PullProfileData()
     self._DeleteDeviceData()
     return data
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 1190249..68a70e9 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -1911,7 +1911,7 @@
     },
 
     'cfi': {
-      'gn_args': 'is_cfi=true use_cfi_icall=true',
+      'gn_args': 'is_cfi=true',
     },
 
     'cfi_full': {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 722a2df..c4705069 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -18128,7 +18128,7 @@
   <int value="957" label="PLATFORMKEYSINTERNAL_SELECTCLIENTCERTIFICATES"/>
   <int value="958" label="CRYPTOTOKENPRIVATE_CANORIGINASSERTAPPID"/>
   <int value="959" label="DELETED_EASYUNLOCKPRIVATE_SETAUTOPAIRINGRESULT"/>
-  <int value="960" label="FILEMANAGERPRIVATE_ISUMAENABLED"/>
+  <int value="960" label="DELETED_FILEMANAGERPRIVATE_ISUMAENABLED"/>
   <int value="961" label="WEBVIEWINTERNAL_SETALLOWSCALING"/>
   <int value="962" label="PLATFORMKEYSINTERNAL_GETPUBLICKEY"/>
   <int value="963" label="RUNTIME_OPENOPTIONSPAGE"/>
@@ -18915,7 +18915,7 @@
   <int value="113" label="kPlatformKeys"/>
   <int value="114" label="kDeleted_Plugin"/>
   <int value="115" label="kPower"/>
-  <int value="116" label="kPreferencesPrivate"/>
+  <int value="116" label="kDeleted_PreferencesPrivate"/>
   <int value="117" label="kDeleted_PrincipalsPrivate"/>
   <int value="118" label="kPrinterProvider"/>
   <int value="119" label="kPrivacy"/>
@@ -46844,7 +46844,7 @@
   <int value="8" label="FileThread"/>
   <int value="9" label="DatabaseThread"/>
   <int value="10" label="WebAudioThread"/>
-  <int value="11" label="ScriptStreamerThread"/>
+  <int value="11" label="ScriptStreamerThread (obsolete)"/>
   <int value="12" label="OfflineAudioRenderThread"/>
   <int value="13" label="ReverbConvolutionBackgroundThread"/>
   <int value="14" label="HRTFDatabaseLoaderThread"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 369ea20b..74dea85 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -37684,6 +37684,26 @@
   </summary>
 </histogram>
 
+<histogram name="FileBrowser.LauncherSearch.Drive" units="ms"
+    expires_after="M79">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
+  <summary>
+    The time taken to execute launcher search for drive files. Recorded when the
+    complete result set is returned from drive.
+  </summary>
+</histogram>
+
+<histogram name="FileBrowser.LauncherSearch.Local" units="ms"
+    expires_after="M79">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
+  <summary>
+    The time taken to execute launcher search for local files. Recorded when the
+    complete result set has been calculated for files on the local disk.
+  </summary>
+</histogram>
+
 <histogram name="FileBrowser.Load" units="ms" expires_after="M79">
   <owner>slangley@chromium.org</owner>
   <owner>weifangsun@chromium.org</owner>
diff --git a/ui/accessibility/ax_language_info_unittest.cc b/ui/accessibility/ax_language_info_unittest.cc
index 0c759c5..90dc981 100644
--- a/ui/accessibility/ax_language_info_unittest.cc
+++ b/ui/accessibility/ax_language_info_unittest.cc
@@ -55,23 +55,26 @@
   initial_state.nodes[1].child_ids[0] = 4;
   initial_state.nodes[2].id = 3;
   initial_state.nodes[3].id = 4;
+
   AXTree tree(initial_state);
+  DetectLanguageForSubtree(tree.root(), &tree);
+  ASSERT_TRUE(LabelLanguageForSubtree(tree.root(), &tree));
 
   // Check that tree parenting conforms to expected shape.
   AXNode* node1 = tree.GetFromId(1);
   EXPECT_EQ(node1->parent(), nullptr);
 
   AXNode* node2 = tree.GetFromId(2);
-  EXPECT_EQ(node2->parent(), node1);
+  ASSERT_EQ(node2->parent(), node1);
   EXPECT_EQ(node2->parent()->parent(), nullptr);
 
   AXNode* node3 = tree.GetFromId(3);
-  EXPECT_EQ(node3->parent(), node1);
+  ASSERT_EQ(node3->parent(), node1);
   EXPECT_EQ(node3->parent()->parent(), nullptr);
 
   AXNode* node4 = tree.GetFromId(4);
-  EXPECT_EQ(node4->parent(), node2);
-  EXPECT_EQ(node4->parent()->parent(), node1);
+  ASSERT_EQ(node4->parent(), node2);
+  ASSERT_EQ(node4->parent()->parent(), node1);
   EXPECT_EQ(node4->parent()->parent()->parent(), nullptr);
 
   EXPECT_EQ(node1->GetLanguage(), "");
@@ -139,6 +142,8 @@
   }
 
   AXTree tree(initial_state);
+  DetectLanguageForSubtree(tree.root(), &tree);
+  ASSERT_TRUE(LabelLanguageForSubtree(tree.root(), &tree));
 
   {
     AXNode* node1 = tree.GetFromId(1);
@@ -233,6 +238,8 @@
   }
 
   AXTree tree(initial_state);
+  DetectLanguageForSubtree(tree.root(), &tree);
+  ASSERT_TRUE(LabelLanguageForSubtree(tree.root(), &tree));
 
   {
     AXNode* node1 = tree.GetFromId(1);
@@ -337,6 +344,8 @@
   }
 
   AXTree tree(initial_state);
+  DetectLanguageForSubtree(tree.root(), &tree);
+  ASSERT_TRUE(LabelLanguageForSubtree(tree.root(), &tree));
 
   {
     AXNode* node1 = tree.GetFromId(1);
@@ -374,6 +383,128 @@
   }
 }
 
+TEST(AXLanguageInfoTest, LanguageDetectionDetectOnly) {
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      ::switches::kEnableExperimentalAccessibilityLanguageDetection);
+
+  // This tests a Detect step without any matching Label step.
+  //
+  // Tree:
+  //        1
+  //      2   3
+  //    4
+  //  5
+  //
+  //  1 - English lang attribute, no text
+  //  2 - French lang attribute,  no text
+  //  3 - no attribute,           French text
+  //  4 - no attribute,           English text
+  //  5 - no attribute,           German text
+  AXTreeUpdate initial_state;
+  initial_state.root_id = 1;
+  initial_state.nodes.resize(5);
+
+  {
+    AXNodeData& node1 = initial_state.nodes[0];
+    node1.id = 1;
+    node1.child_ids.resize(2);
+    node1.child_ids[0] = 2;
+    node1.child_ids[1] = 3;
+    node1.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "en");
+  }
+
+  {
+    AXNodeData& node2 = initial_state.nodes[1];
+    node2.id = 2;
+    node2.child_ids.resize(1);
+    node2.child_ids[0] = 4;
+    node2.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr");
+  }
+
+  {
+    AXNodeData& node3 = initial_state.nodes[2];
+    node3.id = 3;
+    node3.role = ax::mojom::Role::kStaticText;
+    std::string node3_text =
+        "Ce texte a été créé avec Google Translate, il est peu probable qu'il "
+        "soit idiomatique dans la langue cible indiquée Ce texte est "
+        "uniquement utilisé pour tester la détection de la langue.";
+    node3.AddStringAttribute(ax::mojom::StringAttribute::kName, node3_text);
+  }
+
+  {
+    AXNodeData& node4 = initial_state.nodes[3];
+    node4.id = 4;
+    node4.child_ids.resize(1);
+    node4.child_ids[0] = 5;
+    node4.role = ax::mojom::Role::kStaticText;
+    std::string node4_text =
+        "This is text created using Google Translate, it is unlikely to be "
+        "idiomatic in the given target language. This text is only used to "
+        "test language detection";
+    node4.AddStringAttribute(ax::mojom::StringAttribute::kName, node4_text);
+  }
+
+  {
+    AXNodeData& node5 = initial_state.nodes[4];
+    node5.id = 5;
+    node5.role = ax::mojom::Role::kStaticText;
+    std::string node5_text =
+        "Dies ist ein mit Google Translate erstellter Text. Es ist "
+        "unwahrscheinlich, dass er in der angegebenen Zielsprache idiomatisch "
+        "ist. Dieser Text wird nur zum Testen der Spracherkennung verwendet.";
+    node5.AddStringAttribute(ax::mojom::StringAttribute::kName, node5_text);
+  }
+
+  AXTree tree(initial_state);
+  DetectLanguageForSubtree(tree.root(), &tree);
+  // Purposefully not calling Label so we can test Detect in isolation.
+
+  {
+    AXNode* node1 = tree.GetFromId(1);
+    // node1 is not a text node, so no lang info should be attached.
+    EXPECT_EQ(node1->GetLanguageInfo(), nullptr);
+    EXPECT_EQ(node1->GetLanguage(), "en");
+  }
+
+  {
+    AXNode* node2 = tree.GetFromId(2);
+    // node2 is not a text node, so no lang info should be attached.
+    EXPECT_EQ(node2->GetLanguageInfo(), nullptr);
+    EXPECT_EQ(node2->GetLanguage(), "fr");
+  }
+
+  {
+    AXNode* node3 = tree.GetFromId(3);
+    EXPECT_TRUE(node3->IsTextNode());
+    ASSERT_NE(node3->GetLanguageInfo(), nullptr);
+    ASSERT_GT(node3->GetLanguageInfo()->detected_languages.size(), (unsigned)0);
+    ASSERT_EQ(node3->GetLanguageInfo()->detected_languages[0], "fr");
+    EXPECT_TRUE(node3->GetLanguageInfo()->language.empty());
+    EXPECT_EQ(node3->GetLanguage(), "en");
+  }
+
+  {
+    AXNode* node4 = tree.GetFromId(4);
+    EXPECT_TRUE(node4->IsTextNode());
+    ASSERT_NE(node4->GetLanguageInfo(), nullptr);
+    ASSERT_GT(node4->GetLanguageInfo()->detected_languages.size(), (unsigned)0);
+    ASSERT_EQ(node4->GetLanguageInfo()->detected_languages[0], "en");
+    EXPECT_TRUE(node4->GetLanguageInfo()->language.empty());
+    EXPECT_EQ(node4->GetLanguage(), "fr");
+  }
+
+  {
+    AXNode* node5 = tree.GetFromId(5);
+    EXPECT_TRUE(node5->IsTextNode());
+    ASSERT_NE(node5->GetLanguageInfo(), nullptr);
+    ASSERT_GT(node5->GetLanguageInfo()->detected_languages.size(), (unsigned)0);
+    ASSERT_EQ(node5->GetLanguageInfo()->detected_languages[0], "de");
+    EXPECT_TRUE(node5->GetLanguageInfo()->language.empty());
+    EXPECT_EQ(node5->GetLanguage(), "fr");
+  }
+}
+
 TEST(AXLanguageInfoTest, kLanguageUntouched) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       ::switches::kEnableExperimentalAccessibilityLanguageDetection);
@@ -435,11 +566,13 @@
   }
 
   AXTree tree(initial_state);
+  DetectLanguageForSubtree(tree.root(), &tree);
+  ASSERT_TRUE(LabelLanguageForSubtree(tree.root(), &tree));
 
   {
     // French should be detected, original English attr should be untouched.
     AXNode* node1 = tree.GetFromId(1);
-    EXPECT_NE(node1->GetLanguageInfo(), nullptr);
+    ASSERT_NE(node1->GetLanguageInfo(), nullptr);
     EXPECT_EQ(node1->GetLanguageInfo()->language, "fr");
     EXPECT_EQ(node1->GetStringAttribute(ax::mojom::StringAttribute::kLanguage),
               "en");
@@ -449,7 +582,7 @@
   {
     // English should be detected, original French attr should be untouched.
     AXNode* node2 = tree.GetFromId(2);
-    EXPECT_NE(node2->GetLanguageInfo(), nullptr);
+    ASSERT_NE(node2->GetLanguageInfo(), nullptr);
     EXPECT_EQ(node2->GetLanguageInfo()->language, "en");
     EXPECT_EQ(node2->GetStringAttribute(ax::mojom::StringAttribute::kLanguage),
               "fr");
@@ -459,7 +592,7 @@
   {
     // German should be detected, original empty attr should be untouched.
     AXNode* node3 = tree.GetFromId(3);
-    EXPECT_NE(node3->GetLanguageInfo(), nullptr);
+    ASSERT_NE(node3->GetLanguageInfo(), nullptr);
     EXPECT_EQ(node3->GetLanguageInfo()->language, "de");
     EXPECT_EQ(node3->GetStringAttribute(ax::mojom::StringAttribute::kLanguage),
               "");
@@ -478,9 +611,9 @@
     stats.Add(detected_languages);
   }
 
-  EXPECT_EQ(stats.GetScore("en"), 3);
-  EXPECT_EQ(stats.GetScore("fr"), 2);
-  EXPECT_EQ(stats.GetScore("ja"), 1);
+  ASSERT_EQ(stats.GetScore("en"), 3);
+  ASSERT_EQ(stats.GetScore("fr"), 2);
+  ASSERT_EQ(stats.GetScore("ja"), 1);
 
   EXPECT_TRUE(stats.CheckLanguageWithinTop("en"));
   EXPECT_TRUE(stats.CheckLanguageWithinTop("fr"));
@@ -494,10 +627,10 @@
     stats.Add(detected_languages);
   }
 
-  EXPECT_EQ(stats.GetScore("en"), 6);
-  EXPECT_EQ(stats.GetScore("fr"), 3);
-  EXPECT_EQ(stats.GetScore("de"), 2);
-  EXPECT_EQ(stats.GetScore("ja"), 1);
+  ASSERT_EQ(stats.GetScore("en"), 6);
+  ASSERT_EQ(stats.GetScore("fr"), 3);
+  ASSERT_EQ(stats.GetScore("de"), 2);
+  ASSERT_EQ(stats.GetScore("ja"), 1);
 
   EXPECT_TRUE(stats.CheckLanguageWithinTop("en"));
   EXPECT_TRUE(stats.CheckLanguageWithinTop("fr"));
@@ -511,10 +644,10 @@
     stats.Add(detected_languages);
   }
 
-  EXPECT_EQ(stats.GetScore("en"), 6);
-  EXPECT_EQ(stats.GetScore("fr"), 6);
-  EXPECT_EQ(stats.GetScore("de"), 2);
-  EXPECT_EQ(stats.GetScore("ja"), 1);
+  ASSERT_EQ(stats.GetScore("en"), 6);
+  ASSERT_EQ(stats.GetScore("fr"), 6);
+  ASSERT_EQ(stats.GetScore("de"), 2);
+  ASSERT_EQ(stats.GetScore("ja"), 1);
 
   EXPECT_TRUE(stats.CheckLanguageWithinTop("en"));
   EXPECT_TRUE(stats.CheckLanguageWithinTop("fr"));
@@ -530,12 +663,12 @@
     stats.Add(detected_languages);
   }
 
-  EXPECT_EQ(stats.GetScore("en"), 6);
-  EXPECT_EQ(stats.GetScore("fr"), 6);
-  EXPECT_EQ(stats.GetScore("ja"), 4);
-  EXPECT_EQ(stats.GetScore("de"), 2);
-  EXPECT_EQ(stats.GetScore("qq"), 2);
-  EXPECT_EQ(stats.GetScore("zz"), 1);
+  ASSERT_EQ(stats.GetScore("en"), 6);
+  ASSERT_EQ(stats.GetScore("fr"), 6);
+  ASSERT_EQ(stats.GetScore("ja"), 4);
+  ASSERT_EQ(stats.GetScore("de"), 2);
+  ASSERT_EQ(stats.GetScore("qq"), 2);
+  ASSERT_EQ(stats.GetScore("zz"), 1);
 
   EXPECT_TRUE(stats.CheckLanguageWithinTop("en"));
   EXPECT_TRUE(stats.CheckLanguageWithinTop("fr"));
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc
index c797786..d6f103a 100644
--- a/ui/accessibility/ax_tree.cc
+++ b/ui/accessibility/ax_tree.cc
@@ -450,15 +450,6 @@
     }
   }
 
-  // TODO(chrishall): consider running this asynchronously and/or throttling.
-  // TODO(chrishall): only updated detected language for updated subtree rather
-  //                  than entire tree, this requires some smarts as
-  //                  `update.nodes` may contain overlapping subtrees and so
-  //                  walking over it would create redundant work.
-  DetectLanguageForSubtree(root_, this);
-  if (!LabelLanguageForSubtree(root_, this))
-    LOG(ERROR) << "Language detection failed at step: Label";
-
   std::set<const AXNode*>& new_nodes = update_state.new_nodes;
   std::vector<AXTreeObserver::Change> changes;
   changes.reserve(update.nodes.size());
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index b4ad880..d360060 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -174,6 +174,19 @@
   SetWeakGPtrToAtkObject(&g_active_top_level_frame, new_top_level_frame);
 }
 
+AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem
+AtkCoordTypeToTextRangeBoundsCoordinateSystem(AtkCoordType coordinate_type) {
+  switch (coordinate_type) {
+    case ATK_XY_SCREEN:
+      return AXPlatformNodeDelegate::Screen;
+    case ATK_XY_WINDOW:
+      return AXPlatformNodeDelegate::Window;
+    case ATK_XY_PARENT:
+      return AXPlatformNodeDelegate::Parent;
+    default:
+      return AXPlatformNodeDelegate::Screen;
+  }
+}
 }  // namespace
 
 //
@@ -1215,6 +1228,57 @@
 }
 #endif
 
+void AXPlatformNodeAuraLinuxGetCharacterExtents(AtkText* atk_text,
+                                                int offset,
+                                                int* x,
+                                                int* y,
+                                                int* width,
+                                                int* height,
+                                                AtkCoordType coordinate_type) {
+  gfx::Rect rect;
+  AXPlatformNodeAuraLinux* obj =
+      AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(atk_text));
+  if (obj) {
+    rect = obj->GetDelegate()->GetTextRangeBoundsRect(
+        obj->UnicodeToUTF16OffsetInText(offset),
+        obj->UnicodeToUTF16OffsetInText(offset + 1),
+        AtkCoordTypeToTextRangeBoundsCoordinateSystem(coordinate_type));
+  }
+
+  if (x)
+    *x = rect.x();
+  if (y)
+    *y = rect.y();
+  if (width)
+    *width = rect.width();
+  if (height)
+    *height = rect.height();
+}
+
+void AXPlatformNodeAuraLinuxGetRangeExtents(AtkText* atk_text,
+                                            int start_offset,
+                                            int end_offset,
+                                            AtkCoordType coordinate_type,
+                                            AtkTextRectangle* out_rectangle) {
+  if (!out_rectangle)
+    return;
+
+  gfx::Rect rect;
+  AXPlatformNodeAuraLinux* obj =
+      AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(atk_text));
+  if (obj) {
+    rect = obj->GetDelegate()->GetTextRangeBoundsRect(
+        obj->UnicodeToUTF16OffsetInText(start_offset),
+        obj->UnicodeToUTF16OffsetInText(end_offset),
+        AtkCoordTypeToTextRangeBoundsCoordinateSystem(coordinate_type));
+  }
+
+  out_rectangle->x = rect.x();
+  out_rectangle->y = rect.y();
+  out_rectangle->width = rect.width();
+  out_rectangle->height = rect.height();
+}
+
 static void AXTextInterfaceBaseInit(AtkTextIface* iface) {
   iface->get_text = AXPlatformNodeAuraLinuxGetText;
   iface->get_run_attributes = AXPlatformNodeAuraLinuxGetRunAttributes;
@@ -1223,6 +1287,8 @@
   iface->get_text_after_offset = AXPlatformNodeAuraLinuxGetTextAfterOffset;
   iface->get_text_before_offset = AXPlatformNodeAuraLinuxGetTextBeforeOffset;
   iface->get_text_at_offset = AXPlatformNodeAuraLinuxGetTextAtOffset;
+  iface->get_character_extents = AXPlatformNodeAuraLinuxGetCharacterExtents;
+  iface->get_range_extents = AXPlatformNodeAuraLinuxGetRangeExtents;
 
 #if ATK_CHECK_VERSION(2, 10, 0)
   iface->get_string_at_offset = AXPlatformNodeAuraLinuxGetStringAtOffset;
diff --git a/ui/accessibility/platform/ax_platform_node_delegate.h b/ui/accessibility/platform/ax_platform_node_delegate.h
index eccf9db..c416efe 100644
--- a/ui/accessibility/platform/ax_platform_node_delegate.h
+++ b/ui/accessibility/platform/ax_platform_node_delegate.h
@@ -92,6 +92,21 @@
                                             int len,
                                             bool clipped = false) const = 0;
 
+  // Get the bounds of the given text range in the given coordinate system.
+  // Screen gets these boundaries in screen coordinates, Window in coordinates
+  // relative to the parent window, and Parent relative to the parent node. The
+  // offsets refer to offsets within the text returned for this node when
+  // treated as a platform text node.
+  enum TextRangeBoundsCoordinateSystem {
+    Screen,
+    Window,
+    Parent,
+  };
+  virtual gfx::Rect GetTextRangeBoundsRect(
+      int start_offset,
+      int end_offset,
+      TextRangeBoundsCoordinateSystem coordinate_system) const = 0;
+
   // Do a *synchronous* hit test of the given location in global screen
   // coordinates, and the node within this node's subtree (inclusive) that's
   // hit, if any.
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.cc b/ui/accessibility/platform/ax_platform_node_delegate_base.cc
index ca70a981..a3af460 100644
--- a/ui/accessibility/platform/ax_platform_node_delegate_base.cc
+++ b/ui/accessibility/platform/ax_platform_node_delegate_base.cc
@@ -66,6 +66,14 @@
   return gfx::Rect();
 }
 
+gfx::Rect AXPlatformNodeDelegateBase::GetTextRangeBoundsRect(
+    int start_offset,
+    int end_offset,
+    AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem coordinate_system)
+    const {
+  return gfx::Rect();
+}
+
 gfx::NativeViewAccessible AXPlatformNodeDelegateBase::HitTestSync(int x,
                                                                   int y) {
   return nullptr;
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.h b/ui/accessibility/platform/ax_platform_node_delegate_base.h
index 8872890..b7a648f 100644
--- a/ui/accessibility/platform/ax_platform_node_delegate_base.h
+++ b/ui/accessibility/platform/ax_platform_node_delegate_base.h
@@ -67,6 +67,12 @@
                                     int len,
                                     bool clipped = false) const override;
 
+  gfx::Rect GetTextRangeBoundsRect(
+      int start_offset,
+      int end_offset,
+      AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem coordinate_system)
+      const override;
+
   // Do a *synchronous* hit test of the given location in global screen
   // coordinates, and the node within this node's subtree (inclusive) that's
   // hit, if any.
diff --git a/ui/file_manager/file_manager/background/js/launcher_search.js b/ui/file_manager/file_manager/background/js/launcher_search.js
index 36c9580..072796f4 100644
--- a/ui/file_manager/file_manager/background/js/launcher_search.js
+++ b/ui/file_manager/file_manager/background/js/launcher_search.js
@@ -113,6 +113,7 @@
 LauncherSearch.prototype.onQueryStarted_ = function(queryId, query, limit) {
   this.queryId_ = queryId;
 
+  const startTime = Date.now();
   // Request an instance of volume manager to ensure that all volumes are
   // initialized. When user searches while background page of the Files app is
   // not running, it happens that this method is executed before all volumes are
@@ -122,8 +123,8 @@
   volumeManagerFactory.getInstance()
       .then(() => {
         return Promise.all([
-          this.queryDriveEntries_(queryId, query, limit),
-          this.queryLocalEntries_(queryId, query)
+          this.queryDriveEntries_(queryId, query, limit, startTime),
+          this.queryLocalEntries_(queryId, query, startTime)
         ]);
       })
       .then((results) => {
@@ -228,10 +229,12 @@
  * @param {number} queryId
  * @param {string} query
  * @param {number} limit
+ * @param {number} startTime
  * @return {!Promise<!Array<!Entry>>}
  * @private
  */
-LauncherSearch.prototype.queryDriveEntries_ = (queryId, query, limit) => {
+LauncherSearch.prototype
+    .queryDriveEntries_ = (queryId, query, limit, startTime) => {
   const param = {query: query, types: 'ALL', maxResults: limit};
   return new Promise((resolve, reject) => {
     chrome.fileManagerPrivate.searchDriveMetadata(param, results => {
@@ -239,6 +242,8 @@
         if (connectionState.type !== 'online') {
           results = results.filter(result => result.availableOffline !== false);
         }
+        chrome.metricsPrivate.recordTime(
+            'FileBrowser.LauncherSearch.Drive', Date.now() - startTime);
         resolve(results.map(result => result.entry));
       });
     });
@@ -249,10 +254,12 @@
  * Queries entries which match the given query in Downloads.
  * @param {number} queryId
  * @param {string} query
+ * @param {number} startTime
  * @return {!Promise<!Array<!Entry>>}
  * @private
  */
-LauncherSearch.prototype.queryLocalEntries_ = function(queryId, query) {
+LauncherSearch.prototype.queryLocalEntries_ = function(
+    queryId, query, startTime) {
   if (!query) {
     return Promise.resolve([]);
   }
@@ -260,7 +267,7 @@
   return this.getDownloadsEntry_()
       .then((downloadsEntry) => {
         return this.queryEntriesRecursively_(
-            downloadsEntry, queryId, query.toLowerCase());
+            downloadsEntry, queryId, query.toLowerCase(), startTime);
       })
       .catch((error) => {
         if (error.name != 'AbortError') {
@@ -288,11 +295,12 @@
  * @param {!DirectoryEntry} rootEntry
  * @param {number} queryId
  * @param {string} query
+ * @param {number} startTime
  * @return {!Promise<!Array<!Entry>>}
  * @private
  */
 LauncherSearch.prototype.queryEntriesRecursively_ = function(
-    rootEntry, queryId, query) {
+    rootEntry, queryId, query, startTime) {
   return new Promise((resolve, reject) => {
     let foundEntries = [];
     util.readEntriesRecursively(
@@ -305,6 +313,8 @@
           }
         },
         () => {
+          chrome.metricsPrivate.recordTime(
+              'FileBrowser.LauncherSearch.Local', Date.now() - startTime);
           resolve(foundEntries);
         },
         reject,
diff --git a/ui/file_manager/file_manager/test/js/chrome_file_manager_private_test_impl.js b/ui/file_manager/file_manager/test/js/chrome_file_manager_private_test_impl.js
index 6fe2780..789586b 100644
--- a/ui/file_manager/file_manager/test/js/chrome_file_manager_private_test_impl.js
+++ b/ui/file_manager/file_manager/test/js/chrome_file_manager_private_test_impl.js
@@ -128,9 +128,6 @@
   grantAccess: (entryUrls, callback) => {
     setTimeout(callback, 0);
   },
-  isUMAEnabled: (callback) => {
-    setTimeout(callback, 0, false);
-  },
   // Simulate startup of vm and container by taking 1s.
   mountCrostiniDelay_: 1000,
   mountCrostini: (callback) => {