diff --git a/DEPS b/DEPS
index 3f6ac0b..1af29c37 100644
--- a/DEPS
+++ b/DEPS
@@ -129,11 +129,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'd0995493f8f3d1d4d882c6b5b5dbc327072dd41b',
+  'skia_revision': 'ac0aa2096ea47b2376fb732816d8466f1c29a6bc',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'c4cbeac0c0dcce8ac9351199474eb58917de2df7',
+  'v8_revision': 'eafa3e1e7c01dafbc2605299c25af93077737a94',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -145,11 +145,11 @@
   # 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': 'b55772e6e7ddfebcb9cebf78ddcbe686d9cacf28',
+  'swiftshader_revision': '4d3cdbc27b79fc0436015287707af57b7cc4a26d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '459ad7fe015ed4858ed881fcf81dca3eaadc91f3',
+  'pdfium_revision': '3f9d4b7ad04842b7e4ec346459e6b0bbd714e9a0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -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': '2f1832aff38dc3475514b0364f5d27117f6cc8a5',
+  'catapult_revision': '2432a1034a1d738332320ffaebbbd9febacb8b59',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -264,7 +264,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'e105f962cf0020ee96a5a14a881c0de4ad46706c',
+  'dawn_revision': '07950e80fe36028ed9cca0a4a99a8b08e9bb4fdf',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # 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' + '@' + 'ec6b379371e10acb0e7472473406331052b17449',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'dbb7660f84b4c75322f41348e8bfd7b3bb352f3d',
       'condition': 'checkout_linux',
   },
 
@@ -826,7 +826,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '5637e87bda2811565c3e4e58bd2274aeb3a4757e',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4492c37a14be41e3a3bf53234c53671b6e649a8e',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1339,7 +1339,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a0f51b2e123f39c9ff12e621b0b47dd28dd64424',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '741daaf0393c4ba42c1bfc9c88907aaa09349987',
+    Var('webrtc_git') + '/src.git' + '@' + '3dde450f0205e71b7d711fde44333cbd52f1ebc0',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc
index 47946d7f..2a6235a 100644
--- a/ash/login/ui/lock_contents_view.cc
+++ b/ash/login/ui/lock_contents_view.cc
@@ -1334,7 +1334,12 @@
 
   // Set preferred size before running layout actions, as layout actions may
   // depend on the preferred size to determine layout.
-  SetPreferredSize(display.size());
+  gfx::Size preferred_size = display.size();
+  preferred_size.set_height(preferred_size.height() -
+                            keyboard::KeyboardController::Get()
+                                ->GetWorkspaceOccludedBounds()
+                                .height());
+  SetPreferredSize(preferred_size);
 
   bool landscape = login_views_utils::ShouldShowLandscape(GetWidget());
   for (auto& action : layout_actions_)
diff --git a/ash/login/ui/lock_contents_view_unittest.cc b/ash/login/ui/lock_contents_view_unittest.cc
index c534740..9e3e2a2f 100644
--- a/ash/login/ui/lock_contents_view_unittest.cc
+++ b/ash/login/ui/lock_contents_view_unittest.cc
@@ -1298,6 +1298,60 @@
   EXPECT_TRUE(pin_view->visible());
 }
 
+TEST_F(LockContentsViewKeyboardUnitTest,
+       RotationWithKeyboardDoesNotCoverInput) {
+  ASSERT_NO_FATAL_FAILURE(ShowLoginScreen());
+  LockContentsView* contents =
+      LockScreen::TestApi(LockScreen::Get()).contents_view();
+  ASSERT_NE(nullptr, contents);
+
+  const display::Display& display =
+      display::Screen::GetScreen()->GetDisplayNearestWindow(
+          contents->GetWidget()->GetNativeWindow());
+
+  for (int user_count = 1; user_count < 10; user_count++) {
+    SetUserCount(user_count);
+    display_manager()->SetDisplayRotation(
+        display.id(), display::Display::ROTATE_0,
+        display::Display::RotationSource::ACTIVE);
+
+    ASSERT_NO_FATAL_FAILURE(ShowKeyboard());
+    const int height_when_keyboard_shown = contents->height();
+    ASSERT_NO_FATAL_FAILURE(HideKeyboard());
+    const int height_when_keyboard_hidden = contents->height();
+    EXPECT_LT(height_when_keyboard_shown, height_when_keyboard_hidden);
+
+    ASSERT_NO_FATAL_FAILURE(ShowKeyboard());
+
+    EXPECT_EQ(height_when_keyboard_shown, contents->height());
+    // Rotate the display to 90 degrees (portrait).
+    display_manager()->SetDisplayRotation(
+        display.id(), display::Display::ROTATE_90,
+        display::Display::RotationSource::ACTIVE);
+
+    // Rotate the display back to 0 degrees (landscape).
+    display_manager()->SetDisplayRotation(
+        display.id(), display::Display::ROTATE_0,
+        display::Display::RotationSource::ACTIVE);
+    EXPECT_EQ(height_when_keyboard_shown, contents->height());
+
+    ASSERT_NO_FATAL_FAILURE(HideKeyboard());
+
+    EXPECT_EQ(height_when_keyboard_hidden, contents->height());
+    // Rotate the display to 90 degrees (portrait).
+    display_manager()->SetDisplayRotation(
+        display.id(), display::Display::ROTATE_90,
+        display::Display::RotationSource::ACTIVE);
+
+    // Rotate the display back to 0 degrees (landscape).
+    display_manager()->SetDisplayRotation(
+        display.id(), display::Display::ROTATE_0,
+        display::Display::RotationSource::ACTIVE);
+
+    EXPECT_EQ(height_when_keyboard_hidden, contents->height());
+  }
+}
+
 // Verifies that swapping auth users while the virtual keyboard is active
 // focuses the other user's password field.
 TEST_F(LockContentsViewKeyboardUnitTest, SwitchUserWhileKeyboardShown) {
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc
index 308090c..9c580fd 100644
--- a/ash/public/cpp/app_list/app_list_features.cc
+++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -27,8 +27,12 @@
     "EnableAppListSearchAutocomplete", base::FEATURE_ENABLED_BY_DEFAULT};
 const base::Feature kEnableAdaptiveResultRanker{
     "EnableAdaptiveResultRanker", base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kEnableAppSearchResultRanker{
-    "EnableAppSearchResultRanker", base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kEnableQueryBasedAppsRanker{
+    "EnableQueryBasedAppsRanker", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kEnableZeroStateAppsRanker{
+    "EnableZeroStateAppsRanker", base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kEnableQueryBasedMixedTypesRanker{
+    "EnableQueryBasedMixedTypesRanker", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kEnableAppReinstallZeroState{
     "EnableAppReinstallZeroState", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kEnableEmbeddedAssistantUI{
@@ -72,8 +76,16 @@
   return base::FeatureList::IsEnabled(kEnableAdaptiveResultRanker);
 }
 
-bool IsAppSearchResultRankerEnabled() {
-  return base::FeatureList::IsEnabled(kEnableAppSearchResultRanker);
+bool IsQueryBasedAppsRankerEnabled() {
+  return base::FeatureList::IsEnabled(kEnableQueryBasedAppsRanker);
+}
+
+bool IsZeroStateAppsRankerEnabled() {
+  return base::FeatureList::IsEnabled(kEnableZeroStateAppsRanker);
+}
+
+bool IsQueryBasedMixedTypesEnabled() {
+  return base::FeatureList::IsEnabled(kEnableQueryBasedMixedTypesRanker);
 }
 
 bool IsAppReinstallZeroStateEnabled() {
@@ -104,7 +116,7 @@
 
 std::string AppSearchResultRankerPredictorName() {
   const std::string predictor_name = base::GetFieldTrialParamValueByFeature(
-      kEnableAppSearchResultRanker, "app_search_result_ranker_predictor_name");
+      kEnableZeroStateAppsRanker, "app_search_result_ranker_predictor_name");
   if (!predictor_name.empty())
     return predictor_name;
   return std::string("MrfuAppLaunchPredictor");
diff --git a/ash/public/cpp/app_list/app_list_features.h b/ash/public/cpp/app_list/app_list_features.h
index f69ec90..e7fb92e 100644
--- a/ash/public/cpp/app_list/app_list_features.h
+++ b/ash/public/cpp/app_list/app_list_features.h
@@ -44,8 +44,14 @@
 // Enable an adaptive model that tweaks search result scores.
 ASH_PUBLIC_EXPORT extern const base::Feature kEnableAdaptiveResultRanker;
 
-// Enables the feature to rank app search result using AppSearchResultRanker.
-ASH_PUBLIC_EXPORT extern const base::Feature kEnableAppSearchResultRanker;
+// Enable an model that ranks query based apps search result.
+ASH_PUBLIC_EXPORT extern const base::Feature kEnableQueryBasedAppsRanker;
+
+// Enable an model that ranks zero-state apps search result.
+ASH_PUBLIC_EXPORT extern const base::Feature kEnableZeroStateAppsRanker;
+
+// Enable an model that ranks query based non-apps result.
+ASH_PUBLIC_EXPORT extern const base::Feature kEnableQueryBasedMixedTypesRanker;
 
 // Enables the feature to include a single reinstallation candidate in
 // zero-state.
@@ -65,7 +71,9 @@
 bool ASH_PUBLIC_EXPORT IsZeroStateSuggestionsEnabled();
 bool ASH_PUBLIC_EXPORT IsAppListSearchAutocompleteEnabled();
 bool ASH_PUBLIC_EXPORT IsAdaptiveResultRankerEnabled();
-bool ASH_PUBLIC_EXPORT IsAppSearchResultRankerEnabled();
+bool ASH_PUBLIC_EXPORT IsQueryBasedAppsRankerEnabled();
+bool ASH_PUBLIC_EXPORT IsZeroStateAppsRankerEnabled();
+bool ASH_PUBLIC_EXPORT IsQueryBasedMixedTypesRankerEnabled();
 bool ASH_PUBLIC_EXPORT IsAppReinstallZeroStateEnabled();
 bool ASH_PUBLIC_EXPORT IsEmbeddedAssistantUIEnabled();
 bool ASH_PUBLIC_EXPORT IsAppGridGhostEnabled();
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 35cb08c..8e4fd0b 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -2415,7 +2415,6 @@
     "mac/mach_port_broker_unittest.cc",
     "mac/mach_port_rendezvous_unittest.cc",
     "mac/objc_release_properties_unittest.mm",
-    "mac/scoped_mach_vm_unittest.cc",
     "mac/scoped_nsobject_unittest.mm",
     "mac/scoped_objc_class_swizzler_unittest.mm",
     "mac/scoped_sending_event_unittest.mm",
diff --git a/base/mac/scoped_mach_vm.cc b/base/mac/scoped_mach_vm.cc
index a76044d..d52c77f 100644
--- a/base/mac/scoped_mach_vm.cc
+++ b/base/mac/scoped_mach_vm.cc
@@ -4,29 +4,24 @@
 
 #include "base/mac/scoped_mach_vm.h"
 
-#include "base/mac/mach_logging.h"
-
 namespace base {
 namespace mac {
 
 void ScopedMachVM::reset(vm_address_t address, vm_size_t size) {
   DCHECK_EQ(address % PAGE_SIZE, 0u);
   DCHECK_EQ(size % PAGE_SIZE, 0u);
-  reset_unaligned(address, size);
-}
 
-void ScopedMachVM::reset_unaligned(vm_address_t address, vm_size_t size) {
   if (size_) {
     if (address_ < address) {
-      kern_return_t kr = vm_deallocate(mach_task_self(), address_,
-                                       std::min(size_, address - address_));
-      MACH_DCHECK(kr == KERN_SUCCESS, kr) << "vm_deallocate";
+      vm_deallocate(mach_task_self(),
+                    address_,
+                    std::min(size_, address - address_));
     }
     if (address_ + size_ > address + size) {
       vm_address_t deallocate_start = std::max(address_, address + size);
-      kern_return_t kr = vm_deallocate(mach_task_self(), deallocate_start,
-                                       address_ + size_ - deallocate_start);
-      MACH_DCHECK(kr == KERN_SUCCESS, kr) << "vm_deallocate";
+      vm_deallocate(mach_task_self(),
+                    deallocate_start,
+                    address_ + size_ - deallocate_start);
     }
   }
 
diff --git a/base/mac/scoped_mach_vm.h b/base/mac/scoped_mach_vm.h
index 3d4cc022..58a13f66 100644
--- a/base/mac/scoped_mach_vm.h
+++ b/base/mac/scoped_mach_vm.h
@@ -60,16 +60,8 @@
     }
   }
 
-  // Resets the scoper to manage a new memory region. Both |address| and |size|
-  // must be page-aligned. If the new region is a smaller subset of the
-  // existing region (i.e. the new and old regions overlap), the non-
-  // overlapping part of the old region is deallocated.
   void reset(vm_address_t address = 0, vm_size_t size = 0);
 
-  // Like reset() but does not DCHECK that |address| and |size| are page-
-  // aligned.
-  void reset_unaligned(vm_address_t address, vm_size_t size);
-
   vm_address_t address() const {
     return address_;
   }
diff --git a/base/mac/scoped_mach_vm_unittest.cc b/base/mac/scoped_mach_vm_unittest.cc
deleted file mode 100644
index 3e13ff0..0000000
--- a/base/mac/scoped_mach_vm_unittest.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-// 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 "base/mac/scoped_mach_vm.h"
-
-#include <mach/mach.h>
-
-#include "base/test/gtest_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-namespace mac {
-namespace {
-
-void GetRegionInfo(vm_address_t* region_address, vm_size_t* region_size) {
-  vm_region_basic_info_64 region_info;
-  mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
-  mach_port_t object;
-  kern_return_t kr = vm_region_64(
-      mach_task_self(), region_address, region_size, VM_REGION_BASIC_INFO_64,
-      reinterpret_cast<vm_region_info_t>(&region_info), &count, &object);
-  EXPECT_EQ(KERN_SUCCESS, kr);
-}
-
-TEST(ScopedMachVMTest, Basic) {
-  vm_address_t address;
-  vm_size_t size = PAGE_SIZE;
-  kern_return_t kr =
-      vm_allocate(mach_task_self(), &address, size, VM_FLAGS_ANYWHERE);
-  ASSERT_EQ(KERN_SUCCESS, kr);
-
-  ScopedMachVM scoper(address, size);
-  EXPECT_EQ(address, scoper.address());
-  EXPECT_EQ(size, scoper.size());
-
-  // Test the initial region.
-  vm_address_t region_address = address;
-  vm_size_t region_size;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(KERN_SUCCESS, kr);
-  EXPECT_EQ(address, region_address);
-  EXPECT_EQ(1u * PAGE_SIZE, region_size);
-
-  {
-    ScopedMachVM scoper2;
-    EXPECT_EQ(0u, scoper2.address());
-    EXPECT_EQ(0u, scoper2.size());
-
-    scoper.swap(scoper2);
-
-    EXPECT_EQ(address, scoper2.address());
-    EXPECT_EQ(size, scoper2.size());
-
-    EXPECT_EQ(0u, scoper.address());
-    EXPECT_EQ(0u, scoper.size());
-  }
-
-  // After deallocation, the kernel will return the next highest address.
-  region_address = address;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(KERN_SUCCESS, kr);
-  EXPECT_LT(address, region_address);
-}
-
-TEST(ScopedMachVMTest, Reset) {
-  vm_address_t address;
-  vm_size_t size = PAGE_SIZE;
-  kern_return_t kr =
-      vm_allocate(mach_task_self(), &address, size, VM_FLAGS_ANYWHERE);
-  ASSERT_EQ(KERN_SUCCESS, kr);
-
-  ScopedMachVM scoper(address, size);
-
-  // Test the initial region.
-  vm_address_t region_address = address;
-  vm_size_t region_size;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(KERN_SUCCESS, kr);
-  EXPECT_EQ(address, region_address);
-  EXPECT_EQ(1u * PAGE_SIZE, region_size);
-
-  scoper.reset();
-
-  // After deallocation, the kernel will return the next highest address.
-  region_address = address;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(KERN_SUCCESS, kr);
-  EXPECT_LT(address, region_address);
-}
-
-TEST(ScopedMachVMTest, ResetSmallerAddress) {
-  vm_address_t address;
-  vm_size_t size = 2 * PAGE_SIZE;
-  kern_return_t kr =
-      vm_allocate(mach_task_self(), &address, size, VM_FLAGS_ANYWHERE);
-  ASSERT_EQ(KERN_SUCCESS, kr);
-
-  ScopedMachVM scoper(address, PAGE_SIZE);
-
-  // Test the initial region.
-  vm_address_t region_address = address;
-  vm_size_t region_size;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(KERN_SUCCESS, kr);
-  EXPECT_EQ(address, region_address);
-  EXPECT_EQ(2u * PAGE_SIZE, region_size);
-
-  // This will free address..PAGE_SIZE that is currently in the scoper.
-  scoper.reset(address + PAGE_SIZE, size + PAGE_SIZE);
-
-  // Verify that the region is now only one page.
-  region_address = address;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(address + PAGE_SIZE, region_address);
-  EXPECT_EQ(1u * PAGE_SIZE, region_size);
-}
-
-TEST(ScopedMachVMTest, ResetLargerAddressAndSize) {
-  vm_address_t address;
-  vm_size_t size = 3 * PAGE_SIZE;
-  kern_return_t kr =
-      vm_allocate(mach_task_self(), &address, size, VM_FLAGS_ANYWHERE);
-  ASSERT_EQ(KERN_SUCCESS, kr);
-
-  // Test the initial region.
-  vm_address_t region_address = address;
-  vm_size_t region_size;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(KERN_SUCCESS, kr);
-  EXPECT_EQ(address, region_address);
-  EXPECT_EQ(3u * PAGE_SIZE, region_size);
-
-  ScopedMachVM scoper(address + 2 * PAGE_SIZE, 2 * PAGE_SIZE);
-  // Expand the region to be larger.
-  scoper.reset(address, size);
-
-  // Verify that the region is still three pages.
-  region_address = address;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(address, region_address);
-  EXPECT_EQ(3u * PAGE_SIZE, region_size);
-}
-
-TEST(ScopedMachVMTest, ResetLargerAddress) {
-  vm_address_t address;
-  vm_size_t size = 6 * PAGE_SIZE;
-  kern_return_t kr =
-      vm_allocate(mach_task_self(), &address, size, VM_FLAGS_ANYWHERE);
-  ASSERT_EQ(KERN_SUCCESS, kr);
-
-  // Test the initial region.
-  vm_address_t region_address = address;
-  vm_size_t region_size;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(KERN_SUCCESS, kr);
-  EXPECT_EQ(address, region_address);
-  EXPECT_EQ(6u * PAGE_SIZE, region_size);
-
-  ScopedMachVM scoper(address + 3 * PAGE_SIZE, 3 * PAGE_SIZE);
-
-  // Shift the region by three pages; the last three pages should be
-  // deallocated, while keeping the first three.
-  scoper.reset(address, 3 * PAGE_SIZE);
-
-  // Verify that the region is just three pages.
-  region_address = address;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(address, region_address);
-  EXPECT_EQ(3u * PAGE_SIZE, region_size);
-}
-
-TEST(ScopedMachVMTest, ResetUnaligned) {
-  vm_address_t address;
-  vm_size_t size = 2 * PAGE_SIZE;
-  kern_return_t kr =
-      vm_allocate(mach_task_self(), &address, size, VM_FLAGS_ANYWHERE);
-  ASSERT_EQ(KERN_SUCCESS, kr);
-
-  ScopedMachVM scoper;
-
-  // Test the initial region.
-  vm_address_t region_address = address;
-  vm_size_t region_size;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(address, region_address);
-  EXPECT_EQ(2u * PAGE_SIZE, region_size);
-
-  // Initialize with unaligned size.
-  scoper.reset_unaligned(address + PAGE_SIZE, PAGE_SIZE - 3);
-  // Reset with another unaligned size.
-  scoper.reset_unaligned(address + PAGE_SIZE, PAGE_SIZE - 11);
-
-  // The entire unaligned page gets deallocated.
-  region_address = address;
-  GetRegionInfo(&region_address, &region_size);
-  EXPECT_EQ(address, region_address);
-  EXPECT_EQ(1u * PAGE_SIZE, region_size);
-
-  // Reset with the whole region, freeing it.
-  scoper.reset_unaligned(address, size);
-}
-
-#if DCHECK_IS_ON()
-
-TEST(ScopedMachVMTest, ResetMustBeAligned) {
-  vm_address_t address;
-  vm_size_t size = 2 * PAGE_SIZE;
-  kern_return_t kr =
-      vm_allocate(mach_task_self(), &address, size, VM_FLAGS_ANYWHERE);
-  ASSERT_EQ(KERN_SUCCESS, kr);
-
-  ScopedMachVM scoper;
-  EXPECT_DCHECK_DEATH(scoper.reset(address, PAGE_SIZE + 1));
-}
-
-#endif  // DCHECK_IS_ON()
-
-}  // namespace
-}  // namespace mac
-}  // namespace base
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index a86f3b2..89947c3 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-0aba3e826b3187b0bd1bfdbf06fbaff168801edd
\ No newline at end of file
+ff3a76aa5ee027f553436a7caab90523876a8c76
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index b6be569..d4215ec 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-b058131a0406f496bda02c45ea22c75cf12f7d4d
\ No newline at end of file
+97f55815c01d3365e8dfb0ba7ff89bb78577d9f8
\ No newline at end of file
diff --git a/chrome/VERSION b/chrome/VERSION
index 0f6666f..971ec38 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=75
 MINOR=0
-BUILD=3741
+BUILD=3742
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
index 978437f..c303580 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
@@ -340,7 +340,7 @@
     }
 
     private void onRenameItem(OfflineItem item) {
-        // TODO(hesen): Add sanity check canRename for item, and add uma stats.
+        // TODO(hesen): Add uma stats.
         mRenameController.rename(item.title, (newName, renameCallback) -> {
             mProvider.renameItem(item, newName, renameCallback);
         });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCustomView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCustomView.java
index 7e3489d1..dd1080b86 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCustomView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCustomView.java
@@ -26,7 +26,7 @@
         super(context, attrs);
     }
 
-    // ScrollView Implementation
+    // ScrollView implementation.
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -58,8 +58,11 @@
             case RenameResult.FAILURE_NAME_TOO_LONG:
                 mSubtitleView.setText(R.string.rename_failure_name_too_long);
                 break;
-            case RenameResult.FAILURE_UNKNOWN:
-                mSubtitleView.setText(R.string.rename_failure_name_unavailable);
+            case RenameResult.FAILURE_NAME_INVALID:
+                mSubtitleView.setText(R.string.rename_failure_name_invalid);
+                break;
+            case RenameResult.FAILURE_UNAVAILABLE:
+                mSubtitleView.setText(R.string.rename_failure_unavailable);
                 break;
             default:
                 break;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FreIntentCreator.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FreIntentCreator.java
index 228ea6fd..feda30e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FreIntentCreator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FreIntentCreator.java
@@ -10,11 +10,13 @@
 import android.content.Intent;
 import android.content.res.TypedArray;
 import android.os.Bundle;
+import android.support.annotation.Nullable;
 import android.text.TextUtils;
 
 import org.chromium.base.ApplicationStatus;
 import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.LaunchIntentDispatcher;
+import org.chromium.chrome.browser.webapps.WebApkInfo;
 import org.chromium.chrome.browser.webapps.WebappLauncherActivity;
 import org.chromium.ui.base.DeviceFormFactor;
 
@@ -36,21 +38,17 @@
      */
     public Intent create(Context caller, Intent fromIntent, boolean requiresBroadcast,
             boolean preferLightweightFre) {
-        Intent intentToLaunchAfterFreComplete = fromIntent;
-        String associatedAppNameForLightweightFre = null;
-        WebappLauncherActivity.FreParams webApkFreParams =
-                WebappLauncherActivity.slowGenerateFreParamsIfIntentIsForWebApk(fromIntent);
-        if (webApkFreParams != null) {
-            intentToLaunchAfterFreComplete = webApkFreParams.getIntentToLaunchAfterFreComplete();
-            associatedAppNameForLightweightFre = webApkFreParams.webApkShortName();
-        }
+        @Nullable WebApkInfo webApkInfo =
+                WebappLauncherActivity.maybeSlowlyGenerateWebApkInfoFromIntent(fromIntent);
+        Intent intentToLaunchAfterFreComplete = (webApkInfo == null)
+                ? fromIntent
+                : WebappLauncherActivity.createRelaunchWebApkIntent(fromIntent, webApkInfo);
 
         // Launch the Generic First Run Experience if it was previously active.
         boolean isGenericFreActive = checkIsGenericFreActive();
         if (preferLightweightFre && !isGenericFreActive) {
-            return createLightweightFirstRunIntent(caller, fromIntent,
-                    associatedAppNameForLightweightFre, intentToLaunchAfterFreComplete,
-                    requiresBroadcast);
+            return createLightweightFirstRunIntent(caller, fromIntent, webApkInfo,
+                    intentToLaunchAfterFreComplete, requiresBroadcast);
         } else {
             return createGenericFirstRunIntent(
                     caller, fromIntent, intentToLaunchAfterFreComplete, requiresBroadcast);
@@ -61,19 +59,19 @@
      * Returns an intent to show the lightweight first run activity.
      * @param context                        The context.
      * @param fromIntent                     The intent that was used to launch Chrome.
-     * @param associatedAppName              The id of the application associated with the activity
-     *                                       being launched.
+     * @param webApkInfo                     An optional WebApkInfo if this FRE flow was triggered
+     *                                       by launching a WebAPK.
      * @param intentToLaunchAfterFreComplete The intent to launch when the user completes the FRE.
      * @param requiresBroadcast              Whether the relaunch intent must be broadcasted.
      */
     private static Intent createLightweightFirstRunIntent(Context context, Intent fromIntent,
-            String associatedAppName, Intent intentToLaunchAfterFreComplete,
+            @Nullable WebApkInfo webApkInfo, Intent intentToLaunchAfterFreComplete,
             boolean requiresBroadcast) {
         Intent intent = new Intent();
         intent.setClassName(context, LightweightFirstRunActivity.class.getName());
-        if (associatedAppName != null) {
-            intent.putExtra(
-                    LightweightFirstRunActivity.EXTRA_ASSOCIATED_APP_NAME, associatedAppName);
+        String webApkShortName = webApkInfo == null ? null : webApkInfo.shortName();
+        if (webApkShortName != null) {
+            intent.putExtra(LightweightFirstRunActivity.EXTRA_ASSOCIATED_APP_NAME, webApkShortName);
         }
         addPendingIntent(context, intent, intentToLaunchAfterFreComplete, requiresBroadcast);
         return intent;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java
index a2691b7..5524d42 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java
@@ -14,6 +14,7 @@
 import android.os.StrictMode;
 import android.os.SystemClock;
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.text.TextUtils;
 import android.util.Base64;
 
@@ -56,27 +57,6 @@
 
     private static final String TAG = "webapps";
 
-    /** WebAPK first run experience parameters. */
-    public static class FreParams {
-        private final Intent mIntentToLaunchAfterFreComplete;
-        private final String mShortName;
-
-        public FreParams(Intent intentToLaunchAfterFreComplete, String shortName) {
-            mIntentToLaunchAfterFreComplete = intentToLaunchAfterFreComplete;
-            mShortName = shortName;
-        }
-
-        /** Returns the intent launch when the user completes the first run experience. */
-        public Intent getIntentToLaunchAfterFreComplete() {
-            return mIntentToLaunchAfterFreComplete;
-        }
-
-        /** Returns the WebAPK's short name. */
-        public String webApkShortName() {
-            return mShortName;
-        }
-    }
-
     /** Creates intent to relaunch WebAPK. */
     public static Intent createRelaunchWebApkIntent(Intent sourceIntent, WebApkInfo webApkInfo) {
         assert webApkInfo != null;
@@ -112,7 +92,7 @@
      * if the intent does not launch either a WebappLauncherActivity or a WebApkActivity. This
      * method is slow. It makes several PackageManager calls.
      */
-    public static FreParams slowGenerateFreParamsIfIntentIsForWebApk(Intent fromIntent) {
+    public static @Nullable WebApkInfo maybeSlowlyGenerateWebApkInfoFromIntent(Intent fromIntent) {
         // Check for intents targeted at WebApkActivity, WebApkActivity0-9,
         // SameTaskWebApkActivity and WebappLauncherActivity.
         String targetActivityClassName = fromIntent.getComponent().getClassName();
@@ -122,10 +102,7 @@
             return null;
         }
 
-        WebApkInfo info = WebApkInfo.create(fromIntent);
-        return (info != null)
-                ? new FreParams(createRelaunchWebApkIntent(fromIntent, info), info.shortName())
-                : null;
+        return WebApkInfo.create(fromIntent);
     }
 
     @Override
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index de7e7f9..333489b 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1471,8 +1471,11 @@
       <message name="IDS_RENAME_FAILURE_NAME_TOO_LONG" desc="Subtitle for rename dialog in the case that rename attempt failed because the target name is too long.">
        Name is too long
       </message>
-      <message name="IDS_RENAME_FAILURE_NAME_UNAVAILABLE" desc="Subtitle for rename dialog in the case that rename attempt failed because the target name is unavailable.">
-       Name is unavailable
+      <message name="IDS_RENAME_FAILURE_NAME_INVALID" desc="Subtitle for rename dialog in the case that rename attempt failed because the target name is invalid.">
+       Name is invalid
+      </message>
+      <message name="IDS_RENAME_FAILURE_UNAVAILABLE" desc="Subtitle for rename dialog in the case that rename attempt failed because the item is unavailable.">
+       Rename unavailable
       </message>
 
       <!-- About Chrome preferences -->
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/ui/iph/KeyFunctionsIPHMediator.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/ui/iph/KeyFunctionsIPHMediator.java
index f2b5d826..58028bf 100644
--- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/ui/iph/KeyFunctionsIPHMediator.java
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/ui/iph/KeyFunctionsIPHMediator.java
@@ -8,7 +8,7 @@
 import org.chromium.chrome.browser.ActivityTabProvider;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
-import org.chromium.ui.base.CursorVisibilityObserver;
+import org.chromium.ui.base.CursorObserver;
 import org.chromium.ui.base.TouchlessEventHandler;
 import org.chromium.ui.modelutil.PropertyModel;
 
@@ -17,7 +17,7 @@
 /**
  * Controls the UI model for key functions IPH.
  */
-public class KeyFunctionsIPHMediator implements CursorVisibilityObserver {
+public class KeyFunctionsIPHMediator implements CursorObserver {
     private final PropertyModel mModel;
     private final KeyFunctionsIPHTabObserver mKeyFunctionsIPHTabObserver;
     private FutureTask mHideTask;
@@ -29,23 +29,26 @@
     KeyFunctionsIPHMediator(PropertyModel model, ActivityTabProvider activityTabProvider) {
         mModel = model;
         mKeyFunctionsIPHTabObserver = new KeyFunctionsIPHTabObserver(activityTabProvider);
-        TouchlessEventHandler.addCursorVisibilityObserver(this);
+        TouchlessEventHandler.addCursorObserver(this);
     }
 
     @Override
-    public void onCursorVisibilityChanged(boolean isCursorVisible) {
-        show(isCursorVisible);
+    public void onCursorVisibilityChanged(boolean isCursorVisible) {}
+
+    @Override
+    public void onFallbackCursorModeToggled(boolean isOn) {
+        show(isOn);
     }
 
-    private void show(boolean isCursorVisible) {
+    private void show(boolean isFallbackCursorModeOn) {
         // TODO(crbug.com/942665): Populate this.
         boolean pageOptimizedForMobile = true;
-        if ((!isCursorVisible && mHasShownOnSpatNav && pageOptimizedForMobile)
-                || (isCursorVisible && mHasShownOnFallback)) {
+        if ((!isFallbackCursorModeOn && mHasShownOnSpatNav && pageOptimizedForMobile)
+                || (isFallbackCursorModeOn && mHasShownOnFallback)) {
             return;
         }
 
-        if (isCursorVisible) {
+        if (isFallbackCursorModeOn) {
             mHasShownOnFallback = true;
         } else {
             mHasShownOnSpatNav = true;
@@ -56,12 +59,12 @@
             return null;
         });
         PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, mHideTask, DISPLAY_DURATION_MS);
-        mModel.set(KeyFunctionsIPHProperties.IS_CURSOR_VISIBLE, isCursorVisible);
+        mModel.set(KeyFunctionsIPHProperties.IS_CURSOR_VISIBLE, isFallbackCursorModeOn);
         mModel.set(KeyFunctionsIPHProperties.IS_VISIBLE, true);
     }
 
     void destroy() {
-        TouchlessEventHandler.removeCursorVisibilityObserver(this);
+        TouchlessEventHandler.removeCursorObserver(this);
         mKeyFunctionsIPHTabObserver.destroy();
         if (mHideTask != null) mHideTask.cancel(false);
     }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 165ea5c9..098e409 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -8824,6 +8824,9 @@
       <message name="IDS_DEVICE_LOG_TYPE_PRINTER" desc="Checkbox to enable showing events of type Printer">
         Printer
       </message>
+      <message name="IDS_DEVICE_LOG_TYPE_FIDO" desc="Checkbox to enable showing events related to security keys, which is physical devices used by users to log in to websites. It's called FIDO in English because that's the name of the standards body that defines security keys">
+        FIDO
+      </message>
       <message name="IDS_DEVICE_LOG_FILEINFO" desc="File info checkbox in device event log">
         File Info
       </message>
@@ -8866,7 +8869,7 @@
     <if expr="chromeos">
       <!-- CrOSUsb Notification -->
       <message name="IDS_CROSUSB_DEVICE_DETECTED_NOTIFICATION" desc="Content for notification shown to the user when a USB device gets plugged in.">
-        Connect <ph name="USB_DEVICE_NAME">$1<ex>Nexus 5</ex></ph> to Linux
+        Open Settings to connect <ph name="USB_DEVICE_NAME">$1<ex>Nexus 5</ex></ph> to Linux
       </message>
       <message name="IDS_CROSUSB_DEVICE_DETECTED_NOTIFICATION_TITLE" desc="Title for notification shown to the user when a USB device gets plugged in.">
         USB device detected
@@ -8874,9 +8877,6 @@
       <message name="IDS_CROSUSB_NOTIFICATION_BUTTON_CONNECT_TO_LINUX" desc="Label for notification button shown to the user when a USB device gets plugged in to allowed Linux to use the device">
         Connect
       </message>
-      <message name="IDS_CROSUSB_NOTIFICATION_BUTTON_VIEW_SETTINGS" desc="Label for notification button shown to the user when a USB device gets plugged in to view settings in the Settings app">
-        View Settings
-      </message>
       <message name="IDS_CROSUSB_UNKNOWN_DEVICE_FROM_MANUFACTURER" desc="String describing an unknown device in notification shown when a USB device gets plugged in.">
         USB device from <ph name="MANUFACTURER_NAME">$1<ex>Google</ex></ph>
       </message>
diff --git a/chrome/browser/android/download/download_manager_service.cc b/chrome/browser/android/download/download_manager_service.cc
index 2b7f626..011c9ec 100644
--- a/chrome/browser/android/download/download_manager_service.cc
+++ b/chrome/browser/android/download/download_manager_service.cc
@@ -783,24 +783,14 @@
     const JavaParamRef<jobject>& j_callback,
     bool is_off_the_record) {
   std::string download_guid = ConvertJavaStringToUTF8(id);
-  content::DownloadManager* manager = GetDownloadManager(is_off_the_record);
-  if (!manager) {
+  download::DownloadItem* item = GetDownload(download_guid, is_off_the_record);
+  if (!item) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::BindOnce(
             &RenameItemCallback,
             base::android::ScopedJavaGlobalRef<jobject>(env, j_callback),
-            download::DownloadItem::DownloadRenameResult::FAILURE_UNKNOWN));
-    return;
-  }
-  download::DownloadItem* item = manager->GetDownloadByGuid(download_guid);
-  if (!item) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(&RenameItemCallback,
-                                  base::android::ScopedJavaGlobalRef<jobject>(
-                                      env, j_callback),
-                                  download::DownloadItem::DownloadRenameResult::
-                                      FAILURE_NAME_UNAVIALABLE));
+            download::DownloadItem::DownloadRenameResult::FAILURE_UNAVAILABLE));
 
     return;
   }
@@ -809,7 +799,7 @@
       callback = base::BindOnce(
           &RenameItemCallback,
           base::android::ScopedJavaGlobalRef<jobject>(env, j_callback));
-  item->Rename(target_name, std::move(callback));
+  item->Rename(base::FilePath(target_name), std::move(callback));
 }
 
 void DownloadManagerService::CreateInterruptedDownloadForTest(
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc
index fa44872..20d85edb 100644
--- a/chrome/browser/android/tab_web_contents_delegate_android.cc
+++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -458,9 +458,8 @@
   SecurityStateTabHelper* helper =
       SecurityStateTabHelper::FromWebContents(web_contents);
   DCHECK(helper);
-  security_state::SecurityInfo security_info;
-  helper->GetSecurityInfo(&security_info);
-  return security_state::GetSecurityStyle(security_info,
+  return security_state::GetSecurityStyle(helper->GetSecurityLevel(),
+                                          *helper->GetVisibleSecurityState(),
                                           security_style_explanations);
 }
 
diff --git a/chrome/browser/chrome_site_per_process_browsertest.cc b/chrome/browser/chrome_site_per_process_browsertest.cc
index 38ceccd..9f409da 100644
--- a/chrome/browser/chrome_site_per_process_browsertest.cc
+++ b/chrome/browser/chrome_site_per_process_browsertest.cc
@@ -1086,6 +1086,12 @@
 
 // Tests that after disabling spellchecking, spelling in new out-of-process
 // subframes is not checked. See crbug.com/789273 for details.
+// https://crbug.com/944428
+#if defined(OS_MACOSX)
+#define MAYBE_OOPIFDisabledSpellCheckTest DISABLED_OOPIFDisabledSpellCheckTest
+#else
+#define MAYBE_OOPIFDisabledSpellCheckTest OOPIFDisabledSpellCheckTest
+#endif
 IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, OOPIFDisabledSpellCheckTest) {
   TestBrowserClientForSpellCheck browser_client;
   content::ContentBrowserClient* old_browser_client =
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 61dac79..08a3d12 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -526,6 +526,7 @@
 #endif
         TestCase("openQuickViewKeyboardUpDownChangesView"),
         TestCase("openQuickViewKeyboardLeftRightChangesView"),
+        TestCase("openQuickViewSniffedText"),
         TestCase("openQuickViewScrollText"),
         TestCase("openQuickViewScrollHtml"),
         TestCase("openQuickViewBackgroundColorText"),
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/adapter.cc b/chrome/browser/chromeos/power/auto_screen_brightness/adapter.cc
index 78e91a09..97cd9e0a 100644
--- a/chrome/browser/chromeos/power/auto_screen_brightness/adapter.cc
+++ b/chrome/browser/chromeos/power/auto_screen_brightness/adapter.cc
@@ -222,14 +222,10 @@
   return personal_curve_;
 }
 
-base::Optional<double> Adapter::GetAverageAmbientForTesting(
+base::Optional<AlsAvgStdDev> Adapter::GetAverageAmbientWithStdDevForTesting(
     base::TimeTicks now) {
   DCHECK(ambient_light_values_);
-  const base::Optional<double> avg = ambient_light_values_->AverageAmbient(now);
-  if (!avg)
-    return base::nullopt;
-
-  return ConvertToLog(avg.value());
+  return ambient_light_values_->AverageAmbientWithStdDev(now);
 }
 
 double Adapter::GetBrighteningThresholdForTesting() const {
@@ -390,13 +386,12 @@
 
 void Adapter::MaybeAdjustBrightness(base::TimeTicks now) {
   DCHECK(ambient_light_values_);
-  const base::Optional<double> average_ambient_lux_opt =
-      ambient_light_values_->AverageAmbient(now);
-  if (!average_ambient_lux_opt)
+  const base::Optional<AlsAvgStdDev> als_avg_stddev =
+      ambient_light_values_->AverageAmbientWithStdDev(now);
+  if (!als_avg_stddev)
     return;
 
-  const double log_average_ambient_lux =
-      ConvertToLog(average_ambient_lux_opt.value());
+  const double log_average_ambient_lux = ConvertToLog(als_avg_stddev->avg);
 
   const base::Optional<BrightnessChangeCause> brightness_change_cause =
       CanAdjustBrightness(log_average_ambient_lux);
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/adapter.h b/chrome/browser/chromeos/power/auto_screen_brightness/adapter.h
index 51df676..4a75d2f 100644
--- a/chrome/browser/chromeos/power/auto_screen_brightness/adapter.h
+++ b/chrome/browser/chromeos/power/auto_screen_brightness/adapter.h
@@ -154,8 +154,9 @@
   base::Optional<MonotoneCubicSpline> GetGlobalCurveForTesting() const;
   base::Optional<MonotoneCubicSpline> GetPersonalCurveForTesting() const;
 
-  // Returns the actual log average over |ambient_light_values_|.
-  base::Optional<double> GetAverageAmbientForTesting(base::TimeTicks now);
+  // Returns the average and std-dev over |ambient_light_values_|.
+  base::Optional<AlsAvgStdDev> GetAverageAmbientWithStdDevForTesting(
+      base::TimeTicks now);
   double GetBrighteningThresholdForTesting() const;
   double GetDarkeningThresholdForTesting() const;
 
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/adapter_unittest.cc b/chrome/browser/chromeos/power/auto_screen_brightness/adapter_unittest.cc
index 8415c73..febce768a 100644
--- a/chrome/browser/chromeos/power/auto_screen_brightness/adapter_unittest.cc
+++ b/chrome/browser/chromeos/power/auto_screen_brightness/adapter_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/power/auto_screen_brightness/adapter.h"
 
 #include <map>
+#include <vector>
 
 #include "ash/public/cpp/ash_pref_names.h"
 #include "base/memory/ptr_util.h"
@@ -39,6 +40,27 @@
 
 namespace {
 
+// Checks |result.avg| and |result.stddev| are the same as that
+// calculated from the |expected_data|.
+void CheckAverageAndStdDev(const AlsAvgStdDev& result,
+                           const std::vector<double>& expected_data) {
+  const size_t count = expected_data.size();
+  CHECK_NE(count, 0u);
+  double expected_avg = 0;
+  double expected_stddev = 0;
+
+  for (const auto& i : expected_data) {
+    expected_avg += i;
+    expected_stddev += i * i;
+  }
+
+  expected_avg = expected_avg / count;
+  expected_stddev =
+      std::sqrt(expected_stddev / count - expected_avg * expected_avg);
+  EXPECT_DOUBLE_EQ(result.avg, expected_avg);
+  EXPECT_DOUBLE_EQ(result.stddev, expected_stddev);
+}
+
 // Testing modeller.
 class FakeModeller : public Modeller {
  public:
@@ -450,8 +472,11 @@
   fake_als_reader_.ReportAmbientLightUpdate(10);
   thread_bundle_.RunUntilIdle();
   EXPECT_EQ(test_observer_.num_changes(), 1);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            ConvertToLog(10.0));
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {10});
+
   EXPECT_DOUBLE_EQ(adapter_->GetBrighteningThresholdForTesting(),
                    ConvertToLog(10.0) + 0.1);
   EXPECT_DOUBLE_EQ(adapter_->GetDarkeningThresholdForTesting(),
@@ -461,8 +486,11 @@
   fake_als_reader_.ReportAmbientLightUpdate(20);
   thread_bundle_.RunUntilIdle();
   EXPECT_EQ(test_observer_.num_changes(), 2);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            ConvertToLog(15.0));
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {10, 20});
+
   EXPECT_DOUBLE_EQ(adapter_->GetBrighteningThresholdForTesting(),
                    ConvertToLog(15.0) + 0.1);
   EXPECT_DOUBLE_EQ(adapter_->GetDarkeningThresholdForTesting(),
@@ -473,7 +501,8 @@
   // triggered.
   thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(10));
   EXPECT_EQ(test_observer_.num_changes(), 2);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
+  EXPECT_EQ(adapter_->GetAverageAmbientWithStdDevForTesting(
+                thread_bundle_.NowTicks()),
             base::nullopt);
 
   // A new ALS value triggers a brightness change.
@@ -481,8 +510,11 @@
   fake_als_reader_.ReportAmbientLightUpdate(40);
   thread_bundle_.RunUntilIdle();
   EXPECT_EQ(test_observer_.num_changes(), 3);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            ConvertToLog(40));
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {40});
+
   EXPECT_DOUBLE_EQ(adapter_->GetBrighteningThresholdForTesting(),
                    ConvertToLog(40.0) + 0.1);
   EXPECT_DOUBLE_EQ(adapter_->GetDarkeningThresholdForTesting(),
@@ -556,10 +588,13 @@
   // changed.
   fake_als_reader_.ReportAmbientLightUpdate(20);
   thread_bundle_.RunUntilIdle();
-  double expected_log_avg = ConvertToLog(20);
   EXPECT_EQ(test_observer_.num_changes(), 1);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            expected_log_avg);
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {20});
+
+  double expected_log_avg = ConvertToLog(20);
   double expected_brightening_threshold = expected_log_avg + 1;
   double expected_darkening_threshold = expected_log_avg - 0.2;
   EXPECT_DOUBLE_EQ(adapter_->GetBrighteningThresholdForTesting(),
@@ -573,8 +608,11 @@
   fake_als_reader_.ReportAmbientLightUpdate(21);
   thread_bundle_.RunUntilIdle();
   EXPECT_EQ(1, test_observer_.num_changes());
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            ConvertToLog((20 + 21) / 2.0));
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {20, 21});
+
   EXPECT_DOUBLE_EQ(adapter_->GetBrighteningThresholdForTesting(),
                    expected_brightening_threshold);
   EXPECT_DOUBLE_EQ(adapter_->GetDarkeningThresholdForTesting(),
@@ -585,8 +623,11 @@
   fake_als_reader_.ReportAmbientLightUpdate(15);
   thread_bundle_.RunUntilIdle();
   EXPECT_EQ(test_observer_.num_changes(), 1);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            ConvertToLog((20 + 21 + 15) / 3.0));
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {20, 21, 15});
+
   EXPECT_DOUBLE_EQ(adapter_->GetBrighteningThresholdForTesting(),
                    expected_brightening_threshold);
   EXPECT_DOUBLE_EQ(adapter_->GetDarkeningThresholdForTesting(),
@@ -599,8 +640,11 @@
   thread_bundle_.RunUntilIdle();
   EXPECT_EQ(test_observer_.num_changes(), 2);
   expected_log_avg = ConvertToLog((20 + 21 + 15 + 5) / 4.0);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            expected_log_avg);
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {20, 21, 15, 5});
+
   EXPECT_DOUBLE_EQ(adapter_->GetBrighteningThresholdForTesting(),
                    expected_log_avg + 1);
   EXPECT_DOUBLE_EQ(adapter_->GetDarkeningThresholdForTesting(),
@@ -609,15 +653,19 @@
   thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(1));
   fake_als_reader_.ReportAmbientLightUpdate(8);
   thread_bundle_.RunUntilIdle();
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            ConvertToLog((20 + 21 + 15 + 5 + 8) / 5.0));
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {20, 21, 15, 5, 8});
 
   thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(1));
   fake_als_reader_.ReportAmbientLightUpdate(9);
   thread_bundle_.RunUntilIdle();
 
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            ConvertToLog((21 + 15 + 5 + 8 + 9) / 5.0));
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {21, 15, 5, 8, 9});
 }
 
 TEST_F(AdapterTest, UsePersonalCurve) {
@@ -649,8 +697,11 @@
             power_manager::BacklightBrightnessChange_Cause_MODEL);
 
   const double expected_log_avg = ConvertToLog((10 + 20) / 2.0);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            expected_log_avg);
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {10, 20});
+
   const double expected_brightness_percent =
       personal_curve_->Interpolate(expected_log_avg);
   EXPECT_DOUBLE_EQ(test_observer_.GetBrightnessPercent(),
@@ -671,8 +722,10 @@
   thread_bundle_.RunUntilIdle();
   EXPECT_EQ(test_observer_.num_changes(), 1);
   const double expected_log_avg1 = ConvertToLog(10);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            expected_log_avg1);
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {10});
 
   const double expected_brightness_percent1 =
       global_curve_->Interpolate(expected_log_avg1);
@@ -689,8 +742,10 @@
             power_manager::BacklightBrightnessChange_Cause_MODEL);
 
   const double expected_log_avg2 = ConvertToLog(20);
-  EXPECT_EQ(adapter_->GetAverageAmbientForTesting(thread_bundle_.NowTicks()),
-            expected_log_avg2);
+  CheckAverageAndStdDev(
+      adapter_->GetAverageAmbientWithStdDevForTesting(thread_bundle_.NowTicks())
+          .value(),
+      {20});
   const double expected_brightness_percent2 =
       global_curve_->Interpolate(expected_log_avg2);
   EXPECT_DOUBLE_EQ(test_observer_.GetBrightnessPercent(),
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/als_samples.cc b/chrome/browser/chromeos/power/auto_screen_brightness/als_samples.cc
index e2c14f5b..410370dd 100644
--- a/chrome/browser/chromeos/power/auto_screen_brightness/als_samples.cc
+++ b/chrome/browser/chromeos/power/auto_screen_brightness/als_samples.cc
@@ -25,20 +25,23 @@
   Prune(sample.sample_time);
 }
 
-base::Optional<double> AmbientLightSampleBuffer::AverageAmbient(
+base::Optional<AlsAvgStdDev> AmbientLightSampleBuffer::AverageAmbientWithStdDev(
     base::TimeTicks now) {
-  const auto add_lux = [](double lux, const Sample& sample) {
-    return lux + sample.lux;
-  };
-
   Prune(now);
-
-  if (samples_.empty()) {
+  if (samples_.empty())
     return base::nullopt;
-  } else {
-    return std::accumulate(samples_.begin(), samples_.end(), 0.0, add_lux) /
-           samples_.size();
+
+  const size_t count = samples_.size();
+  double avg = 0;
+  double stddev = 0;
+  for (const auto& sample : samples_) {
+    avg += sample.lux;
+    stddev += sample.lux * sample.lux;
   }
+
+  avg = avg / count;
+  return base::Optional<AlsAvgStdDev>(
+      {avg, std::sqrt(stddev / count - avg * avg)});
 }
 
 size_t AmbientLightSampleBuffer::NumberOfSamples(base::TimeTicks now) {
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/als_samples.h b/chrome/browser/chromeos/power/auto_screen_brightness/als_samples.h
index ee98d85..525d2fee 100644
--- a/chrome/browser/chromeos/power/auto_screen_brightness/als_samples.h
+++ b/chrome/browser/chromeos/power/auto_screen_brightness/als_samples.h
@@ -14,6 +14,11 @@
 namespace power {
 namespace auto_screen_brightness {
 
+struct AlsAvgStdDev {
+  double avg = 0;
+  double stddev = 0;
+};
+
 // AmbientLightSampleBuffer stores most recent ambient light samples, with
 // horizon defined in its ctor.
 class AmbientLightSampleBuffer {
@@ -32,10 +37,10 @@
   // |sample| must be later than any previously added sample.
   void SaveToBuffer(const Sample& sample);
 
-  // Returns average ambient lux from the buffer (discarding samples that are
-  // now too old). |now| must be no earlier than any previously added sample. If
-  // there are no valid samples, returns nullopt.
-  base::Optional<double> AverageAmbient(base::TimeTicks now);
+  // Returns average and std-dev of ambient lux from the buffer (discarding
+  // samples that are now too old). |now| must be no earlier than any previously
+  // added sample. If there are no valid samples, returns nullopt.
+  base::Optional<AlsAvgStdDev> AverageAmbientWithStdDev(base::TimeTicks now);
 
   // Returns the number of recorded samples within |horizon| of the last
   // observed time point. |now| must be no earlier than any previously added
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/als_samples_unittest.cc b/chrome/browser/chromeos/power/auto_screen_brightness/als_samples_unittest.cc
index 1ecce941..8ed98808f 100644
--- a/chrome/browser/chromeos/power/auto_screen_brightness/als_samples_unittest.cc
+++ b/chrome/browser/chromeos/power/auto_screen_brightness/als_samples_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/power/auto_screen_brightness/als_samples.h"
 
 #include <cmath>
+#include <vector>
 
 #include "base/logging.h"
 #include "base/test/simple_test_tick_clock.h"
@@ -15,45 +16,74 @@
 namespace power {
 namespace auto_screen_brightness {
 
+namespace {
+
+// Checks |result.avg| and |result.stddev| are the same as that
+// calculated from the |expected_data| vector.
+void CheckAverageAndStdDev(const AlsAvgStdDev& result,
+                           const std::vector<double>& expected_data) {
+  const size_t count = expected_data.size();
+  CHECK_NE(count, 0u);
+  double expected_avg = 0;
+  double expected_stddev = 0;
+
+  for (const auto& i : expected_data) {
+    expected_avg += i;
+    expected_stddev += i * i;
+  }
+
+  expected_avg = expected_avg / count;
+  expected_stddev =
+      std::sqrt(expected_stddev / count - expected_avg * expected_avg);
+  EXPECT_DOUBLE_EQ(result.avg, expected_avg);
+  EXPECT_DOUBLE_EQ(result.stddev, expected_stddev);
+}
+
+}  // namespace
+
 TEST(AmbientLightSampleBufferTest, Basic) {
   base::SimpleTestTickClock tick_clock;
   AmbientLightSampleBuffer buffer(base::TimeDelta::FromSeconds(5));
-  double sum = 0;
+  std::vector<double> expected_data;
   for (int i = 1; i < 6; ++i) {
     tick_clock.Advance(base::TimeDelta::FromSeconds(1));
     const AmbientLightSampleBuffer::Sample sample = {i, tick_clock.NowTicks()};
-    sum += i;
+    expected_data.push_back(i);
     buffer.SaveToBuffer(sample);
     EXPECT_EQ(buffer.NumberOfSamplesForTesting(), static_cast<size_t>(i));
-    EXPECT_DOUBLE_EQ(buffer.AverageAmbient(tick_clock.NowTicks()).value(),
-                     sum / i);
+    const AlsAvgStdDev avg_std =
+        buffer.AverageAmbientWithStdDev(tick_clock.NowTicks()).value();
+
+    CheckAverageAndStdDev(avg_std, expected_data);
+
     EXPECT_EQ(buffer.NumberOfSamplesForTesting(), static_cast<size_t>(i));
   }
 
   // Add another two items that will push out the oldest.
   tick_clock.Advance(base::TimeDelta::FromSeconds(1));
   buffer.SaveToBuffer({10, tick_clock.NowTicks()});
-  sum = sum - 1 + 10;
+
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 5u);
-  EXPECT_DOUBLE_EQ(buffer.AverageAmbient(tick_clock.NowTicks()).value(),
-                   sum / 5);
+  CheckAverageAndStdDev(
+      buffer.AverageAmbientWithStdDev(tick_clock.NowTicks()).value(),
+      {2, 3, 4, 5, 10});
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 5u);
 
   tick_clock.Advance(base::TimeDelta::FromSeconds(1));
   buffer.SaveToBuffer({20, tick_clock.NowTicks()});
-  sum = sum - 2 + 20;
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 5u);
-  EXPECT_DOUBLE_EQ(buffer.AverageAmbient(tick_clock.NowTicks()).value(),
-                   sum / 5);
+  CheckAverageAndStdDev(
+      buffer.AverageAmbientWithStdDev(tick_clock.NowTicks()).value(),
+      {3, 4, 5, 10, 20});
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 5u);
 
   // Add another item but it doesn't push out the oldest.
   tick_clock.Advance(base::TimeDelta::FromMilliseconds(1));
   buffer.SaveToBuffer({100, tick_clock.NowTicks()});
-  sum += 100;
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 6u);
-  EXPECT_DOUBLE_EQ(buffer.AverageAmbient(tick_clock.NowTicks()).value(),
-                   sum / 6);
+  CheckAverageAndStdDev(
+      buffer.AverageAmbientWithStdDev(tick_clock.NowTicks()).value(),
+      {3, 4, 5, 10, 20, 100});
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 6u);
 }
 
@@ -64,14 +94,16 @@
   const AmbientLightSampleBuffer::Sample sample = {10, tick_clock.NowTicks()};
   buffer.SaveToBuffer(sample);
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 1u);
-  EXPECT_DOUBLE_EQ(buffer.AverageAmbient(tick_clock.NowTicks()).value(), 10.0);
+  CheckAverageAndStdDev(
+      buffer.AverageAmbientWithStdDev(tick_clock.NowTicks()).value(), {10});
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 1u);
 
   // Another samples arrives sufficiently late so the 1st sample is pushed out.
   tick_clock.Advance(base::TimeDelta::FromSeconds(5));
   buffer.SaveToBuffer({20, tick_clock.NowTicks()});
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 1u);
-  EXPECT_DOUBLE_EQ(buffer.AverageAmbient(tick_clock.NowTicks()).value(), 20);
+  CheckAverageAndStdDev(
+      buffer.AverageAmbientWithStdDev(tick_clock.NowTicks()).value(), {20});
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 1u);
 }
 
@@ -82,14 +114,16 @@
   const AmbientLightSampleBuffer::Sample sample = {10, tick_clock.NowTicks()};
   buffer.SaveToBuffer(sample);
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 1u);
-  EXPECT_DOUBLE_EQ(buffer.AverageAmbient(tick_clock.NowTicks()).value(), 10.0);
+  CheckAverageAndStdDev(
+      buffer.AverageAmbientWithStdDev(tick_clock.NowTicks()).value(), {10});
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 1u);
 
   // When average is calculated, all samples are too old, hence average is
   // nullopt.
   tick_clock.Advance(base::TimeDelta::FromSeconds(5));
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 1u);
-  EXPECT_FALSE(buffer.AverageAmbient(tick_clock.NowTicks()).has_value());
+  EXPECT_FALSE(
+      buffer.AverageAmbientWithStdDev(tick_clock.NowTicks()).has_value());
   EXPECT_EQ(buffer.NumberOfSamplesForTesting(), 0u);
 }
 
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc
index 5ebacaf0..418810c1 100644
--- a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc
+++ b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc
@@ -173,12 +173,12 @@
   DCHECK(ambient_light_values_);
   const base::TimeTicks now = tick_clock_->NowTicks();
   // We don't add any training data if there is no ambient light sample.
-  const base::Optional<double> average_ambient_lux_opt =
-      ambient_light_values_->AverageAmbient(now);
-  if (!average_ambient_lux_opt)
+  const base::Optional<AlsAvgStdDev> als_avg_stddev =
+      ambient_light_values_->AverageAmbientWithStdDev(now);
+  if (!als_avg_stddev)
     return;
 
-  const double average_ambient_lux = average_ambient_lux_opt.value();
+  const double average_ambient_lux = als_avg_stddev->avg;
   data_cache_.push_back({old_brightness_percent, new_brightness_percent,
                          ConvertToLog(average_ambient_lux), now});
 
@@ -226,7 +226,12 @@
     base::TimeTicks now) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(ambient_light_values_);
-  return ambient_light_values_->AverageAmbient(now);
+  const base::Optional<AlsAvgStdDev> als_avg_stddev =
+      ambient_light_values_->AverageAmbientWithStdDev(now);
+  if (!als_avg_stddev)
+    return base::nullopt;
+
+  return als_avg_stddev->avg;
 }
 
 size_t ModellerImpl::NumberTrainingDataPointsForTesting() const {
diff --git a/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager_unittest.cc b/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager_unittest.cc
index 85d20f2..b31f7a0 100644
--- a/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager_unittest.cc
+++ b/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager_unittest.cc
@@ -640,7 +640,9 @@
   tab_strip_model->CloseAllTabs();
 }
 
-TEST_F(AdaptiveScreenBrightnessManagerTest, MultipleBrowsersWithActive) {
+// Test is flaky. See https://crbug.com/944325.
+TEST_F(AdaptiveScreenBrightnessManagerTest,
+       DISABLED_MultipleBrowsersWithActive) {
   // Simulates three browsers:
   //  - browser1 is the last active but minimized, so not visible.
   //  - browser2 and browser3 are both visible but browser2 is the topmost.
diff --git a/chrome/browser/chromeos/usb/cros_usb_detector.cc b/chrome/browser/chromeos/usb/cros_usb_detector.cc
index ab564ab..52c5ba6 100644
--- a/chrome/browser/chromeos/usb/cros_usb_detector.cc
+++ b/chrome/browser/chromeos/usb/cros_usb_detector.cc
@@ -77,15 +77,10 @@
   void Click(const base::Optional<int>& button_index,
              const base::Optional<base::string16>& reply) override {
     disposition_ = CrosUsbNotificationClosed::kUnknown;
-    if (button_index) {
-      switch (button_index.value()) {
-        case 0:
-          HandleConnectToVm();
-          break;
-        case 1:
-          HandleShowSettings();
-          break;
-      }
+    if (button_index && button_index.value() == 0) {
+      HandleConnectToVm();
+    } else {
+      HandleShowSettings();
     }
   }
 
@@ -159,9 +154,6 @@
   rich_notification_data.buttons.emplace_back(
       message_center::ButtonInfo(l10n_util::GetStringUTF16(
           IDS_CROSUSB_NOTIFICATION_BUTTON_CONNECT_TO_LINUX)));
-  rich_notification_data.buttons.emplace_back(
-      message_center::ButtonInfo(l10n_util::GetStringUTF16(
-          IDS_CROSUSB_NOTIFICATION_BUTTON_VIEW_SETTINGS)));
 
   std::string notification_id =
       CrosUsbDetector::MakeNotificationId(device_info->guid);
diff --git a/chrome/browser/chromeos/usb/cros_usb_detector_unittest.cc b/chrome/browser/chromeos/usb/cros_usb_detector_unittest.cc
index 5ab7f4f..1dcbce8 100644
--- a/chrome/browser/chromeos/usb/cros_usb_detector_unittest.cc
+++ b/chrome/browser/chromeos/usb/cros_usb_detector_unittest.cc
@@ -155,8 +155,8 @@
 
  protected:
   base::string16 connection_message(const char* product_name) {
-    return base::ASCIIToUTF16(
-        base::StringPrintf("Connect %s to Linux", product_name));
+    return base::ASCIIToUTF16(base::StringPrintf(
+        "Open Settings to connect %s to Linux", product_name));
   }
 
   base::string16 expected_title() {
diff --git a/chrome/browser/download/download_offline_content_provider.cc b/chrome/browser/download/download_offline_content_provider.cc
index 0067d0d9..129ae8b 100644
--- a/chrome/browser/download/download_offline_content_provider.cc
+++ b/chrome/browser/download/download_offline_content_provider.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/browser/download/image_thumbnail_request.h"
@@ -123,7 +124,6 @@
   for (auto* item : all_items) {
     if (!ShouldShowDownloadItem(item))
       continue;
-
     items.push_back(OfflineItemUtils::CreateOfflineItem(name_space_, item));
   }
 
@@ -173,8 +173,8 @@
   DownloadItem* item = GetDownload(id.id);
   if (!item) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(std::move(callback),
-                                  RenameResult::FAILURE_NAME_UNAVIALABLE));
+        FROM_HERE,
+        base::BindOnce(std::move(callback), RenameResult::FAILURE_UNAVAILABLE));
     return;
   }
   download::DownloadItem::RenameDownloadCallback download_callback =
@@ -186,7 +186,13 @@
                     result));
           },
           std::move(callback));
-  item->Rename(name, std::move(download_callback));
+  base::FilePath::StringType filename;
+#if defined(OS_WIN)
+  filename = base::UTF8ToWide(name);
+#else
+  filename = name;
+#endif
+  item->Rename(base::FilePath(filename), std::move(download_callback));
 }
 
 void DownloadOfflineContentProvider::AddObserver(
diff --git a/chrome/browser/download/offline_item_utils.cc b/chrome/browser/download/offline_item_utils.cc
index d0a837d..3d51829 100644
--- a/chrome/browser/download/offline_item_utils.cc
+++ b/chrome/browser/download/offline_item_utils.cc
@@ -290,8 +290,10 @@
       return RenameResult::FAILURE_NAME_CONFLICT;
     case DownloadRenameResult::FAILURE_NAME_TOO_LONG:
       return RenameResult::FAILURE_NAME_TOO_LONG;
-    case DownloadRenameResult::FAILURE_NAME_UNAVIALABLE:
-      return RenameResult::FAILURE_NAME_UNAVIALABLE;
+    case DownloadRenameResult::FAILURE_NAME_INVALID:
+      return RenameResult::FAILURE_NAME_INVALID;
+    case DownloadRenameResult::FAILURE_UNAVAILABLE:
+      return RenameResult::FAILURE_UNAVAILABLE;
     case DownloadRenameResult::FAILURE_UNKNOWN:
       return RenameResult::FAILURE_UNKNOWN;
   }
diff --git a/chrome/browser/extensions/api/automation/automation_apitest.cc b/chrome/browser/extensions/api/automation/automation_apitest.cc
index 1e3cd80..5ca838d 100644
--- a/chrome/browser/extensions/api/automation/automation_apitest.cc
+++ b/chrome/browser/extensions/api/automation/automation_apitest.cc
@@ -142,7 +142,8 @@
   EXPECT_EQ(expected_mode, web_contents->GetAccessibilityMode());
 }
 
-IN_PROC_BROWSER_TEST_F(AutomationApiTest, GetTreeByTabId) {
+// TODO(aboxhall): Fix flakiness
+IN_PROC_BROWSER_TEST_F(AutomationApiTest, DISABLED_GetTreeByTabId) {
   StartEmbeddedTestServer();
   ASSERT_TRUE(RunExtensionSubtest("automation/tests/tabs", "tab_id.html"))
       << message_;
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
index 1d6446a..f6d148d 100644
--- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -560,6 +560,26 @@
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
+                       WebRequestAuthRequiredAsync) {
+  CancelLoginDialog login_dialog_helper;
+
+  ASSERT_TRUE(StartEmbeddedTestServer());
+  ASSERT_TRUE(
+      RunExtensionSubtest("webrequest", "test_auth_required_async.html"))
+      << message_;
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
+                       WebRequestAuthRequiredParallel) {
+  CancelLoginDialog login_dialog_helper;
+
+  ASSERT_TRUE(StartEmbeddedTestServer());
+  ASSERT_TRUE(
+      RunExtensionSubtest("webrequest", "test_auth_required_parallel.html"))
+      << message_;
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                        WebRequestAuthRequiredIncognito) {
   CancelLoginDialog login_dialog_helper;
 
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 6b8c6df00..15bce0cf 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -453,11 +453,6 @@
 #endif
 }
 
-void ChromePasswordManagerClient::HidePasswordGenerationPopup() {
-  if (popup_controller_)
-    popup_controller_->HideAndDestroy();
-}
-
 #if defined(FULL_SAFE_BROWSING)
 safe_browsing::PasswordProtectionService*
 ChromePasswordManagerClient::GetPasswordProtectionService() const {
@@ -737,9 +732,8 @@
 }
 
 void ChromePasswordManagerClient::PasswordGenerationRejectedByTyping() {
-  // TODO(crbug.com/835234):The call to hide the popup should be made for
-  // desktop only.
-  HidePasswordGenerationPopup();
+  if (popup_controller_)
+    popup_controller_->GeneratedPasswordRejected();
 }
 
 void ChromePasswordManagerClient::PresaveGeneratedPassword(
@@ -775,10 +769,15 @@
   if (controller &&
       controller->state() ==
           PasswordGenerationPopupController::kEditGeneratedPassword) {
-    HidePasswordGenerationPopup();
+    popup_controller_->GeneratedPasswordRejected();
   }
 }
 
+void ChromePasswordManagerClient::FrameWasScrolled() {
+  if (popup_controller_)
+    popup_controller_->FrameWasScrolled();
+}
+
 const GURL& ChromePasswordManagerClient::GetMainFrameURL() const {
   return web_contents()->GetVisibleURL();
 }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index ce8575a..b95dec1e 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -137,8 +137,7 @@
       const autofill::PasswordForm& password_form) override;
   void PasswordNoLongerGenerated(
       const autofill::PasswordForm& password_form) override;
-
-  void HidePasswordGenerationPopup();
+  void FrameWasScrolled() override;
 
 #if defined(FULL_SAFE_BROWSING)
   safe_browsing::PasswordProtectionService* GetPasswordProtectionService()
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/recovery_strategy_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/recovery_strategy_test.extjs
index 72e6398..502f7677 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/recovery_strategy_test.extjs
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/recovery_strategy_test.extjs
@@ -43,12 +43,18 @@
     var pTreePathRecovery = new TreePathRecoveryStrategy(p);
     var sTreePathRecovery = new TreePathRecoveryStrategy(s);
     this.listenOnce(b, 'clicked', function() {
-      assertFalse(bAncestryRecovery.requiresRecovery());
-      assertTrue(pAncestryRecovery.requiresRecovery());
-      assertTrue(sAncestryRecovery.requiresRecovery());
-      assertFalse(bTreePathRecovery.requiresRecovery());
-      assertTrue(pTreePathRecovery.requiresRecovery());
-      assertTrue(sTreePathRecovery.requiresRecovery());
+      assertFalse(bAncestryRecovery.requiresRecovery(),
+                  "bAncestryRecovery.requiresRecovery");
+      assertTrue(pAncestryRecovery.requiresRecovery(),
+                 "pAncestryRecovery.requiresRecovery()");
+      assertTrue(sAncestryRecovery.requiresRecovery(),
+                 "sAncestryRecovery.requiresRecovery()");
+      assertFalse(bTreePathRecovery.requiresRecovery(),
+                  "bTreePathRecovery.requiresRecovery()");
+      assertTrue(pTreePathRecovery.requiresRecovery(),
+                 "pTreePathRecovery.requiresRecovery()");
+      assertTrue(sTreePathRecovery.requiresRecovery(),
+                 "sTreePathRecovery.requiresRecovery()");
 
       assertEquals(RoleType.BUTTON, bAncestryRecovery.node.role);
       assertEquals(root, pAncestryRecovery.node);
@@ -58,12 +64,18 @@
       assertEquals(b, pTreePathRecovery.node);
       assertEquals(b, sTreePathRecovery.node);
 
-      assertFalse(bAncestryRecovery.requiresRecovery());
-      assertFalse(pAncestryRecovery.requiresRecovery());
-      assertFalse(sAncestryRecovery.requiresRecovery());
-      assertFalse(bTreePathRecovery.requiresRecovery());
-      assertFalse(pTreePathRecovery.requiresRecovery());
-      assertFalse(sTreePathRecovery.requiresRecovery());
+      assertFalse(bAncestryRecovery.requiresRecovery(),
+                  "bAncestryRecovery.requiresRecovery()");
+      assertFalse(pAncestryRecovery.requiresRecovery(),
+                  "pAncestryRecovery.requiresRecovery()");
+      assertFalse(sAncestryRecovery.requiresRecovery(),
+                  "sAncestryRecovery.requiresRecovery()");
+      assertFalse(bTreePathRecovery.requiresRecovery(),
+                  "bTreePathRecovery.requiresRecovery()");
+      assertFalse(pTreePathRecovery.requiresRecovery(),
+                  "pTreePathRecovery.requiresRecovery()");
+      assertFalse(sTreePathRecovery.requiresRecovery(),
+                  "sTreePathRecovery.requiresRecovery()");
     });
     // Trigger the change.
     b.doDefault();
diff --git a/chrome/browser/resources/chromeos/switch_access/switch_access_constants.js b/chrome/browser/resources/chromeos/switch_access/switch_access_constants.js
index bab3450..99b0514 100644
--- a/chrome/browser/resources/chromeos/switch_access/switch_access_constants.js
+++ b/chrome/browser/resources/chromeos/switch_access/switch_access_constants.js
@@ -49,16 +49,14 @@
    * @type {string}
    * @const
    */
-  PRIMARY_FOCUS_COLOR: '#8ab4f8',
+  PRIMARY_FOCUS_COLOR: '#8ab4f8b8',
 
   /**
    * The outer color of the focus rings.
-   * Temporarily does not match spec, as alpha is not yet configurable.
-   * TODO(anastasi): Set alpha as specified in the spec.
    * @type {string}
    * @const
    */
-  SECONDARY_FOCUS_COLOR: '#aaa',
+  SECONDARY_FOCUS_COLOR: '#0003',
 
   /**
    * The amount of space (in px) needed to fit a focus ring around an element.
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
index 170f706..b361532 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
@@ -71,6 +71,7 @@
   margin-top: 8px;
   overflow: hidden;
   pointer-events: auto;
+  position: relative;
   transition: border-top 130ms ease;
   user-select: none;
 }
@@ -96,7 +97,6 @@
   padding: 0 30px;
   position: relative;
   transition: all 500ms ease;
-  width: 100%;
 }
 
 .ink {
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_categories_list.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_categories_list.js
index 0e0a4c8..11c5c62 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_categories_list.js
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_categories_list.js
@@ -69,25 +69,31 @@
         cr.defineProperty(li, 'selected', cr.PropertyKind.BOOL_ATTR);
         var div = self.ownerDocument.createElement('div');
         div.textContent = entry;
+        var inkEl = self.ownerDocument.createElement('span');
+        inkEl.classList.add('ink');
+        li.appendChild(inkEl);
         li.appendChild(div);
-        div.addEventListener('mousedown', e => {
-          var targetEl = e.target;
-          var inkEl = targetEl.querySelector('.ink');
-          if (inkEl) {
-            inkEl.classList.remove('ripple-category-list-item-animation');
-          } else {
-            inkEl = document.createElement('span');
-            inkEl.classList.add('ink');
-            inkEl.style.width = inkEl.style.height =
-                Math.max(targetEl.offsetWidth, targetEl.offsetHeight) + 'px';
-            targetEl.appendChild(inkEl);
-          }
-          inkEl.style.left = (e.offsetX - 0.5 * inkEl.offsetWidth) + 'px';
-          inkEl.style.top = (e.offsetY - 0.5 * inkEl.offsetHeight) + 'px';
+        li.addEventListener('mousedown', e => {
+          var currentTarget = e.currentTarget;
+          var inkEl = currentTarget.querySelector('.ink');
+          inkEl.style.width = inkEl.style.height =
+              currentTarget.offsetWidth + 'px';
+          // If target is div, the offset of div relative to li must be added.
+          inkEl.style.left =
+              (e.offsetX +
+               (e.target.tagName == 'DIV' ? e.target.offsetLeft : 0) -
+               0.5 * inkEl.offsetWidth) +
+              'px';
+          inkEl.style.top =
+              (e.offsetY +
+               (e.target.tagName == 'DIV' ? e.target.offsetTop : 0) -
+               0.5 * inkEl.offsetHeight) +
+              'px';
           inkEl.classList.add('ripple-category-list-item-animation');
         });
-        li.addEventListener('mousedown', e => {
-          e.preventDefault();
+        inkEl.addEventListener('animationend', e => {
+          var inkTarget = e.target;
+          inkTarget.classList.remove('ripple-category-list-item-animation');
         });
         return li;
       };
diff --git a/chrome/browser/resources/device_log_ui/device_log_ui.html b/chrome/browser/resources/device_log_ui/device_log_ui.html
index 4a6af562..7bbd71e5a 100644
--- a/chrome/browser/resources/device_log_ui/device_log_ui.html
+++ b/chrome/browser/resources/device_log_ui/device_log_ui.html
@@ -62,6 +62,10 @@
       <span>$i18n{logTypePrinterText}</span>
     </label>
     <label>
+      <input id="log-type-fido" type="checkbox">
+      <span>$i18n{logTypeFidoText}</span>
+    </label>
+    <label>
       <input id="log-fileinfo" type="checkbox">
       <span>$i18n{logLevelFileinfoText}</span>
     </label>
diff --git a/chrome/browser/resources/ntp4/new_tab_theme.css b/chrome/browser/resources/ntp4/new_tab_theme.css
index 56bb6889..48aea93 100644
--- a/chrome/browser/resources/ntp4/new_tab_theme.css
+++ b/chrome/browser/resources/ntp4/new_tab_theme.css
@@ -10,17 +10,6 @@
   background-repeat: $i18n{backgroundTiling};
 }
 
-#attribution {
-  left: $i18n{leftAlignAttribution};
-  right: $i18n{rightAlignAttribution};
-  text-align: $i18n{textAlignAttribution};
-  display: $i18n{displayAttribution};
-}
-
-#attribution-img {
-  content: url(chrome://theme/IDR_THEME_NTP_ATTRIBUTION?$i18n{themeId});
-}
-
 html[bookmarkbarattached='true'] {
   background-position: $i18n{backgroundBarAttached};
 }
@@ -31,13 +20,21 @@
   overflow: auto;
 }
 
-#attribution,
-[is='action-link'] {
-  color: $i18n{colorTextLight};
+[is='action-link'],
+[is='action-link']:active {
+  color: rgb($i18n{colorLink});
 }
 
-[is='action-link']:active {
-  color: $i18n{colorTextRgba};
+#attribution {
+  color: $i18n{colorTextLight};
+  display: $i18n{displayAttribution};
+  left: $i18n{leftAlignAttribution};
+  right: $i18n{rightAlignAttribution};
+  text-align: $i18n{textAlignAttribution};
+}
+
+#attribution-img {
+  content: url(chrome://theme/IDR_THEME_NTP_ATTRIBUTION?$i18n{themeId});
 }
 
 .page-switcher {
diff --git a/chrome/browser/resources/settings/a11y_page/tts_subpage.html b/chrome/browser/resources/settings/a11y_page/tts_subpage.html
index 8d105fb8..7f0ec20 100644
--- a/chrome/browser/resources/settings/a11y_page/tts_subpage.html
+++ b/chrome/browser/resources/settings/a11y_page/tts_subpage.html
@@ -88,7 +88,8 @@
     </div>
     <div class="settings-box continuation">
       <cr-input id="previewInput" label="$i18n{textToSpeechPreviewInputLabel}"
-          value="{{previewText_}}">
+          value="{{previewText_}}"
+          disabled="[[isPreviewing_]]">
         <paper-button on-click="onPreviewTtsClick_"
             disabled$="[[!enablePreviewButton_(allVoices, isPreviewing_,
                          previewText_)]]"
diff --git a/chrome/browser/ssl/security_state_tab_helper.cc b/chrome/browser/ssl/security_state_tab_helper.cc
index 1ca339c..aef4333 100644
--- a/chrome/browser/ssl/security_state_tab_helper.cc
+++ b/chrome/browser/ssl/security_state_tab_helper.cc
@@ -90,23 +90,11 @@
 
 SecurityStateTabHelper::~SecurityStateTabHelper() {}
 
-void SecurityStateTabHelper::GetSecurityInfo(
-    security_state::SecurityInfo* result) const {
-  security_state::GetSecurityInfo(
-      GetVisibleSecurityState(), UsedPolicyInstalledCertificate(),
-      base::BindRepeating(&IsOriginSecureWithWhitelist,
-                          GetSecureOriginsAndPatterns()),
-      result);
-}
-
 security_state::SecurityLevel SecurityStateTabHelper::GetSecurityLevel() const {
-  security_state::SecurityInfo result;
-  security_state::GetSecurityInfo(
-      GetVisibleSecurityState(), UsedPolicyInstalledCertificate(),
+  return security_state::GetSecurityLevel(
+      *GetVisibleSecurityState(), UsedPolicyInstalledCertificate(),
       base::BindRepeating(&IsOriginSecureWithWhitelist,
-                          GetSecureOriginsAndPatterns()),
-      &result);
-  return result.security_level;
+                          GetSecureOriginsAndPatterns()));
 }
 
 std::unique_ptr<security_state::VisibleSecurityState>
@@ -191,7 +179,7 @@
 }
 
 void SecurityStateTabHelper::DidChangeVisibleSecurityState() {
-  RecordSecurityLevel(*GetVisibleSecurityState().get(), GetSecurityLevel());
+  RecordSecurityLevel(*GetVisibleSecurityState(), GetSecurityLevel());
 }
 
 bool SecurityStateTabHelper::UsedPolicyInstalledCertificate() const {
diff --git a/chrome/browser/ssl/security_state_tab_helper.h b/chrome/browser/ssl/security_state_tab_helper.h
index 4c9c99d..c966ac2 100644
--- a/chrome/browser/ssl/security_state_tab_helper.h
+++ b/chrome/browser/ssl/security_state_tab_helper.h
@@ -25,9 +25,7 @@
  public:
   ~SecurityStateTabHelper() override;
 
-  // See security_state::GetSecurityInfo.
-  void GetSecurityInfo(
-      security_state::SecurityInfo* result) const;
+  // See security_state::GetSecurityLevel.
   security_state::SecurityLevel GetSecurityLevel() const;
   std::unique_ptr<security_state::VisibleSecurityState>
   GetVisibleSecurityState() const;
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
index d19b0b4b..6969f51 100644
--- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
+++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -382,9 +382,8 @@
   std::unique_ptr<security_state::VisibleSecurityState> visible_security_state =
       helper->GetVisibleSecurityState();
   EXPECT_EQ(expect_security_level, helper->GetSecurityLevel());
-  security_state::SecurityInfo security_info;
-  helper->GetSecurityInfo(&security_info);
-  EXPECT_EQ(expect_sha1_in_chain, security_info.sha1_in_chain);
+  EXPECT_EQ(expect_sha1_in_chain,
+            security_state::IsSHA1InChain(*visible_security_state));
   EXPECT_EQ(expect_displayed_mixed_content,
             visible_security_state->displayed_mixed_content);
   EXPECT_EQ(expect_ran_mixed_content,
@@ -408,9 +407,7 @@
   std::unique_ptr<security_state::VisibleSecurityState> visible_security_state =
       helper->GetVisibleSecurityState();
   EXPECT_EQ(security_state::NONE, helper->GetSecurityLevel());
-  security_state::SecurityInfo security_info;
-  helper->GetSecurityInfo(&security_info);
-  EXPECT_FALSE(security_info.sha1_in_chain);
+  EXPECT_FALSE(security_state::IsSHA1InChain(*visible_security_state));
   EXPECT_FALSE(visible_security_state->displayed_mixed_content);
   EXPECT_FALSE(visible_security_state->ran_mixed_content);
   EXPECT_FALSE(
@@ -630,9 +627,7 @@
   std::unique_ptr<security_state::VisibleSecurityState> visible_security_state =
       helper->GetVisibleSecurityState();
   EXPECT_EQ(security_state::NONE, helper->GetSecurityLevel());
-  security_state::SecurityInfo security_info;
-  helper->GetSecurityInfo(&security_info);
-  EXPECT_FALSE(security_info.sha1_in_chain);
+  EXPECT_FALSE(security_state::IsSHA1InChain(*visible_security_state));
   EXPECT_FALSE(visible_security_state->displayed_mixed_content);
   EXPECT_FALSE(visible_security_state->ran_mixed_content);
   EXPECT_FALSE(
diff --git a/chrome/browser/themes/theme_properties.cc b/chrome/browser/themes/theme_properties.cc
index 0257cdf..6a95b23 100644
--- a/chrome/browser/themes/theme_properties.cc
+++ b/chrome/browser/themes/theme_properties.cc
@@ -71,6 +71,8 @@
       return SK_ColorWHITE;
     case ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR:
       return SkColorSetRGB(0x28, 0x28, 0x28);
+    case ThemeProperties::COLOR_NTP_LINK:
+      return gfx::kGoogleBlue300;
     default:
       return base::nullopt;
   }
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc
index a81fa96..49b5c382 100644
--- a/chrome/browser/ui/app_list/search/app_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -77,11 +77,11 @@
 // is somewhat arbitrary, but is roughly equivalent to the 'ter' in 'terminal'.
 constexpr double kCrostiniTerminalRelevanceThreshold = 0.8;
 
-// When ranking with the |AppSearchResultRanker| is enabled, this boost is
+// When ranking with the |QueryBasedAppsRanker| is enabled, this boost is
 // added to all apps that the ranker knows about.
 constexpr float kDefaultRankerScoreBoost = 0.0f;
 
-// When ranking with the |AppSearchResultRanker| is enabled, its scores are
+// When ranking with the |QueryBasedAppsRanker| is enabled, its scores are
 // multiplied by this amount.
 constexpr float kDefaultRankerScoreCoefficient = 0.1f;
 
@@ -784,9 +784,9 @@
   new_results.reserve(apps_size);
 
   const bool should_rerank =
-      app_list_features::IsAppSearchResultRankerEnabled() &&
+      app_list_features::IsQueryBasedAppsRankerEnabled() &&
       base::GetFieldTrialParamByFeatureAsBool(
-          app_list_features::kEnableAppSearchResultRanker,
+          app_list_features::kEnableQueryBasedAppsRanker,
           "rank_app_query_results", false) &&
       ranker_ != nullptr;
   // Maps app IDs to their score according to |ranker_|.
@@ -796,10 +796,10 @@
   if (should_rerank) {
     ranker_scores = ranker_->Rank();
     ranker_score_coefficient = base::GetFieldTrialParamByFeatureAsDouble(
-        app_list_features::kEnableAppSearchResultRanker,
-        "app_query_coefficient", ranker_score_coefficient);
+        app_list_features::kEnableQueryBasedAppsRanker, "app_query_coefficient",
+        ranker_score_coefficient);
     ranker_score_boost = base::GetFieldTrialParamByFeatureAsDouble(
-        app_list_features::kEnableAppSearchResultRanker, "app_query_boost",
+        app_list_features::kEnableQueryBasedAppsRanker, "app_query_boost",
         ranker_score_boost);
   }
 
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc
index 9df6533..0172b408 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc
@@ -22,11 +22,11 @@
 
 namespace {
 
-// When ranking with the |AppSearchResultRanker| is enabled, this boost is
+// When ranking with the |QueryBasedAppsRanker| is enabled, this boost is
 // added to all shortcuts that the ranker knows about.
 constexpr float kDefaultRankerScoreBoost = 0.0f;
 
-// When ranking with the |AppSearchResultRanker| is enabled, its scores are
+// When ranking with the |QueryBasedAppsRanker| is enabled, its scores are
 // multiplied by this amount.
 constexpr float kDefaultRankerScoreCoefficient = 0.1f;
 
@@ -87,9 +87,9 @@
   // implemented, split the |rank_arc_app_shortcuts| flag into two flags to
   // control zero-state and query-based re-ranking individually.
   const bool should_rerank =
-      app_list_features::IsAppSearchResultRankerEnabled() &&
+      app_list_features::IsQueryBasedAppsRankerEnabled() &&
       base::GetFieldTrialParamByFeatureAsBool(
-          app_list_features::kEnableAppSearchResultRanker,
+          app_list_features::kEnableQueryBasedAppsRanker,
           "rank_arc_app_shortcuts", false) &&
       ranker_ != nullptr;
   // Maps app IDs to their score according to |ranker_|.
@@ -99,10 +99,10 @@
   if (should_rerank) {
     ranker_scores = ranker_->Rank();
     ranker_score_coefficient = base::GetFieldTrialParamByFeatureAsDouble(
-        app_list_features::kEnableAppSearchResultRanker,
+        app_list_features::kEnableQueryBasedAppsRanker,
         "arc_app_shortcuts_query_coefficient", ranker_score_coefficient);
     ranker_score_boost = base::GetFieldTrialParamByFeatureAsDouble(
-        app_list_features::kEnableAppSearchResultRanker,
+        app_list_features::kEnableQueryBasedAppsRanker,
         "arc_app_shortcuts_query_boost", ranker_score_boost);
   }
 
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
index a2eed18..8aebef2 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
@@ -55,14 +55,14 @@
   void CreateRanker(const std::map<std::string, std::string>& params = {}) {
     if (!params.empty()) {
       scoped_feature_list_.InitAndEnableFeatureWithParameters(
-          app_list_features::kEnableAppSearchResultRanker, params);
+          app_list_features::kEnableQueryBasedAppsRanker, params);
       ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
       ranker_ =
           std::make_unique<AppSearchResultRanker>(temp_dir_.GetPath(),
                                                   /*is_ephemeral_user=*/false);
     } else {
       scoped_feature_list_.InitWithFeatures(
-          {}, {app_list_features::kEnableAppSearchResultRanker});
+          {}, {app_list_features::kEnableQueryBasedAppsRanker});
     }
   }
 
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc
index c1297c2..521673f 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc
@@ -265,25 +265,25 @@
   // And the sum weights[1] + ..., + weights[4] also needs to be in [0.0, 1.0]
   // so that the weight[0] is set to be 1.0 - (weights[1] + ..., + weights[4]).
   weights[1] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble(
-      app_list_features::kEnableAppSearchResultRanker,
-      "weight_1_hour_later_bin", -1.0));
+      app_list_features::kEnableZeroStateAppsRanker, "weight_1_hour_later_bin",
+      -1.0));
   if (weights[1] < 0.0 || weights[1] > 1.0)
     return default_weights;
 
   weights[2] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble(
-      app_list_features::kEnableAppSearchResultRanker,
-      "weight_2_hour_later_bin", -1.0));
+      app_list_features::kEnableZeroStateAppsRanker, "weight_2_hour_later_bin",
+      -1.0));
   if (weights[2] < 0.0 || weights[2] > 1.0)
     return default_weights;
 
   weights[3] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble(
-      app_list_features::kEnableAppSearchResultRanker,
+      app_list_features::kEnableZeroStateAppsRanker,
       "weight_2_hour_earlier_bin", -1.0));
   if (weights[3] < 0.0 || weights[3] > 1.0)
     return default_weights;
 
   weights[4] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble(
-      app_list_features::kEnableAppSearchResultRanker,
+      app_list_features::kEnableZeroStateAppsRanker,
       "weight_1_hour_earlier_bin", -1.0));
   if (weights[4] < 0.0 || weights[4] > 1.0)
     return default_weights;
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc
index dd16a86..2b1b185 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc
@@ -233,7 +233,7 @@
 TEST_F(HourAppLaunchPredictorTest, CheckDefaultWeights) {
   base::test::ScopedFeatureList scoped_feature_list_;
   scoped_feature_list_.InitAndEnableFeature(
-      app_list_features::kEnableAppSearchResultRanker);
+      app_list_features::kEnableZeroStateAppsRanker);
 
   EXPECT_THAT(HourAppLaunchPredictor::BinWeightsFromFlagOrDefault(),
               ElementsAre(FloatEq(0.6), FloatEq(0.15), FloatEq(0.05),
@@ -244,7 +244,7 @@
 TEST_F(HourAppLaunchPredictorTest, SetWeightsFromFlag) {
   base::test::ScopedFeatureList scoped_feature_list_;
   scoped_feature_list_.InitAndEnableFeatureWithParameters(
-      app_list_features::kEnableAppSearchResultRanker,
+      app_list_features::kEnableZeroStateAppsRanker,
       {{"weight_1_hour_later_bin", "0.1"},
        {"weight_2_hour_later_bin", "0.2"},
        {"weight_2_hour_earlier_bin", "0.22"},
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.cc b/chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.cc
index b3b2519..8e5bda5 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.cc
@@ -94,7 +94,7 @@
     : predictor_filename_(
           profile_path.AppendASCII(kAppLaunchPredictorFilename)),
       weak_factory_(this) {
-  if (!app_list_features::IsAppSearchResultRankerEnabled())
+  if (!app_list_features::IsZeroStateAppsRankerEnabled())
     return;
 
   predictor_ =
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker_unittest.cc
index 9fdc52d..b1ed01e5 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker_unittest.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker_unittest.cc
@@ -48,7 +48,7 @@
 
 TEST_F(AppSearchResultRankerFlagTest, TrainAndInfer) {
   scoped_feature_list_.InitAndEnableFeatureWithParameters(
-      app_list_features::kEnableAppSearchResultRanker,
+      app_list_features::kEnableZeroStateAppsRanker,
       {{"app_search_result_ranker_predictor_name",
         FakeAppLaunchPredictor::kPredictorName}});
 
@@ -65,7 +65,7 @@
 
 TEST_F(AppSearchResultRankerFlagTest, EphemeralUsersAreDisabled) {
   scoped_feature_list_.InitAndEnableFeatureWithParameters(
-      app_list_features::kEnableAppSearchResultRanker,
+      app_list_features::kEnableZeroStateAppsRanker,
       {{"app_search_result_ranker_predictor_name",
         FakeAppLaunchPredictor::kPredictorName}});
 
@@ -80,7 +80,7 @@
 
 TEST_F(AppSearchResultRankerFlagTest, ReturnEmptyIfDisabled) {
   scoped_feature_list_.InitWithFeatures(
-      {}, {app_list_features::kEnableAppSearchResultRanker});
+      {}, {app_list_features::kEnableZeroStateAppsRanker});
 
   AppSearchResultRanker ranker(temp_dir_.GetPath(), kNotAnEphemeralUser);
   Wait();
@@ -107,7 +107,7 @@
           ->mutable_rank_result())[kTarget2] = 2.0f;
 
     scoped_feature_list_.InitAndEnableFeatureWithParameters(
-        app_list_features::kEnableAppSearchResultRanker,
+        app_list_features::kEnableZeroStateAppsRanker,
         {{"app_search_result_ranker_predictor_name",
           FakeAppLaunchPredictor::kPredictorName}});
   }
diff --git a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
index 17fa7b2..9d3da04 100644
--- a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
@@ -634,7 +634,7 @@
 TEST_F(AppSearchProviderTest, FetchRecommendationsFromRanker) {
   base::test::ScopedFeatureList scoped_feature_list_;
   scoped_feature_list_.InitWithFeatures(
-      {app_list_features::kEnableAppSearchResultRanker}, {});
+      {app_list_features::kEnableZeroStateAppsRanker}, {});
   CreateSearch();
 
   extensions::ExtensionPrefs* prefs =
@@ -656,7 +656,7 @@
 TEST_F(AppSearchProviderTest, RankerIsDisabledWithFlag) {
   base::test::ScopedFeatureList scoped_feature_list_;
   scoped_feature_list_.InitWithFeatures(
-      {}, {app_list_features::kEnableAppSearchResultRanker});
+      {}, {app_list_features::kEnableZeroStateAppsRanker});
   CreateSearch();
 
   extensions::ExtensionPrefs* prefs =
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index 0e32a8c..cf3a1ff 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -434,13 +434,6 @@
 void ChromeAutofillClient::HideAutofillPopup() {
   if (popup_controller_.get())
     popup_controller_->Hide();
-
-  // Password generation popups behave in the same fashion and should also
-  // be hidden.
-  ChromePasswordManagerClient* password_client =
-      ChromePasswordManagerClient::FromWebContents(web_contents());
-  if (password_client)
-    password_client->HidePasswordGenerationPopup();
 }
 
 bool ChromeAutofillClient::IsAutocompleteEnabled() {
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index c8e49a1..d7f0056 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1176,9 +1176,8 @@
   SecurityStateTabHelper* helper =
       SecurityStateTabHelper::FromWebContents(web_contents);
   DCHECK(helper);
-  security_state::SecurityInfo security_info;
-  helper->GetSecurityInfo(&security_info);
-  return security_state::GetSecurityStyle(security_info,
+  return security_state::GetSecurityStyle(helper->GetSecurityLevel(),
+                                          *helper->GetVisibleSecurityState(),
                                           security_style_explanations);
 }
 
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
index 16f6f21..7213bc4 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
+++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
@@ -57,7 +57,7 @@
     content::WebContents* web_contents,
     gfx::NativeView container_view) {
   if (previous.get() && previous->element_bounds() == bounds &&
-      previous->web_contents_ == web_contents &&
+      previous->web_contents() == web_contents &&
       previous->container_view() == container_view) {
     return previous;
   }
@@ -81,7 +81,8 @@
     PasswordGenerationPopupObserver* observer,
     content::WebContents* web_contents,
     gfx::NativeView container_view)
-    : view_(nullptr),
+    : content::WebContentsObserver(web_contents),
+      view_(nullptr),
       form_(form),
       driver_(driver),
       observer_(observer),
@@ -94,13 +95,29 @@
       controller_common_(bounds, base::i18n::LEFT_TO_RIGHT, container_view),
       password_selected_(false),
       state_(kOfferGeneration),
-      web_contents_(web_contents),
       weak_ptr_factory_(this) {
+#if !defined(OS_ANDROID)
+  zoom::ZoomController* zoom_controller =
+      zoom::ZoomController::FromWebContents(web_contents);
+  // There may not always be a ZoomController, e.g. in tests.
+  if (zoom_controller) {
+    zoom_controller->AddObserver(this);
+  }
+#endif  // !defined(OS_ANDROID)
+
   help_text_ = l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_PROMPT);
 }
 
 PasswordGenerationPopupControllerImpl::
-    ~PasswordGenerationPopupControllerImpl() {}
+    ~PasswordGenerationPopupControllerImpl() {
+#if !defined(OS_ANDROID)
+  zoom::ZoomController* zoom_controller =
+      zoom::ZoomController::FromWebContents(web_contents());
+  if (zoom_controller) {
+    zoom_controller->RemoveObserver(this);
+  }
+#endif  // !defined(OS_ANDROID)
+}
 
 base::WeakPtr<PasswordGenerationPopupControllerImpl>
 PasswordGenerationPopupControllerImpl::GetWeakPtr() {
@@ -159,7 +176,7 @@
     uint32_t spec_priority = 0;
     current_password_ =
         driver_->GetPasswordGenerationHelper()->GeneratePassword(
-            web_contents_->GetLastCommittedURL().GetOrigin(), form_signature_,
+            web_contents()->GetLastCommittedURL().GetOrigin(), form_signature_,
             field_signature_, max_length_, &spec_priority);
     if (driver_ && driver_->GetPasswordManager()) {
       driver_->GetPasswordManager()->ReportSpecPriorityForGeneratedPassword(
@@ -199,10 +216,29 @@
     view_->UpdatePasswordValue();
 }
 
-void PasswordGenerationPopupControllerImpl::HideAndDestroy() {
+void PasswordGenerationPopupControllerImpl::FrameWasScrolled() {
   Hide();
 }
 
+void PasswordGenerationPopupControllerImpl::GeneratedPasswordRejected() {
+  Hide();
+}
+
+void PasswordGenerationPopupControllerImpl::DidAttachInterstitialPage() {
+  Hide();
+}
+
+void PasswordGenerationPopupControllerImpl::WebContentsDestroyed() {
+  Hide();
+}
+
+#if !defined(OS_ANDROID)
+void PasswordGenerationPopupControllerImpl::OnZoomChanged(
+    const zoom::ZoomController::ZoomChangedEventData& data) {
+  Hide();
+}
+#endif  // !defined(OS_ANDROID)
+
 void PasswordGenerationPopupControllerImpl::Hide() {
   if (driver_) {
     static_cast<autofill::ContentAutofillDriver*>(driver_->GetAutofillDriver())
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h
index c7c6c3e..711a6e2b 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h
+++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h
@@ -17,10 +17,15 @@
 #include "chrome/browser/ui/passwords/password_generation_popup_controller.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/autofill/core/common/signatures_util.h"
+#include "content/public/browser/web_contents_observer.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/native_widget_types.h"
 
+#if !defined(OS_ANDROID)
+#include "components/zoom/zoom_observer.h"
+#endif  // !defined(OS_ANDROID)
+
 namespace content {
 struct NativeWebKeyboardEvent;
 class WebContents;
@@ -43,8 +48,19 @@
 // determining the location of the popup, handling keypress events while the
 // popup is active, and notifying both the renderer and the password manager
 // if the password is accepted.
+//
+// NOTE: This is used on Android only to display the editing popup.
+//
+// TODO(crbug.com/944502): Clean up the popup code on Android to make its use
+// clear and remove unused code.
 class PasswordGenerationPopupControllerImpl
-    : public PasswordGenerationPopupController {
+    : public PasswordGenerationPopupController,
+      public content::WebContentsObserver
+#if !defined(OS_ANDROID)
+    ,
+      public zoom::ZoomObserver
+#endif  // !defined(OS_ANDROID)
+{
  public:
   // Create a controller or return |previous| if it is suitable. Will hide
   // |previous| if it is not returned. |bounds| is the bounds of the element
@@ -74,8 +90,25 @@
   // Update the password to be displayed in the UI.
   void UpdatePassword(base::string16 new_password);
 
-  // Hides the popup and destroys |this|.
-  void HideAndDestroy();
+  // Hides the popup, since its position is no longer valid.
+  void FrameWasScrolled();
+
+  // The generated password counts as rejected either if the user ignores the
+  // popup and types a password, or if the generated password is deleted.
+  // In both cases the popups should be hidden. In the latter case, a new popup
+  // might be shown offering another password if generation is offered
+  // automatically on that field.
+  void GeneratedPasswordRejected();
+
+  // content::WebContentsObserver overrides
+  void DidAttachInterstitialPage() override;
+  void WebContentsDestroyed() override;
+
+#if !defined(OS_ANDROID)
+  // ZoomObserver implementation.
+  void OnZoomChanged(
+      const zoom::ZoomController::ZoomChangedEventData& data) override;
+#endif  // !defined(OS_ANDROID)
 
  protected:
   PasswordGenerationPopupControllerImpl(
@@ -160,8 +193,6 @@
 
   autofill::PopupViewCommon view_common_;
 
-  content::WebContents* const web_contents_;
-
   base::WeakPtrFactory<PasswordGenerationPopupControllerImpl> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(PasswordGenerationPopupControllerImpl);
diff --git a/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc b/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc
index e9de3b2..7182b45 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc
+++ b/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc
@@ -67,8 +67,8 @@
 
   GetViewTester()->SimulateMouseMovementAt(gfx::Point(1, 1));
 
-  // Deletes |controller_|.
-  controller_->HideAndDestroy();
+  // This hides the popup and destroys the controller.
+  GetWebContents()->Close();
 }
 
 // Verify that we calling Show() with an invalid container does not crash.
@@ -76,6 +76,9 @@
 IN_PROC_BROWSER_TEST_F(PasswordGenerationPopupViewTest, InvalidContainerView) {
   controller_ = new autofill::TestPasswordGenerationPopupController(
       GetWebContents(), NULL);
+
+  // Creation of the popup view should fail, in which case the controller
+  // is destroyed.
   controller_->Show(PasswordGenerationPopupController::kOfferGeneration);
 }
 
@@ -85,6 +88,7 @@
   controller_ = new autofill::TestPasswordGenerationPopupController(
       GetWebContents(), GetNativeView());
   controller_->Show(PasswordGenerationPopupController::kEditGeneratedPassword);
+
   GetWebContents()->Close();
 }
 
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc b/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
index 56365dd..972101e 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
@@ -300,7 +300,6 @@
             {kBothToLockVariation, kMockNonsecureURL, 0, security_state::NONE,
              false, kEmptyString}};
 
-  security_state::SecurityInfo security_info;
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(tab);
@@ -321,8 +320,7 @@
     }
     SetUpInterceptor(c.cert_status);
     ui_test_utils::NavigateToURL(browser(), c.url);
-    helper->GetSecurityInfo(&security_info);
-    EXPECT_EQ(c.security_level, security_info.security_level);
+    EXPECT_EQ(c.security_level, helper->GetSecurityLevel());
     EXPECT_EQ(c.should_show_text,
               location_bar_view->location_icon_view()->ShouldShowLabel());
     EXPECT_EQ(c.indicator_text,
diff --git a/chrome/browser/ui/webui/device_log_ui.cc b/chrome/browser/ui/webui/device_log_ui.cc
index 5cec52a..fcf7025 100644
--- a/chrome/browser/ui/webui/device_log_ui.cc
+++ b/chrome/browser/ui/webui/device_log_ui.cc
@@ -78,6 +78,7 @@
   html->AddLocalizedString("logTypeUsbText", IDS_DEVICE_LOG_TYPE_USB);
   html->AddLocalizedString("logTypeHidText", IDS_DEVICE_LOG_TYPE_HID);
   html->AddLocalizedString("logTypePrinterText", IDS_DEVICE_LOG_TYPE_PRINTER);
+  html->AddLocalizedString("logTypeFidoText", IDS_DEVICE_LOG_TYPE_FIDO);
 
   html->AddLocalizedString("logEntryFormat", IDS_DEVICE_LOG_ENTRY);
   html->SetJsonPath("strings.js");
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
index 46fe18f..090be9f 100644
--- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
+++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -255,6 +255,7 @@
   new_tab_html_ = nullptr;
   new_tab_incognito_css_ = nullptr;
   new_tab_css_ = nullptr;
+  new_tab_guest_html_ = nullptr;
 }
 
 void NTPResourceCache::CreateNewTabIncognitoHTML() {
@@ -552,6 +553,8 @@
   // Colors.
   substitutions["colorBackground"] =
       color_utils::SkColorToRgbaString(color_background);
+  substitutions["colorLink"] = color_utils::SkColorToRgbString(
+      GetThemeColor(tp, ThemeProperties::COLOR_NTP_LINK));
   substitutions["backgroundBarDetached"] = GetNewTabBackgroundCSS(tp, false);
   substitutions["backgroundBarAttached"] = GetNewTabBackgroundCSS(tp, true);
   substitutions["backgroundTiling"] = GetNewTabBackgroundTilingCSS(tp);
diff --git a/chrome/renderer/autofill/fake_password_generation_driver.h b/chrome/renderer/autofill/fake_password_generation_driver.h
index 3875324d..75ac3ff6 100644
--- a/chrome/renderer/autofill/fake_password_generation_driver.h
+++ b/chrome/renderer/autofill/fake_password_generation_driver.h
@@ -58,6 +58,7 @@
   MOCK_METHOD2(ShowPasswordEditingPopup,
                void(const gfx::RectF& bounds,
                     const autofill::PasswordForm& form));
+  MOCK_METHOD0(FrameWasScrolled, void());
 
  private:
   // autofill::mojom::PasswordManagerClient:
diff --git a/chrome/renderer/autofill/password_generation_agent_browsertest.cc b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
index 6c038f1..64691d5 100644
--- a/chrome/renderer/autofill/password_generation_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
@@ -1190,7 +1190,9 @@
               PresaveGeneratedPassword(testing::Field(
                   &autofill::PasswordForm::password_value, password)));
   password_generation_->GeneratedPasswordAccepted(password);
+
   EXPECT_CALL(fake_pw_client_, PasswordNoLongerGenerated(testing::_));
+  EXPECT_CALL(fake_pw_client_, AutomaticGenerationStatusChanged(true, _));
   ExecuteJavaScriptForTests(
       "document.getElementById('first_password').value = '';");
   FocusField(kGenerationElementId);
diff --git a/chrome/services/app_service/public/cpp/icon_cache.cc b/chrome/services/app_service/public/cpp/icon_cache.cc
index ac86fe99..cef8db4 100644
--- a/chrome/services/app_service/public/cpp/icon_cache.cc
+++ b/chrome/services/app_service/public/cpp/icon_cache.cc
@@ -42,10 +42,8 @@
     bool allow_placeholder_icon,
     apps::mojom::Publisher::LoadIconCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  apps::mojom::IconKey null_icon_key;
   IconLoader::Key key(
-      app_type, app_id, icon_key ? *icon_key : null_icon_key, icon_compression,
-      size_hint_in_dip,
+      app_type, app_id, icon_key, icon_compression, size_hint_in_dip,
       // We pass false instead of allow_placeholder_icon, as the Value
       // already records placeholder-ness. If the allow_placeholder_icon
       // arg to this function is true, we can re-use a cache hit regardless
diff --git a/chrome/services/app_service/public/cpp/icon_loader.cc b/chrome/services/app_service/public/cpp/icon_loader.cc
index 3f405dd..8ffef2b 100644
--- a/chrome/services/app_service/public/cpp/icon_loader.cc
+++ b/chrome/services/app_service/public/cpp/icon_loader.cc
@@ -20,15 +20,15 @@
 
 IconLoader::Key::Key(apps::mojom::AppType app_type,
                      const std::string& app_id,
-                     const apps::mojom::IconKey& icon_key,
+                     const apps::mojom::IconKeyPtr& icon_key,
                      apps::mojom::IconCompression icon_compression,
                      int32_t size_hint_in_dip,
                      bool allow_placeholder_icon)
     : app_type_(app_type),
       app_id_(app_id),
-      timeline_(icon_key.timeline),
-      resource_id_(icon_key.resource_id),
-      icon_effects_(icon_key.icon_effects),
+      timeline_(icon_key ? icon_key->timeline : 0),
+      resource_id_(icon_key ? icon_key->resource_id : 0),
+      icon_effects_(icon_key ? icon_key->icon_effects : 0),
       icon_compression_(icon_compression),
       size_hint_in_dip_(size_hint_in_dip),
       allow_placeholder_icon_(allow_placeholder_icon) {}
diff --git a/chrome/services/app_service/public/cpp/icon_loader.h b/chrome/services/app_service/public/cpp/icon_loader.h
index 4a1eb6f..ca18e90 100644
--- a/chrome/services/app_service/public/cpp/icon_loader.h
+++ b/chrome/services/app_service/public/cpp/icon_loader.h
@@ -91,7 +91,7 @@
 
     Key(apps::mojom::AppType app_type,
         const std::string& app_id,
-        const apps::mojom::IconKey& icon_key,
+        const apps::mojom::IconKeyPtr& icon_key,
         apps::mojom::IconCompression icon_compression,
         int32_t size_hint_in_dip,
         bool allow_placeholder_icon);
diff --git a/chrome/test/data/chromeos/file_manager/plaintext b/chrome/test/data/chromeos/file_manager/plaintext
new file mode 100644
index 0000000..5368ac1d
--- /dev/null
+++ b/chrome/test/data/chromeos/file_manager/plaintext
@@ -0,0 +1 @@
+From somewhere a long time ago.
diff --git a/chrome/test/data/chromeos/file_manager/world.webm b/chrome/test/data/chromeos/file_manager/world.webm
new file mode 100644
index 0000000..20dd6fe
--- /dev/null
+++ b/chrome/test/data/chromeos/file_manager/world.webm
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/automation/tests/tabs/tab_id.js b/chrome/test/data/extensions/api_test/automation/tests/tabs/tab_id.js
index 49b9f922..d416e39 100644
--- a/chrome/test/data/extensions/api_test/automation/tests/tabs/tab_id.js
+++ b/chrome/test/data/extensions/api_test/automation/tests/tabs/tab_id.js
@@ -3,10 +3,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+var originalActiveTab;
+
 function createBackgroundTab(url, callback) {
   chrome.tabs.query({ active: true }, function(tabs) {
     chrome.test.assertEq(1, tabs.length);
-    var originalActiveTab = tabs[0];
+    originalActiveTab = tabs[0];
     createTab(url, function(tab) {
       chrome.tabs.update(originalActiveTab.id, { active: true }, function() {
         callback(tab);
@@ -21,22 +23,45 @@
   chrome.test.succeed();
 }
 
+function getTreeForBackgroundTab(foregroundTabRootNode, backgroundTab) {
+  // We haven't cheated and loaded the test in the foreground tab.
+  chrome.test.assertTrue(foregroundTabRootNode.docLoaded);
+  var foregroundTabTitle = foregroundTabRootNode.docTitle;
+  chrome.test.assertFalse(foregroundTabTitle == 'Automation Tests');
+
+}
+
 var allTests = [
   function testGetTabById() {
     getUrlFromConfig('index.html', function(url) {
       // Keep the NTP as the active tab so that we know we're requesting the
       // tab by ID rather than just getting the active tab still.
-      createBackgroundTab(url, function(tab) {
-        chrome.automation.getTree(tab.id, function(rootNode) {
-          if (rootNode.docLoaded) {
-            assertCorrectTab(rootNode);
-            return;
-          }
+      createBackgroundTab(url, function(backgroundTab) {
+        // Fetch the current foreground tab to compare with the background tab.
+        chrome.automation.getTree(originalActiveTab.id,
+                                  function(ntpRootNode) {
+          chrome.test.assertEq(ntpRootNode, undefined,
+                               "Can't get automation tree for NTP");
 
-          rootNode.addEventListener('loadComplete', function() {
-            assertCorrectTab(rootNode);
+          chrome.automation.getTree(backgroundTab.id, function(rootNode) {
+            chrome.test.assertFalse(rootNode === undefined,
+                                    "Got automation tree for background tab");
+            chrome.test.assertFalse(
+                rootNode.docLoaded,
+                "Load complete never fires unless tab is foregrounded");
+
+            chrome.tabs.update(backgroundTab.id, { active: true }, function() {
+              if (rootNode.docLoaded) {
+                assertCorrectTab(rootNode);
+                return;
+              }
+
+              rootNode.addEventListener('loadComplete', function() {
+                assertCorrectTab(rootNode);
+              });
+            });
           });
-        })
+        });
       });
     });
   }
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_auth_required.js b/chrome/test/data/extensions/api_test/webrequest/test_auth_required.js
index c042883..6f4ee36 100644
--- a/chrome/test/data/extensions/api_test/webrequest/test_auth_required.js
+++ b/chrome/test/data/extensions/api_test/webrequest/test_auth_required.js
@@ -338,500 +338,4 @@
       ["responseHeaders", "blocking"]);
     navigateAndWait(url);
   },
-
-  // onAuthRequired is an async function but takes no action in this variant.
-  function authRequiredAsyncNoAction() {
-    var realm = 'asyncnoaction';
-    var url = getURLAuthRequired(realm);
-    expect(
-      [  // events
-        { label: "onBeforeRequest",
-          event: "onBeforeRequest",
-          details: {
-            url: url,
-            frameUrl: url
-          }
-        },
-        { label: "onBeforeSendHeaders",
-          event: "onBeforeSendHeaders",
-          details: {
-            url: url,
-            // Note: no requestHeaders because we don't ask for them.
-          },
-        },
-        { label: "onSendHeaders",
-          event: "onSendHeaders",
-          details: {
-            url: url,
-          }
-        },
-        { label: "onHeadersReceived",
-          event: "onHeadersReceived",
-          details: {
-            url: url,
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-            statusCode: 401,
-          }
-        },
-        { label: "onAuthRequired",
-          event: "onAuthRequired",
-          details: {
-            url: url,
-            isProxy: false,
-            scheme: "basic",
-            realm: realm,
-            challenger: {host: testServer, port: testServerPort},
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-            statusCode: 401,
-          }
-        },
-        { label: "onResponseStarted",
-          event: "onResponseStarted",
-          details: {
-            url: url,
-            fromCache: false,
-            statusCode: 401,
-            ip: "127.0.0.1",
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-          }
-        },
-        { label: "onCompleted",
-          event: "onCompleted",
-          details: {
-            url: url,
-            fromCache: false,
-            statusCode: 401,
-            ip: "127.0.0.1",
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-          }
-        },
-      ],
-      [  // event order
-        ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
-         "onHeadersReceived", "onAuthRequired", "onResponseStarted",
-         "onCompleted"]
-      ],
-      {urls: ["<all_urls>"]}, ["asyncBlocking", "responseHeaders"]);
-    navigateAndWait(url);
-  },
-
-  // onAuthRequired is an async function that cancels the auth attempt.
-  function authRequiredAsyncCancelAuth() {
-    var realm = 'asynccancel';
-    var url = getURLAuthRequired(realm);
-    expect(
-      [  // events
-        { label: "onBeforeRequest",
-          event: "onBeforeRequest",
-          details: {
-            url: url,
-            frameUrl: url
-          },
-          retval: {}
-        },
-        { label: "onBeforeSendHeaders",
-          event: "onBeforeSendHeaders",
-          details: {
-            url: url,
-            // Note: no requestHeaders because we don't ask for them.
-          },
-          retval: {}
-        },
-        { label: "onSendHeaders",
-          event: "onSendHeaders",
-          details: {
-            url: url,
-          }
-        },
-        { label: "onHeadersReceived",
-          event: "onHeadersReceived",
-          details: {
-            url: url,
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-            statusCode: 401,
-          }
-        },
-        { label: "onAuthRequired",
-          event: "onAuthRequired",
-          details: {
-            url: url,
-            isProxy: false,
-            scheme: "basic",
-            realm: realm,
-            challenger: {host: testServer, port: testServerPort},
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-            statusCode: 401,
-          },
-          retval: {cancel: true}
-        },
-        { label: "onResponseStarted",
-          event: "onResponseStarted",
-          details: {
-            url: url,
-            fromCache: false,
-            statusCode: 401,
-            ip: "127.0.0.1",
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-          }
-        },
-        { label: "onCompleted",
-          event: "onCompleted",
-          details: {
-            url: url,
-            fromCache: false,
-            statusCode: 401,
-            ip: "127.0.0.1",
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-          }
-        },
-      ],
-      [  // event order
-        ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
-         "onHeadersReceived", "onAuthRequired", "onResponseStarted",
-         "onCompleted"]
-      ],
-      {urls: ["<all_urls>"]},
-      ["responseHeaders", "asyncBlocking"]);
-    navigateAndWait(url);
-  },
-
-  // onAuthRequired is an async function that sets authentication credentials.
-  function authRequiredAsyncSetAuth() {
-    var realm = 'asyncsetauth';
-    var url = getURLAuthRequired(realm);
-    expect(
-      [  // events
-        { label: "onBeforeRequest",
-          event: "onBeforeRequest",
-          details: {
-            url: url,
-            frameUrl: url
-          },
-          retval: {}
-        },
-        { label: "onBeforeSendHeaders",
-          event: "onBeforeSendHeaders",
-          details: {
-            url: url,
-            // Note: no requestHeaders because we don't ask for them.
-          },
-          retval: {}
-        },
-        { label: "onSendHeaders",
-          event: "onSendHeaders",
-          details: {
-            url: url,
-          }
-        },
-        { label: "onHeadersReceived",
-          event: "onHeadersReceived",
-          details: {
-            url: url,
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-            statusCode: 401,
-          }
-        },
-        { label: "onAuthRequired",
-          event: "onAuthRequired",
-          details: {
-            url: url,
-            isProxy: false,
-            scheme: "basic",
-            realm: realm,
-            challenger: {host: testServer, port: testServerPort},
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 401 Unauthorized",
-            statusCode: 401,
-          },
-          retval: {authCredentials: {username: "foo", password: "secret"}}
-        },
-        { label: "onResponseStarted",
-          event: "onResponseStarted",
-          details: {
-            url: url,
-            fromCache: false,
-            statusCode: 200,
-            ip: "127.0.0.1",
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 200 OK",
-          }
-        },
-        { label: "onCompleted",
-          event: "onCompleted",
-          details: {
-            url: url,
-            fromCache: false,
-            statusCode: 200,
-            ip: "127.0.0.1",
-            responseHeadersExist: true,
-            statusLine: "HTTP/1.1 200 OK",
-          }
-        },
-      ],
-      [  // event order
-        ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
-         "onHeadersReceived", "onAuthRequired", "onResponseStarted",
-         "onCompleted"]
-      ],
-      {urls: ["<all_urls>"]},
-      ["responseHeaders", "asyncBlocking"]);
-    navigateAndWait(url);
-  },
-
-  // Test that two parallel onAuthRequired signals do not interfere with each
-  // other. This is a regression test for https://crbug.com/931479.
-  function authRequiredParallel() {
-    const realm = 'parallelasync';
-
-    const imgUrl1 = getURLAuthRequired(realm, '1');
-    const imgUrl2 = getURLAuthRequired(realm, '2');
-    const initiator = getServerDomain(initiators.WEB_INITIATED);
-    const parallelAuthRequestsUrl = getServerURL(
-        'extensions/api_test/webrequest/auth_parallel?img1=' +
-        encodeURIComponent(imgUrl1) + '&img2=' + encodeURIComponent(imgUrl2));
-
-    function createExternallyResolvablePromise() {
-      let _resolve;
-      const promise = new Promise((resolve, reject) => _resolve = resolve);
-      promise.resolve = _resolve;
-      return promise;
-    }
-
-    // Create some promises that will resolved to callbacks when onAuthRequired
-    // and onComplete fire.
-    const authRequired1 = createExternallyResolvablePromise();
-    const completed1 = createExternallyResolvablePromise();
-    const authRequired2 = createExternallyResolvablePromise();
-
-    // responseStarted2 is whether the request for |imgUrl2| has signalled
-    // |onResponseStarted| yet.
-    let responseStarted2 = false;
-
-    expect(
-      [  // events
-        { label: 'onBeforeRequest-1',
-          event: 'onBeforeRequest',
-          details: {
-            url: imgUrl1,
-            type: 'image',
-            initiator: initiator,
-            // The testing framework cannot recover the frame URL because the
-            // URL filter below does not capture the top-level request.
-            frameUrl: 'unknown frame URL',
-          },
-        },
-        { label: 'onBeforeSendHeaders-1',
-          event: 'onBeforeSendHeaders',
-          details: {
-            url: imgUrl1,
-            type: 'image',
-            initiator: initiator,
-            // Note: no requestHeaders because we don't ask for them.
-          },
-          retval: {}
-        },
-        { label: 'onSendHeaders-1',
-          event: 'onSendHeaders',
-          details: {
-            url: imgUrl1,
-            type: 'image',
-            initiator: initiator,
-          }
-        },
-        { label: 'onHeadersReceived-1',
-          event: 'onHeadersReceived',
-          details: {
-            url: imgUrl1,
-            type: 'image',
-            initiator: initiator,
-            responseHeadersExist: true,
-            statusLine: 'HTTP/1.1 401 Unauthorized',
-            statusCode: 401,
-          }
-        },
-        { label: 'onAuthRequired-1',
-          event: 'onAuthRequired',
-          details: {
-            url: imgUrl1,
-            type: 'image',
-            initiator: initiator,
-            isProxy: false,
-            scheme: 'basic',
-            realm: realm,
-            challenger: {host: testServer, port: testServerPort},
-            responseHeadersExist: true,
-            statusLine: 'HTTP/1.1 401 Unauthorized',
-            statusCode: 401,
-          },
-          retval_function:
-              (name, details, callback) => authRequired1.resolve(callback),
-        },
-        { label: 'onResponseStarted-1',
-          event: 'onResponseStarted',
-          details: {
-            url: imgUrl1,
-            type: 'image',
-            initiator: initiator,
-            fromCache: false,
-            statusCode: 200,
-            ip: '127.0.0.1',
-            responseHeadersExist: true,
-            statusLine: 'HTTP/1.1 200 OK',
-          }
-        },
-        { label: 'onCompleted-1',
-          event: 'onCompleted',
-          details: {
-            url: imgUrl1,
-            type: 'image',
-            initiator: initiator,
-            fromCache: false,
-            statusCode: 200,
-            ip: '127.0.0.1',
-            responseHeadersExist: true,
-            statusLine: 'HTTP/1.1 200 OK',
-          },
-          retval_function: (name, details) => completed1.resolve(),
-        },
-        { label: 'onBeforeRequest-2',
-          event: 'onBeforeRequest',
-          details: {
-            url: imgUrl2,
-            type: 'image',
-            initiator: initiator,
-            // The testing framework cannot recover the frame URL because the
-            // URL filter below does not capture the top-level request.
-            frameUrl: 'unknown frame URL',
-          },
-        },
-        { label: 'onBeforeSendHeaders-2',
-          event: 'onBeforeSendHeaders',
-          details: {
-            url: imgUrl2,
-            type: 'image',
-            initiator: initiator,
-            // Note: no requestHeaders because we don't ask for them.
-          },
-          retval: {}
-        },
-        { label: 'onSendHeaders-2',
-          event: 'onSendHeaders',
-          details: {
-            url: imgUrl2,
-            type: 'image',
-            initiator: initiator,
-          }
-        },
-        { label: 'onHeadersReceived-2',
-          event: 'onHeadersReceived',
-          details: {
-            url: imgUrl2,
-            type: 'image',
-            initiator: initiator,
-            responseHeadersExist: true,
-            statusLine: 'HTTP/1.1 401 Unauthorized',
-            statusCode: 401,
-          }
-        },
-        { label: 'onAuthRequired-2',
-          event: 'onAuthRequired',
-          details: {
-            url: imgUrl2,
-            type: 'image',
-            initiator: initiator,
-            isProxy: false,
-            scheme: 'basic',
-            realm: realm,
-            challenger: {host: testServer, port: testServerPort},
-            responseHeadersExist: true,
-            statusLine: 'HTTP/1.1 401 Unauthorized',
-            statusCode: 401,
-          },
-          retval_function:
-              (name, details, callback) => authRequired2.resolve(callback),
-        },
-        { label: 'onResponseStarted-2',
-          event: 'onResponseStarted',
-          details: {
-            url: imgUrl2,
-            type: 'image',
-            initiator: initiator,
-            fromCache: false,
-            statusCode: 401,
-            ip: '127.0.0.1',
-            responseHeadersExist: true,
-            statusLine: 'HTTP/1.1 401 Unauthorized',
-          },
-          retval_function: (name, details) => responseStarted2 = true,
-        },
-        { label: 'onCompleted-2',
-          event: 'onCompleted',
-          details: {
-            url: imgUrl2,
-            type: 'image',
-            initiator: initiator,
-            fromCache: false,
-            statusCode: 401,
-            ip: '127.0.0.1',
-            responseHeadersExist: true,
-            statusLine: 'HTTP/1.1 401 Unauthorized',
-          }
-        },
-      ],
-      [  // event order
-        ['onBeforeRequest-1', 'onBeforeSendHeaders-1', 'onSendHeaders-1',
-         'onHeadersReceived-1', 'onAuthRequired-1', 'onResponseStarted-1',
-         'onCompleted-1'],
-        ['onBeforeRequest-2', 'onBeforeSendHeaders-2', 'onSendHeaders-2',
-         'onHeadersReceived-2', 'onAuthRequired-2', 'onResponseStarted-2',
-         'onCompleted-2']
-      ],
-      // Only pay attention to |imgUrl1| and |imgUrl2|, not
-      // |parallelAuthRequestsUrl|.
-      {urls: ['<all_urls>'], types: ['image']},
-      ['responseHeaders', 'asyncBlocking']);
-
-    navigateAndWait(parallelAuthRequestsUrl);
-    (async function() {
-      // Wait for onAuthRequired to be signaled for both requests before doing
-      // anything.
-      const callback1 = await authRequired1;
-      const callback2 = await authRequired2;
-
-      // Resolve the first request and let it complete.
-      callback1({authCredentials: {username: 'foo', password: 'secret'}});
-      await completed1;
-
-      // We wish to test that this did not resolve |callback2| with the same
-      // credentials internally. This would cause |imgUrl2| to signal
-      // |onResponseStarted| and |onCompleted| though it should be blocked.
-      chrome.test.assertFalse(responseStarted2);
-
-      // However it's possible that the second request may be much slower than
-      // the first, causing the above check to pass even if we don't correctly
-      // isolate the two authentication requests.
-      //
-      // Per the webRequest documentation, |onBeforeSendHeaders| should be
-      // signaled after a resolved |onAuthRequired|. This happens without a
-      // network delay, so it would make a fairly reliable test. However,
-      // webRequest does not match the documentation and does not signal it. See
-      // https://crbug.com/809761.
-      //
-      // Instead, resolve the second request, this time canceling the
-      // authentication request. This should result in |imgUrl2| completing with
-      // a 401 response. If the credentials were incorrectly propagated from
-      // |imgUrl1|, this will be ignored and |imgUrl2| will complete with a 200
-      // response.
-      callback2({cancel: true});
-    })();
-  },
 ]);
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_auth_required_async.html b/chrome/test/data/extensions/api_test/webrequest/test_auth_required_async.html
new file mode 100644
index 0000000..ff46cf5
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webrequest/test_auth_required_async.html
@@ -0,0 +1,7 @@
+<!--
+ * 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.
+-->
+<script src="framework.js"></script>
+<script src="test_auth_required_async.js"></script>
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_auth_required_async.js b/chrome/test/data/extensions/api_test/webrequest/test_auth_required_async.js
new file mode 100644
index 0000000..aaec99c
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webrequest/test_auth_required_async.js
@@ -0,0 +1,261 @@
+// 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.
+
+// Generates a unique authentication URL so each test can run
+// without hitting the HTTP authentication cache. Each test
+// must use a unique realm, however.
+function getURLAuthRequired(realm, subpath = 'subpath') {
+  return getServerURL(
+      'auth-basic/' + realm + '/' + subpath + '?realm=' + realm);
+}
+
+runTests([
+  // onAuthRequired is an async function but takes no action in this variant.
+  function authRequiredAsyncNoAction() {
+    var realm = 'asyncnoaction';
+    var url = getURLAuthRequired(realm);
+    expect(
+      [  // events
+        { label: "onBeforeRequest",
+          event: "onBeforeRequest",
+          details: {
+            url: url,
+            frameUrl: url
+          }
+        },
+        { label: "onBeforeSendHeaders",
+          event: "onBeforeSendHeaders",
+          details: {
+            url: url,
+            // Note: no requestHeaders because we don't ask for them.
+          },
+        },
+        { label: "onSendHeaders",
+          event: "onSendHeaders",
+          details: {
+            url: url,
+          }
+        },
+        { label: "onHeadersReceived",
+          event: "onHeadersReceived",
+          details: {
+            url: url,
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+            statusCode: 401,
+          }
+        },
+        { label: "onAuthRequired",
+          event: "onAuthRequired",
+          details: {
+            url: url,
+            isProxy: false,
+            scheme: "basic",
+            realm: realm,
+            challenger: {host: testServer, port: testServerPort},
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+            statusCode: 401,
+          }
+        },
+        { label: "onResponseStarted",
+          event: "onResponseStarted",
+          details: {
+            url: url,
+            fromCache: false,
+            statusCode: 401,
+            ip: "127.0.0.1",
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+          }
+        },
+        { label: "onCompleted",
+          event: "onCompleted",
+          details: {
+            url: url,
+            fromCache: false,
+            statusCode: 401,
+            ip: "127.0.0.1",
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+          }
+        },
+      ],
+      [  // event order
+        ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
+         "onHeadersReceived", "onAuthRequired", "onResponseStarted",
+         "onCompleted"]
+      ],
+      {urls: ["<all_urls>"]}, ["asyncBlocking", "responseHeaders"]);
+    navigateAndWait(url);
+  },
+
+  // onAuthRequired is an async function that cancels the auth attempt.
+  function authRequiredAsyncCancelAuth() {
+    var realm = 'asynccancel';
+    var url = getURLAuthRequired(realm);
+    expect(
+      [  // events
+        { label: "onBeforeRequest",
+          event: "onBeforeRequest",
+          details: {
+            url: url,
+            frameUrl: url
+          },
+          retval: {}
+        },
+        { label: "onBeforeSendHeaders",
+          event: "onBeforeSendHeaders",
+          details: {
+            url: url,
+            // Note: no requestHeaders because we don't ask for them.
+          },
+          retval: {}
+        },
+        { label: "onSendHeaders",
+          event: "onSendHeaders",
+          details: {
+            url: url,
+          }
+        },
+        { label: "onHeadersReceived",
+          event: "onHeadersReceived",
+          details: {
+            url: url,
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+            statusCode: 401,
+          }
+        },
+        { label: "onAuthRequired",
+          event: "onAuthRequired",
+          details: {
+            url: url,
+            isProxy: false,
+            scheme: "basic",
+            realm: realm,
+            challenger: {host: testServer, port: testServerPort},
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+            statusCode: 401,
+          },
+          retval: {cancel: true}
+        },
+        { label: "onResponseStarted",
+          event: "onResponseStarted",
+          details: {
+            url: url,
+            fromCache: false,
+            statusCode: 401,
+            ip: "127.0.0.1",
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+          }
+        },
+        { label: "onCompleted",
+          event: "onCompleted",
+          details: {
+            url: url,
+            fromCache: false,
+            statusCode: 401,
+            ip: "127.0.0.1",
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+          }
+        },
+      ],
+      [  // event order
+        ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
+         "onHeadersReceived", "onAuthRequired", "onResponseStarted",
+         "onCompleted"]
+      ],
+      {urls: ["<all_urls>"]},
+      ["responseHeaders", "asyncBlocking"]);
+    navigateAndWait(url);
+  },
+
+  // onAuthRequired is an async function that sets authentication credentials.
+  function authRequiredAsyncSetAuth() {
+    var realm = 'asyncsetauth';
+    var url = getURLAuthRequired(realm);
+    expect(
+      [  // events
+        { label: "onBeforeRequest",
+          event: "onBeforeRequest",
+          details: {
+            url: url,
+            frameUrl: url
+          },
+          retval: {}
+        },
+        { label: "onBeforeSendHeaders",
+          event: "onBeforeSendHeaders",
+          details: {
+            url: url,
+            // Note: no requestHeaders because we don't ask for them.
+          },
+          retval: {}
+        },
+        { label: "onSendHeaders",
+          event: "onSendHeaders",
+          details: {
+            url: url,
+          }
+        },
+        { label: "onHeadersReceived",
+          event: "onHeadersReceived",
+          details: {
+            url: url,
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+            statusCode: 401,
+          }
+        },
+        { label: "onAuthRequired",
+          event: "onAuthRequired",
+          details: {
+            url: url,
+            isProxy: false,
+            scheme: "basic",
+            realm: realm,
+            challenger: {host: testServer, port: testServerPort},
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 401 Unauthorized",
+            statusCode: 401,
+          },
+          retval: {authCredentials: {username: "foo", password: "secret"}}
+        },
+        { label: "onResponseStarted",
+          event: "onResponseStarted",
+          details: {
+            url: url,
+            fromCache: false,
+            statusCode: 200,
+            ip: "127.0.0.1",
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 200 OK",
+          }
+        },
+        { label: "onCompleted",
+          event: "onCompleted",
+          details: {
+            url: url,
+            fromCache: false,
+            statusCode: 200,
+            ip: "127.0.0.1",
+            responseHeadersExist: true,
+            statusLine: "HTTP/1.1 200 OK",
+          }
+        },
+      ],
+      [  // event order
+        ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
+         "onHeadersReceived", "onAuthRequired", "onResponseStarted",
+         "onCompleted"]
+      ],
+      {urls: ["<all_urls>"]},
+      ["responseHeaders", "asyncBlocking"]);
+    navigateAndWait(url);
+  },
+]);
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_auth_required_parallel.html b/chrome/test/data/extensions/api_test/webrequest/test_auth_required_parallel.html
new file mode 100644
index 0000000..84d5d6e4
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webrequest/test_auth_required_parallel.html
@@ -0,0 +1,7 @@
+<!--
+ * 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.
+-->
+<script src="framework.js"></script>
+<script src="test_auth_required_parallel.js"></script>
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_auth_required_parallel.js b/chrome/test/data/extensions/api_test/webrequest/test_auth_required_parallel.js
new file mode 100644
index 0000000..ec644ec3
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webrequest/test_auth_required_parallel.js
@@ -0,0 +1,261 @@
+// 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.
+
+// Generates a unique authentication URL so each test can run
+// without hitting the HTTP authentication cache. Each test
+// must use a unique realm, however.
+function getURLAuthRequired(realm, subpath = 'subpath') {
+  return getServerURL(
+      'auth-basic/' + realm + '/' + subpath + '?realm=' + realm);
+}
+
+runTests([
+  // Test that two parallel onAuthRequired signals do not interfere with each
+  // other. This is a regression test for https://crbug.com/931479.
+  function authRequiredParallel() {
+    const realm = 'parallelasync';
+
+    const imgUrl1 = getURLAuthRequired(realm, '1');
+    const imgUrl2 = getURLAuthRequired(realm, '2');
+    const initiator = getServerDomain(initiators.WEB_INITIATED);
+    const parallelAuthRequestsUrl = getServerURL(
+        'extensions/api_test/webrequest/auth_parallel?img1=' +
+        encodeURIComponent(imgUrl1) + '&img2=' + encodeURIComponent(imgUrl2));
+
+    function createExternallyResolvablePromise() {
+      let _resolve;
+      const promise = new Promise((resolve, reject) => _resolve = resolve);
+      promise.resolve = _resolve;
+      return promise;
+    }
+
+    // Create some promises that will resolved to callbacks when onAuthRequired
+    // and onComplete fire.
+    const authRequired1 = createExternallyResolvablePromise();
+    const completed1 = createExternallyResolvablePromise();
+    const authRequired2 = createExternallyResolvablePromise();
+
+    // responseStarted2 is whether the request for |imgUrl2| has signalled
+    // |onResponseStarted| yet.
+    let responseStarted2 = false;
+
+    expect(
+      [  // events
+        { label: 'onBeforeRequest-1',
+          event: 'onBeforeRequest',
+          details: {
+            url: imgUrl1,
+            type: 'image',
+            initiator: initiator,
+            // The testing framework cannot recover the frame URL because the
+            // URL filter below does not capture the top-level request.
+            frameUrl: 'unknown frame URL',
+          },
+        },
+        { label: 'onBeforeSendHeaders-1',
+          event: 'onBeforeSendHeaders',
+          details: {
+            url: imgUrl1,
+            type: 'image',
+            initiator: initiator,
+            // Note: no requestHeaders because we don't ask for them.
+          },
+          retval: {}
+        },
+        { label: 'onSendHeaders-1',
+          event: 'onSendHeaders',
+          details: {
+            url: imgUrl1,
+            type: 'image',
+            initiator: initiator,
+          }
+        },
+        { label: 'onHeadersReceived-1',
+          event: 'onHeadersReceived',
+          details: {
+            url: imgUrl1,
+            type: 'image',
+            initiator: initiator,
+            responseHeadersExist: true,
+            statusLine: 'HTTP/1.1 401 Unauthorized',
+            statusCode: 401,
+          }
+        },
+        { label: 'onAuthRequired-1',
+          event: 'onAuthRequired',
+          details: {
+            url: imgUrl1,
+            type: 'image',
+            initiator: initiator,
+            isProxy: false,
+            scheme: 'basic',
+            realm: realm,
+            challenger: {host: testServer, port: testServerPort},
+            responseHeadersExist: true,
+            statusLine: 'HTTP/1.1 401 Unauthorized',
+            statusCode: 401,
+          },
+          retval_function:
+              (name, details, callback) => authRequired1.resolve(callback),
+        },
+        { label: 'onResponseStarted-1',
+          event: 'onResponseStarted',
+          details: {
+            url: imgUrl1,
+            type: 'image',
+            initiator: initiator,
+            fromCache: false,
+            statusCode: 200,
+            ip: '127.0.0.1',
+            responseHeadersExist: true,
+            statusLine: 'HTTP/1.1 200 OK',
+          }
+        },
+        { label: 'onCompleted-1',
+          event: 'onCompleted',
+          details: {
+            url: imgUrl1,
+            type: 'image',
+            initiator: initiator,
+            fromCache: false,
+            statusCode: 200,
+            ip: '127.0.0.1',
+            responseHeadersExist: true,
+            statusLine: 'HTTP/1.1 200 OK',
+          },
+          retval_function: (name, details) => completed1.resolve(),
+        },
+        { label: 'onBeforeRequest-2',
+          event: 'onBeforeRequest',
+          details: {
+            url: imgUrl2,
+            type: 'image',
+            initiator: initiator,
+            // The testing framework cannot recover the frame URL because the
+            // URL filter below does not capture the top-level request.
+            frameUrl: 'unknown frame URL',
+          },
+        },
+        { label: 'onBeforeSendHeaders-2',
+          event: 'onBeforeSendHeaders',
+          details: {
+            url: imgUrl2,
+            type: 'image',
+            initiator: initiator,
+            // Note: no requestHeaders because we don't ask for them.
+          },
+          retval: {}
+        },
+        { label: 'onSendHeaders-2',
+          event: 'onSendHeaders',
+          details: {
+            url: imgUrl2,
+            type: 'image',
+            initiator: initiator,
+          }
+        },
+        { label: 'onHeadersReceived-2',
+          event: 'onHeadersReceived',
+          details: {
+            url: imgUrl2,
+            type: 'image',
+            initiator: initiator,
+            responseHeadersExist: true,
+            statusLine: 'HTTP/1.1 401 Unauthorized',
+            statusCode: 401,
+          }
+        },
+        { label: 'onAuthRequired-2',
+          event: 'onAuthRequired',
+          details: {
+            url: imgUrl2,
+            type: 'image',
+            initiator: initiator,
+            isProxy: false,
+            scheme: 'basic',
+            realm: realm,
+            challenger: {host: testServer, port: testServerPort},
+            responseHeadersExist: true,
+            statusLine: 'HTTP/1.1 401 Unauthorized',
+            statusCode: 401,
+          },
+          retval_function:
+              (name, details, callback) => authRequired2.resolve(callback),
+        },
+        { label: 'onResponseStarted-2',
+          event: 'onResponseStarted',
+          details: {
+            url: imgUrl2,
+            type: 'image',
+            initiator: initiator,
+            fromCache: false,
+            statusCode: 401,
+            ip: '127.0.0.1',
+            responseHeadersExist: true,
+            statusLine: 'HTTP/1.1 401 Unauthorized',
+          },
+          retval_function: (name, details) => responseStarted2 = true,
+        },
+        { label: 'onCompleted-2',
+          event: 'onCompleted',
+          details: {
+            url: imgUrl2,
+            type: 'image',
+            initiator: initiator,
+            fromCache: false,
+            statusCode: 401,
+            ip: '127.0.0.1',
+            responseHeadersExist: true,
+            statusLine: 'HTTP/1.1 401 Unauthorized',
+          }
+        },
+      ],
+      [  // event order
+        ['onBeforeRequest-1', 'onBeforeSendHeaders-1', 'onSendHeaders-1',
+         'onHeadersReceived-1', 'onAuthRequired-1', 'onResponseStarted-1',
+         'onCompleted-1'],
+        ['onBeforeRequest-2', 'onBeforeSendHeaders-2', 'onSendHeaders-2',
+         'onHeadersReceived-2', 'onAuthRequired-2', 'onResponseStarted-2',
+         'onCompleted-2']
+      ],
+      // Only pay attention to |imgUrl1| and |imgUrl2|, not
+      // |parallelAuthRequestsUrl|.
+      {urls: ['<all_urls>'], types: ['image']},
+      ['responseHeaders', 'asyncBlocking']);
+
+    navigateAndWait(parallelAuthRequestsUrl);
+    (async function() {
+      // Wait for onAuthRequired to be signaled for both requests before doing
+      // anything.
+      const callback1 = await authRequired1;
+      const callback2 = await authRequired2;
+
+      // Resolve the first request and let it complete.
+      callback1({authCredentials: {username: 'foo', password: 'secret'}});
+      await completed1;
+
+      // We wish to test that this did not resolve |callback2| with the same
+      // credentials internally. This would cause |imgUrl2| to signal
+      // |onResponseStarted| and |onCompleted| though it should be blocked.
+      chrome.test.assertFalse(responseStarted2);
+
+      // However it's possible that the second request may be much slower than
+      // the first, causing the above check to pass even if we don't correctly
+      // isolate the two authentication requests.
+      //
+      // Per the webRequest documentation, |onBeforeSendHeaders| should be
+      // signaled after a resolved |onAuthRequired|. This happens without a
+      // network delay, so it would make a fairly reliable test. However,
+      // webRequest does not match the documentation and does not signal it. See
+      // https://crbug.com/809761.
+      //
+      // Instead, resolve the second request, this time canceling the
+      // authentication request. This should result in |imgUrl2| completing with
+      // a 401 response. If the credentials were incorrectly propagated from
+      // |imgUrl1|, this will be ignored and |imgUrl2| will complete with a 200
+      // response.
+      callback2({cancel: true});
+    })();
+  },
+]);
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index 87328b61..93bf44d0 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -13,6 +13,11 @@
 const base::Feature kAutoScreenBrightness{"AutoScreenBrightness",
                                           base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Feature containing param to block provided long term keys.
+const base::Feature kBlueZLongTermKeyBlocklist{
+    "BlueZLongTermKeyBlocklist", base::FEATURE_DISABLED_BY_DEFAULT};
+const char kBlueZLongTermKeyBlocklistParamName[] = "ltk_blocklist";
+
 // Enables or disables Crostini Backup.
 const base::Feature kCrostiniBackup{"CrostiniBackup",
                                     base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h
index f5681ba..a2f602b 100644
--- a/chromeos/constants/chromeos_features.h
+++ b/chromeos/constants/chromeos_features.h
@@ -17,6 +17,10 @@
 
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kAutoScreenBrightness;
+COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
+extern const base::Feature kBlueZLongTermKeyBlocklist;
+COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
+extern const char kBlueZLongTermKeyBlocklistParamName[];
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kCrostiniBackup;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kCrostiniUsbSupport;
diff --git a/components/autofill/content/common/autofill_driver.mojom b/components/autofill/content/common/autofill_driver.mojom
index 1235cd0..433bd60 100644
--- a/components/autofill/content/common/autofill_driver.mojom
+++ b/components/autofill/content/common/autofill_driver.mojom
@@ -167,4 +167,8 @@
   // Instructs the browser that form no longer contains a generated password and
   // the presaved form should be removed.
   PasswordNoLongerGenerated(PasswordForm password_form);
+
+  // Communicates to the browser that a scroll event happened on the frame. This
+  // event affects the password generation popup position.
+  FrameWasScrolled();
 };
diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc
index 7a802fe..bbf4c19 100644
--- a/components/autofill/content/renderer/password_generation_agent.cc
+++ b/components/autofill/content/renderer/password_generation_agent.cc
@@ -335,6 +335,12 @@
   generation_enabled_fields_.clear();
 }
 
+void PasswordGenerationAgent::DidChangeScrollOffset() {
+  if (!current_generation_item_)
+    return;
+  GetPasswordGenerationDriver()->FrameWasScrolled();
+}
+
 void PasswordGenerationAgent::DidFinishDocumentLoad() {
   FindPossibleGenerationForm();
 }
@@ -720,6 +726,7 @@
     if (current_generation_item_->generation_element_.Value().length() <
         kMinimumLengthForEditedPassword) {
       PasswordNoLongerGenerated();
+      MaybeOfferAutomaticGeneration();
       if (current_generation_item_->generation_element_.Value().IsEmpty())
         current_generation_item_->generation_element_.SetShouldRevealPassword(
             false);
diff --git a/components/autofill/content/renderer/password_generation_agent.h b/components/autofill/content/renderer/password_generation_agent.h
index 40915c5..170a7bf4 100644
--- a/components/autofill/content/renderer/password_generation_agent.h
+++ b/components/autofill/content/renderer/password_generation_agent.h
@@ -114,6 +114,7 @@
   // RenderFrameObserver:
   void DidCommitProvisionalLoad(bool is_same_document_navigation,
                                 ui::PageTransition transition) override;
+  void DidChangeScrollOffset() override;
   void DidFinishDocumentLoad() override;
   void DidFinishLoad() override;
   void OnDestruct() override;
diff --git a/components/autofill/ios/browser/autofill_agent_unittests.mm b/components/autofill/ios/browser/autofill_agent_unittests.mm
index aa919a3..c91d2a3 100644
--- a/components/autofill/ios/browser/autofill_agent_unittests.mm
+++ b/components/autofill/ios/browser/autofill_agent_unittests.mm
@@ -157,7 +157,7 @@
       "\"value\":\"name_value\"},"
       "\"number\":{\"section\":\"\",\"value\":\"number_value\"}},"
       "\"formName\":\"CC form\"}, \"\");",
-      fake_main_frame_->last_javascript_call());
+      fake_main_frame_->GetLastJavaScriptCall());
 }
 
 // Tests that in the case of conflict in fields' identifiers, the last seen
@@ -203,12 +203,11 @@
   [autofill_agent_ fillFormData:form
                         inFrame:web::GetMainWebFrame(&test_web_state_)];
   test_web_state_.WasShown();
-  EXPECT_EQ(
-      "__gCrWeb.autofill.fillForm({\"fields\":{\"field1\":{\"section\":"
-      "\"\",\"value\":\"value "
-      "2\"},\"region\":{\"section\":\"\",\"value\":\"California\"}},"
-      "\"formName\":\"\"}, \"\");",
-      fake_main_frame_->last_javascript_call());
+  EXPECT_EQ("__gCrWeb.autofill.fillForm({\"fields\":{\"field1\":{\"section\":"
+            "\"\",\"value\":\"value "
+            "2\"},\"region\":{\"section\":\"\",\"value\":\"California\"}},"
+            "\"formName\":\"\"}, \"\");",
+            fake_main_frame_->GetLastJavaScriptCall());
 }
 
 // Tests that when a user initiated form activity is registered the script to
@@ -233,7 +232,7 @@
                                     completionHandler:nil];
   test_web_state_.WasShown();
   EXPECT_EQ("__gCrWeb.autofill.extractForms(1, true);",
-            fake_main_frame_->last_javascript_call());
+            fake_main_frame_->GetLastJavaScriptCall());
 }
 
 // Tests that when a non user initiated form activity is registered the
diff --git a/components/device_event_log/device_event_log.h b/components/device_event_log/device_event_log.h
index f5afc12f..417f743 100644
--- a/components/device_event_log/device_event_log.h
+++ b/components/device_event_log/device_event_log.h
@@ -63,6 +63,9 @@
 #define PRINTER_LOG(level)                         \
   DEVICE_LOG(::device_event_log::LOG_TYPE_PRINTER, \
              ::device_event_log::LOG_LEVEL_##level)
+#define FIDO_LOG(level)                         \
+  DEVICE_LOG(::device_event_log::LOG_TYPE_FIDO, \
+             ::device_event_log::LOG_LEVEL_##level)
 
 // Generally prefer the above macros unless |type| or |level| is not constant.
 
@@ -106,8 +109,10 @@
   LOG_TYPE_MEMORY = 6,
   // Printer related events.
   LOG_TYPE_PRINTER = 7,
+  // Security key events.
+  LOG_TYPE_FIDO = 8,
   // Used internally, must be the last type (may be changed).
-  LOG_TYPE_UNKNOWN = 8
+  LOG_TYPE_UNKNOWN = 9
 };
 
 // Used to specify the detail level for logging. In GetAsString, used to
diff --git a/components/device_event_log/device_event_log_impl.cc b/components/device_event_log/device_event_log_impl.cc
index 9f5c4352a..2b6e8f7 100644
--- a/components/device_event_log/device_event_log_impl.cc
+++ b/components/device_event_log/device_event_log_impl.cc
@@ -34,6 +34,7 @@
 const char* kLogTypeHidDesc = "HID";
 const char* kLogTypeMemoryDesc = "Memory";
 const char* kLogTypePrinterDesc = "Printer";
+const char* kLogTypeFidoDesc = "FIDO";
 
 std::string GetLogTypeString(LogType type) {
   switch (type) {
@@ -53,6 +54,8 @@
       return kLogTypeMemoryDesc;
     case LOG_TYPE_PRINTER:
       return kLogTypePrinterDesc;
+    case LOG_TYPE_FIDO:
+      return kLogTypeFidoDesc;
     case LOG_TYPE_UNKNOWN:
       break;
   }
diff --git a/components/download/internal/common/android/download_collection_bridge.cc b/components/download/internal/common/android/download_collection_bridge.cc
index bb80514..5f17a68 100644
--- a/components/download/internal/common/android/download_collection_bridge.cc
+++ b/components/download/internal/common/android/download_collection_bridge.cc
@@ -119,7 +119,7 @@
 }
 
 // static
-bool DownloadCollectionBridge::renameDownloadUri(
+bool DownloadCollectionBridge::RenameDownloadUri(
     const base::FilePath& download_uri,
     const base::FilePath& new_display_name) {
   JNIEnv* env = base::android::AttachCurrentThread();
diff --git a/components/download/internal/common/android/download_collection_bridge.h b/components/download/internal/common/android/download_collection_bridge.h
index 70fd560..e565b4e 100644
--- a/components/download/internal/common/android/download_collection_bridge.h
+++ b/components/download/internal/common/android/download_collection_bridge.h
@@ -59,7 +59,7 @@
   // Renames a content URI download to |new_display_name|. Returns true on
   // success, and false otherwise.
   // Called on non UI thread.
-  static bool renameDownloadUri(const base::FilePath& download_uri,
+  static bool RenameDownloadUri(const base::FilePath& download_uri,
                                 const base::FilePath& new_display_name);
 
   // Whether download display names needs to be retrieved.
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc
index 233043e..02725fd 100644
--- a/components/download/internal/common/download_item_impl.cc
+++ b/components/download/internal/common/download_item_impl.cc
@@ -617,7 +617,6 @@
 
   InterruptAndDiscardPartialState(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
   UpdateObservers();
-
   NotifyRemoved();
   delegate_->DownloadRemoved(this);
   // We have now been deleted.
@@ -662,21 +661,37 @@
 }
 
 void DownloadItemImpl::RenameDownloadedFileDone(RenameDownloadCallback callback,
+                                                const base::FilePath& new_path,
                                                 DownloadRenameResult result) {
-  if (std::move(result) == DownloadRenameResult::SUCCESS) {
-    NOTIMPLEMENTED();
+  if (result == DownloadRenameResult::SUCCESS) {
+    destination_info_.target_path = new_path;
+    destination_info_.current_path = new_path;
+    UpdateObservers();
   }
   std::move(callback).Run(result);
 }
 
-void DownloadItemImpl::Rename(const std::string& name,
+void DownloadItemImpl::Rename(const base::FilePath& name,
                               DownloadItem::RenameDownloadCallback callback) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  if (name.IsAbsolute()) {
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(&DownloadItemImpl::RenameDownloadedFileDone,
+                                  weak_ptr_factory_.GetWeakPtr(),
+                                  std::move(callback), GetFullPath(),
+                                  DownloadRenameResult::FAILURE_NAME_INVALID));
+    return;
+  }
+
+  auto full_path = base::FilePath(GetFullPath().DirName()).Append(name);
+
   base::PostTaskAndReplyWithResult(
       GetDownloadTaskRunner().get(), FROM_HERE,
-      base::BindOnce(&download::RenameDownloadedFile, GetFullPath(), name),
+      base::BindOnce(&download::RenameDownloadedFile, GetFullPath(), full_path),
       base::BindOnce(&DownloadItemImpl::RenameDownloadedFileDone,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                     full_path));
 }
 
 uint32_t DownloadItemImpl::GetId() const {
diff --git a/components/download/internal/common/download_utils.cc b/components/download/internal/common/download_utils.cc
index 89ef0358..1d3fefb 100644
--- a/components/download/internal/common/download_utils.cc
+++ b/components/download/internal/common/download_utils.cc
@@ -6,8 +6,10 @@
 
 #include "base/files/file_util.h"
 #include "base/format_macros.h"
+#include "base/i18n/file_util_icu.h"
 #include "base/rand_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "components/download/public/common/download_create_info.h"
 #include "components/download/public/common/download_interrupt_reasons_utils.h"
@@ -19,9 +21,9 @@
 #include "net/http/http_request_headers.h"
 #include "net/http/http_status_code.h"
 #include "services/network/public/cpp/resource_request.h"
-
 #if defined(OS_ANDROID)
 #include "base/android/content_uri_utils.h"
+#include "components/download/internal/common/android/download_collection_bridge.h"
 #endif
 
 namespace download {
@@ -550,9 +552,39 @@
 }
 
 download::DownloadItem::DownloadRenameResult RenameDownloadedFile(
-    const base::FilePath& oldpath,
-    const std::string& name) {
-  NOTIMPLEMENTED();
-  return DownloadItem::DownloadRenameResult::SUCCESS;
+    const base::FilePath& from_path,
+    const base::FilePath& to_path) {
+  if (!base::PathExists(from_path) ||
+      !base::DirectoryExists(from_path.DirName()))
+    return DownloadItem::DownloadRenameResult::FAILURE_UNAVAILABLE;
+
+  if (!base::DirectoryExists(to_path.DirName()))
+    return DownloadItem::DownloadRenameResult::FAILURE_NAME_INVALID;
+
+  if (base::PathExists(to_path))
+    return DownloadItem::DownloadRenameResult::FAILURE_NAME_CONFLICT;
+
+  int max_path_component_length =
+      base::GetMaximumPathComponentLength(to_path.DirName());
+  if (max_path_component_length != -1) {
+    if (static_cast<int>(to_path.value().length()) >=
+        max_path_component_length) {
+      return DownloadItem::DownloadRenameResult::FAILURE_NAME_TOO_LONG;
+    }
+  }
+#if defined(OS_ANDROID)
+  if (from_path.IsContentUri()) {
+    return DownloadCollectionBridge::RenameDownloadUri(from_path,
+                                                       to_path.BaseName())
+               ? download::DownloadItem::DownloadRenameResult::SUCCESS
+               : download::DownloadItem::DownloadRenameResult::
+                     FAILURE_NAME_INVALID;
+  }
+#endif
+
+  return base::Move(from_path, to_path)
+             ? download::DownloadItem::DownloadRenameResult::SUCCESS
+             : download::DownloadItem::DownloadRenameResult::
+                   FAILURE_NAME_INVALID;
 }
 }  // namespace download
diff --git a/components/download/public/common/download_item.h b/components/download/public/common/download_item.h
index cc3e40ba..cfd9d19 100644
--- a/components/download/public/common/download_item.h
+++ b/components/download/public/common/download_item.h
@@ -91,8 +91,9 @@
     SUCCESS = 0,
     FAILURE_NAME_CONFLICT = 1,
     FAILURE_NAME_TOO_LONG = 2,
-    FAILURE_NAME_UNAVIALABLE = 3,
-    FAILURE_UNKNOWN = 4,
+    FAILURE_NAME_INVALID = 3,
+    FAILURE_UNAVAILABLE = 4,
+    FAILURE_UNKNOWN = 5,
     RESULT_MAX = FAILURE_UNKNOWN
   };
 
@@ -192,9 +193,10 @@
   // Show the download via the OS shell.
   virtual void ShowDownloadInShell() = 0;
 
-  // Rename a downloaded item to |name|, implementer should post and reply the
-  // result.
-  virtual void Rename(const std::string& name,
+  // Rename a downloaded item to |new_name|, implementer should post and reply
+  // the result. Do not pass the full file path, just pass the file name portion
+  // instead.
+  virtual void Rename(const base::FilePath& new_name,
                       RenameDownloadCallback callback) = 0;
 
   // State accessors -----------------------------------------------------------
diff --git a/components/download/public/common/download_item_impl.h b/components/download/public/common/download_item_impl.h
index 64d3b2ba..7e1937d5 100644
--- a/components/download/public/common/download_item_impl.h
+++ b/components/download/public/common/download_item_impl.h
@@ -222,7 +222,7 @@
   void Remove() override;
   void OpenDownload() override;
   void ShowDownloadInShell() override;
-  void Rename(const std::string& name,
+  void Rename(const base::FilePath& name,
               RenameDownloadCallback callback) override;
   uint32_t GetId() const override;
   const std::string& GetGuid() const override;
@@ -638,6 +638,7 @@
   DownloadItem::DownloadRenameResult RenameDownloadedFile(
       const std::string& name);
   void RenameDownloadedFileDone(RenameDownloadCallback callback,
+                                const base::FilePath& new_path,
                                 DownloadRenameResult result);
 
   static DownloadState InternalToExternalState(
diff --git a/components/download/public/common/download_utils.h b/components/download/public/common/download_utils.h
index 079bcdd..dfeb282 100644
--- a/components/download/public/common/download_utils.h
+++ b/components/download/public/common/download_utils.h
@@ -99,7 +99,8 @@
 
 // Rename downloaded file from |oldpath| to newname.
 COMPONENTS_DOWNLOAD_EXPORT download::DownloadItem::DownloadRenameResult
-RenameDownloadedFile(const base::FilePath& path, const std::string& new_name);
+RenameDownloadedFile(const base::FilePath& from_path,
+                     const base::FilePath& to_path);
 }  // namespace download
 
 #endif  // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_UTILS_H_
diff --git a/components/download/public/common/mock_download_item.h b/components/download/public/common/mock_download_item.h
index d36ba67..98420c1 100644
--- a/components/download/public/common/mock_download_item.h
+++ b/components/download/public/common/mock_download_item.h
@@ -119,7 +119,7 @@
   MOCK_METHOD1(SetDisplayName, void(const base::FilePath&));
   MOCK_CONST_METHOD1(DebugString, std::string(bool));
   MOCK_METHOD1(SimulateErrorForTesting, void(DownloadInterruptReason));
-  MOCK_METHOD2(Rename, void(const std::string&, RenameDownloadCallback));
+  MOCK_METHOD2(Rename, void(const base::FilePath&, RenameDownloadCallback));
 
  private:
   base::ObserverList<Observer>::Unchecked observers_;
diff --git a/components/offline_items_collection/core/android/offline_item_bridge.cc b/components/offline_items_collection/core/android/offline_item_bridge.cc
index 3b8a65a1..5f59cf8 100644
--- a/components/offline_items_collection/core/android/offline_item_bridge.cc
+++ b/components/offline_items_collection/core/android/offline_item_bridge.cc
@@ -64,10 +64,8 @@
     const std::vector<OfflineItem>& items) {
   ScopedJavaLocalRef<jobject> jlist =
       Java_OfflineItemBridge_createArrayList(env);
-
   for (const auto& item : items)
     JNI_OfflineItemBridge_createOfflineItemAndMaybeAddToList(env, jlist, item);
-
   return jlist;
 }
 
diff --git a/components/offline_items_collection/core/offline_content_aggregator.cc b/components/offline_items_collection/core/offline_content_aggregator.cc
index 5719eb61..5737275 100644
--- a/components/offline_items_collection/core/offline_content_aggregator.cc
+++ b/components/offline_items_collection/core/offline_content_aggregator.cc
@@ -227,8 +227,8 @@
   auto it = providers_.find(id.name_space);
   if (it == providers_.end()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(std::move(callback),
-                                  RenameResult::FAILURE_NAME_UNAVIALABLE));
+        FROM_HERE,
+        base::BindOnce(std::move(callback), RenameResult::FAILURE_UNAVAILABLE));
     return;
   }
   it->second->RenameItem(id, name, std::move(callback));
diff --git a/components/offline_items_collection/core/rename_result.h b/components/offline_items_collection/core/rename_result.h
index 151ca737..67e4e5c 100644
--- a/components/offline_items_collection/core/rename_result.h
+++ b/components/offline_items_collection/core/rename_result.h
@@ -9,11 +9,12 @@
 // A Java counterpart will be generated for this enum.
 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.offline_items_collection
 enum class RenameResult {
-  SUCCESS = 0,                   // Rename filename successfully
-  FAILURE_NAME_CONFLICT = 1,     // Filename already exists
-  FAILURE_NAME_TOO_LONG = 2,     // Illegal file name: too long
-  FAILURE_NAME_UNAVIALABLE = 3,  // Name unavailable
-  FAILURE_UNKNOWN = 4,           // Unknown
+  SUCCESS = 0,                // Rename filename successfully
+  FAILURE_NAME_CONFLICT = 1,  // Filename already exists
+  FAILURE_NAME_TOO_LONG = 2,  // Illegal file name: too long
+  FAILURE_NAME_INVALID = 3,   // Name invalid
+  FAILURE_UNAVAILABLE = 4,    // Item unavailable
+  FAILURE_UNKNOWN = 5,        // Unknown
   kMaxValue = FAILURE_UNKNOWN
 };
 
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index 222db5c..49c0226 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -302,6 +302,14 @@
     // converted back safely for the integer |scale_factor| in WebPrintParams.
     webkit_print_params->scale_factor =
         static_cast<int>(print_params.scale_factor * 100);
+
+#if defined(OS_MACOSX)
+    // For Mac, GetDPI() returns a value that avoids DPI-based scaling. This is
+    // correct except when rastering PDFs, which uses |printer_dpi|, and the
+    // value for |printer_dpi| is too low. Adjust that here.
+    // See https://crbug.com/943462
+    webkit_print_params->printer_dpi = kDefaultPdfDpi;
+#endif
   }
   webkit_print_params->rasterize_pdf = print_params.rasterize_pdf;
   webkit_print_params->print_scaling_option = print_params.print_scaling_option;
diff --git a/components/security_state/content/content_utils.cc b/components/security_state/content/content_utils.cc
index c8d55bf..b5e926f 100644
--- a/components/security_state/content/content_utils.cc
+++ b/components/security_state/content/content_utils.cc
@@ -20,6 +20,7 @@
 #include "content/public/browser/security_style_explanations.h"
 #include "content/public/browser/ssl_status.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/origin_util.h"
 #include "content/public/common/url_constants.h"
 #include "net/base/net_errors.h"
 #include "net/cert/x509_certificate.h"
@@ -57,15 +58,16 @@
 }
 
 void ExplainHTTPSecurity(
-    const security_state::SecurityInfo& security_info,
+    security_state::SecurityLevel security_level,
+    const security_state::VisibleSecurityState& visible_security_state,
     content::SecurityStyleExplanations* security_style_explanations) {
   // If the page triggers an HTTP-Bad dangerous warning, then override the main
   // summary for the page and add a bullet describing the issue.
-  if (security_info.security_level == security_state::DANGEROUS &&
-      !security_info.scheme_is_cryptographic) {
+  if (security_level == security_state::DANGEROUS &&
+      !security_state::IsSchemeCryptographic(visible_security_state.url)) {
     security_style_explanations->summary =
         l10n_util::GetStringUTF8(IDS_HTTP_NONSECURE_SUMMARY);
-    if (security_info.insecure_input_events.insecure_field_edited) {
+    if (visible_security_state.insecure_input_events.insecure_field_edited) {
       security_style_explanations->insecure_explanations.push_back(
           content::SecurityStyleExplanation(
               l10n_util::GetStringUTF8(IDS_EDITED_NONSECURE),
@@ -75,9 +77,9 @@
 }
 
 void ExplainSafeBrowsingSecurity(
-    const security_state::SecurityInfo& security_info,
+    const security_state::VisibleSecurityState& visible_security_state,
     content::SecurityStyleExplanations* security_style_explanations) {
-  DCHECK_NE(security_info.malicious_content_status,
+  DCHECK_NE(visible_security_state.malicious_content_status,
             MALICIOUS_CONTENT_STATUS_NONE);
 
   // Override the main summary for the page.
@@ -91,48 +93,52 @@
 }
 
 void ExplainCertificateSecurity(
-    const security_state::SecurityInfo& security_info,
+    const security_state::VisibleSecurityState& visible_security_state,
     content::SecurityStyleExplanations* security_style_explanations) {
-  if (security_info.sha1_in_chain) {
+  if (security_state::IsSHA1InChain(visible_security_state)) {
     content::SecurityStyleExplanation explanation(
         l10n_util::GetStringUTF8(IDS_CERTIFICATE_TITLE),
         l10n_util::GetStringUTF8(IDS_SHA1),
         l10n_util::GetStringUTF8(IDS_SHA1_DESCRIPTION),
-        security_info.certificate,
+        visible_security_state.certificate,
         blink::WebMixedContentContextType::kNotMixedContent);
     // The impact of SHA1 on the certificate status depends on
     // the EnableSHA1ForLocalAnchors policy.
-    if (security_info.cert_status & net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM) {
+    if (visible_security_state.cert_status &
+        net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM) {
       security_style_explanations->insecure_explanations.push_back(explanation);
     } else {
       security_style_explanations->neutral_explanations.push_back(explanation);
     }
   }
 
-  if (security_info.cert_missing_subject_alt_name) {
+  if (visible_security_state.certificate &&
+      !visible_security_state.certificate->GetSubjectAltName(nullptr,
+                                                             nullptr)) {
     security_style_explanations->insecure_explanations.push_back(
         content::SecurityStyleExplanation(
             l10n_util::GetStringUTF8(IDS_CERTIFICATE_TITLE),
             l10n_util::GetStringUTF8(IDS_SUBJECT_ALT_NAME_MISSING),
             l10n_util::GetStringUTF8(IDS_SUBJECT_ALT_NAME_MISSING_DESCRIPTION),
-            security_info.certificate,
+            visible_security_state.certificate,
             blink::WebMixedContentContextType::kNotMixedContent));
   }
 
-  bool is_cert_status_error = net::IsCertStatusError(security_info.cert_status);
+  bool is_cert_status_error =
+      net::IsCertStatusError(visible_security_state.cert_status);
   bool is_cert_status_minor_error =
-      net::IsCertStatusMinorError(security_info.cert_status);
+      net::IsCertStatusMinorError(visible_security_state.cert_status);
 
   if (is_cert_status_error) {
     base::string16 error_string = base::UTF8ToUTF16(net::ErrorToString(
-        net::MapCertStatusToNetError(security_info.cert_status)));
+        net::MapCertStatusToNetError(visible_security_state.cert_status)));
 
     content::SecurityStyleExplanation explanation(
         l10n_util::GetStringUTF8(IDS_CERTIFICATE_TITLE),
         l10n_util::GetStringUTF8(IDS_CERTIFICATE_CHAIN_ERROR),
         l10n_util::GetStringFUTF8(
             IDS_CERTIFICATE_CHAIN_ERROR_DESCRIPTION_FORMAT, error_string),
-        security_info.certificate,
+        visible_security_state.certificate,
         blink::WebMixedContentContextType::kNotMixedContent);
 
     if (is_cert_status_minor_error) {
@@ -145,10 +151,10 @@
     // an explanation that the certificate is valid.
 
     base::string16 issuer_name;
-    if (security_info.certificate) {
+    if (visible_security_state.certificate) {
       // This results in the empty string if there is no relevant display name.
       issuer_name = base::UTF8ToUTF16(
-          security_info.certificate->issuer().GetDisplayName());
+          visible_security_state.certificate->issuer().GetDisplayName());
     } else {
       issuer_name = base::string16();
     }
@@ -157,20 +163,21 @@
           l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY));
     }
 
-    if (!security_info.sha1_in_chain) {
+    if (!security_state::IsSHA1InChain(visible_security_state)) {
       security_style_explanations->secure_explanations.push_back(
           content::SecurityStyleExplanation(
               l10n_util::GetStringUTF8(IDS_CERTIFICATE_TITLE),
               l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE),
               l10n_util::GetStringFUTF8(
                   IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION, issuer_name),
-              security_info.certificate,
+              visible_security_state.certificate,
               blink::WebMixedContentContextType::kNotMixedContent));
     }
   }
 
-  security_style_explanations->pkp_bypassed = security_info.pkp_bypassed;
-  if (security_info.pkp_bypassed) {
+  security_style_explanations->pkp_bypassed =
+      visible_security_state.pkp_bypassed;
+  if (visible_security_state.pkp_bypassed) {
     security_style_explanations->info_explanations.push_back(
         content::SecurityStyleExplanation(
             l10n_util::GetStringUTF8(IDS_CERTIFICATE_TITLE),
@@ -179,11 +186,12 @@
                 IDS_PRIVATE_KEY_PINNING_BYPASSED_DESCRIPTION)));
   }
 
-  if (security_info.certificate &&
-      !security_info.certificate->valid_expiry().is_null() &&
-      (security_info.certificate->valid_expiry() - base::Time::Now())
+  if (visible_security_state.certificate &&
+      !visible_security_state.certificate->valid_expiry().is_null() &&
+      (visible_security_state.certificate->valid_expiry() - base::Time::Now())
               .InHours() < 48 &&
-      (security_info.certificate->valid_expiry() > base::Time::Now())) {
+      (visible_security_state.certificate->valid_expiry() >
+       base::Time::Now())) {
     security_style_explanations->info_explanations.push_back(
         content::SecurityStyleExplanation(
             l10n_util::GetStringUTF8(IDS_CERTIFICATE_EXPIRING_SOON),
@@ -193,17 +201,17 @@
 }
 
 void ExplainConnectionSecurity(
-    const security_state::SecurityInfo& security_info,
+    const security_state::VisibleSecurityState& visible_security_state,
     content::SecurityStyleExplanations* security_style_explanations) {
   // Avoid showing TLS details when we couldn't even establish a TLS connection
   // (e.g. for net errors) or if there was no real connection (some tests). We
   // check the |connection_status| to see if there was a connection.
-  if (security_info.connection_status == 0) {
+  if (visible_security_state.connection_status == 0) {
     return;
   }
 
-  int ssl_version =
-      net::SSLConnectionStatusToVersion(security_info.connection_status);
+  int ssl_version = net::SSLConnectionStatusToVersion(
+      visible_security_state.connection_status);
   const char* protocol;
   net::SSLVersionToString(&protocol, ssl_version);
   const char* key_exchange;
@@ -211,8 +219,8 @@
   const char* mac;
   bool is_aead;
   bool is_tls13;
-  uint16_t cipher_suite =
-      net::SSLConnectionStatusToCipherSuite(security_info.connection_status);
+  uint16_t cipher_suite = net::SSLConnectionStatusToCipherSuite(
+      visible_security_state.connection_status);
   net::SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead,
                                &is_tls13, cipher_suite);
   const base::string16 protocol_name = base::ASCIIToUTF16(protocol);
@@ -227,17 +235,19 @@
   base::string16 key_exchange_name;
   if (is_tls13) {
     key_exchange_name = base::ASCIIToUTF16(
-        SSL_get_curve_name(security_info.key_exchange_group));
-  } else if (security_info.key_exchange_group != 0) {
+        SSL_get_curve_name(visible_security_state.key_exchange_group));
+  } else if (visible_security_state.key_exchange_group != 0) {
     key_exchange_name = l10n_util::GetStringFUTF16(
         IDS_SSL_KEY_EXCHANGE_WITH_GROUP, base::ASCIIToUTF16(key_exchange),
         base::ASCIIToUTF16(
-            SSL_get_curve_name(security_info.key_exchange_group)));
+            SSL_get_curve_name(visible_security_state.key_exchange_group)));
   } else {
     key_exchange_name = base::ASCIIToUTF16(key_exchange);
   }
 
-  int status = security_info.obsolete_ssl_status;
+  int status =
+      net::ObsoleteSSLStatus(visible_security_state.connection_status,
+                             visible_security_state.peer_signature_algorithm);
   if (status == net::OBSOLETE_SSL_NONE) {
     security_style_explanations->secure_explanations.emplace_back(
         l10n_util::GetStringUTF8(IDS_SSL_CONNECTION_TITLE),
@@ -277,7 +287,7 @@
 }
 
 void ExplainContentSecurity(
-    const security_state::SecurityInfo& security_info,
+    const security_state::VisibleSecurityState& visible_security_state,
     content::SecurityStyleExplanations* security_style_explanations) {
   security_style_explanations->ran_insecure_content_style =
       SecurityLevelToSecurityStyle(security_state::kRanInsecureContentLevel);
@@ -289,10 +299,7 @@
   bool add_secure_explanation = true;
 
   security_style_explanations->ran_mixed_content =
-      security_info.mixed_content_status ==
-          security_state::CONTENT_STATUS_RAN ||
-      security_info.mixed_content_status ==
-          security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
+      visible_security_state.ran_mixed_content;
   if (security_style_explanations->ran_mixed_content) {
     add_secure_explanation = false;
     security_style_explanations->insecure_explanations.push_back(
@@ -304,10 +311,7 @@
   }
 
   security_style_explanations->displayed_mixed_content =
-      security_info.mixed_content_status ==
-          security_state::CONTENT_STATUS_DISPLAYED ||
-      security_info.mixed_content_status ==
-          security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
+      visible_security_state.displayed_mixed_content;
   if (security_style_explanations->displayed_mixed_content) {
     add_secure_explanation = false;
     security_style_explanations->neutral_explanations.push_back(
@@ -319,7 +323,7 @@
   }
 
   security_style_explanations->contained_mixed_form =
-      security_info.contained_mixed_form;
+      visible_security_state.contained_mixed_form;
   if (security_style_explanations->contained_mixed_form) {
     add_secure_explanation = false;
     security_style_explanations->neutral_explanations.push_back(
@@ -335,15 +339,13 @@
   // main resource was loaded with major certificate errors because, in the
   // common case, these subresource certificate errors would be duplicative with
   // the main resource's error.
-  bool is_cert_status_error = net::IsCertStatusError(security_info.cert_status);
+  bool is_cert_status_error =
+      net::IsCertStatusError(visible_security_state.cert_status);
   bool is_cert_status_minor_error =
-      net::IsCertStatusMinorError(security_info.cert_status);
+      net::IsCertStatusMinorError(visible_security_state.cert_status);
   if (!is_cert_status_error || is_cert_status_minor_error) {
     security_style_explanations->ran_content_with_cert_errors =
-        security_info.content_with_cert_errors_status ==
-            security_state::CONTENT_STATUS_RAN ||
-        security_info.content_with_cert_errors_status ==
-            security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
+        visible_security_state.ran_content_with_cert_errors;
     if (security_style_explanations->ran_content_with_cert_errors) {
       add_secure_explanation = false;
       security_style_explanations->insecure_explanations.push_back(
@@ -355,10 +357,7 @@
     }
 
     security_style_explanations->displayed_content_with_cert_errors =
-        security_info.content_with_cert_errors_status ==
-            security_state::CONTENT_STATUS_DISPLAYED ||
-        security_info.content_with_cert_errors_status ==
-            security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
+        visible_security_state.displayed_content_with_cert_errors;
     if (security_style_explanations->displayed_content_with_cert_errors) {
       add_secure_explanation = false;
       security_style_explanations->neutral_explanations.push_back(
@@ -371,7 +370,7 @@
   }
 
   if (add_secure_explanation) {
-    DCHECK(security_info.scheme_is_cryptographic);
+    DCHECK(security_state::IsSchemeCryptographic(visible_security_state.url));
     security_style_explanations->secure_explanations.push_back(
         content::SecurityStyleExplanation(
             l10n_util::GetStringUTF8(IDS_RESOURCE_SECURITY_TITLE),
@@ -429,15 +428,20 @@
 }
 
 blink::WebSecurityStyle GetSecurityStyle(
-    const security_state::SecurityInfo& security_info,
+    security_state::SecurityLevel security_level,
+    const security_state::VisibleSecurityState& visible_security_state,
     content::SecurityStyleExplanations* security_style_explanations) {
   const blink::WebSecurityStyle security_style =
-      SecurityLevelToSecurityStyle(security_info.security_level);
+      SecurityLevelToSecurityStyle(security_level);
 
-  if (security_info.malicious_content_status !=
+  if (visible_security_state.malicious_content_status !=
       security_state::MALICIOUS_CONTENT_STATUS_NONE) {
-    ExplainSafeBrowsingSecurity(security_info, security_style_explanations);
-  } else if (security_info.is_non_cert_error_page) {
+    ExplainSafeBrowsingSecurity(visible_security_state,
+                                security_style_explanations);
+  } else if (visible_security_state.is_error_page &&
+             (!net::IsCertStatusError(visible_security_state.cert_status) ||
+              net::IsCertStatusMinorError(
+                  visible_security_state.cert_status))) {
     security_style_explanations->summary =
         l10n_util::GetStringUTF8(IDS_ERROR_PAGE_SUMMARY);
     // In the case of a non cert error page, we usually don't have a
@@ -445,7 +449,8 @@
     // the case of a net error, so we can early return.
     return security_style;
   } else {
-    ExplainHTTPSecurity(security_info, security_style_explanations);
+    ExplainHTTPSecurity(security_level, visible_security_state,
+                        security_style_explanations);
   }
 
   // Check if the page is HTTP; if so, no more explanations are needed. Note
@@ -456,21 +461,23 @@
   // if it wants to (for example, displaying deprecated crypto
   // algorithms with the same UI treatment as HTTP pages).
   security_style_explanations->scheme_is_cryptographic =
-      security_info.scheme_is_cryptographic;
-  if (!security_info.scheme_is_cryptographic) {
+      security_state::IsSchemeCryptographic(visible_security_state.url);
+  if (!security_style_explanations->scheme_is_cryptographic) {
     // Some origins are considered secure even if they're not cryptographic, so
     // display a more precise summary.
-    if (security_info.security_level == security_state::NONE &&
-        security_info.origin_is_secure) {
+    if (security_level == security_state::NONE &&
+        content::IsOriginSecure(visible_security_state.url)) {
       security_style_explanations->summary =
           l10n_util::GetStringUTF8(IDS_NON_CRYPTO_SECURE_SUMMARY);
     }
     return security_style;
   }
 
-  ExplainCertificateSecurity(security_info, security_style_explanations);
-  ExplainConnectionSecurity(security_info, security_style_explanations);
-  ExplainContentSecurity(security_info, security_style_explanations);
+  ExplainCertificateSecurity(visible_security_state,
+                             security_style_explanations);
+  ExplainConnectionSecurity(visible_security_state,
+                            security_style_explanations);
+  ExplainContentSecurity(visible_security_state, security_style_explanations);
 
   return security_style;
 }
diff --git a/components/security_state/content/content_utils.h b/components/security_state/content/content_utils.h
index f5488b0..b50f187 100644
--- a/components/security_state/content/content_utils.h
+++ b/components/security_state/content/content_utils.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "components/security_state/core/security_state.h"
 #include "third_party/blink/public/platform/web_security_style.h"
 
 namespace content {
@@ -15,23 +16,18 @@
 }  // namespace content
 
 namespace security_state {
-struct SecurityInfo;
-struct VisibleSecurityState;
-}  // namespace security_state
 
-namespace security_state {
-
-// Retrieves the visible security state that is relevant to GetSecurityInfo()
-// from the current page in |web_contents|.
+// Retrieves the visible security state from the current page in |web_contents|.
 std::unique_ptr<security_state::VisibleSecurityState> GetVisibleSecurityState(
     content::WebContents* web_contents);
 
 // Returns the SecurityStyle that should be applied to a WebContents
-// with the given |security_info|. Populates
+// with the given |security_level| and |visible_security_state|. Populates
 // |security_style_explanations| to explain why the returned
 // SecurityStyle was chosen.
 blink::WebSecurityStyle GetSecurityStyle(
-    const security_state::SecurityInfo& security_info,
+    security_state::SecurityLevel security_level,
+    const security_state::VisibleSecurityState& visible_security_state,
     content::SecurityStyleExplanations* security_style_explanations);
 
 }  // namespace security_state
diff --git a/components/security_state/content/content_utils_unittest.cc b/components/security_state/content/content_utils_unittest.cc
index fd58adb..44a97292 100644
--- a/components/security_state/content/content_utils_unittest.cc
+++ b/components/security_state/content/content_utils_unittest.cc
@@ -30,36 +30,38 @@
 
 using security_state::GetSecurityStyle;
 
-// Tests that SecurityInfo flags for subresources with certificate
+// Tests that VisibleSecurityState flags for subresources with certificate
 // errors are reflected in the SecurityStyleExplanations produced by
 // GetSecurityStyle.
 TEST(SecurityStateContentUtilsTest, GetSecurityStyleForContentWithCertErrors) {
   content::SecurityStyleExplanations explanations;
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = 0;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = 0;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.ran_content_with_cert_errors = true;
+  visible_security_state.displayed_content_with_cert_errors = true;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_TRUE(explanations.ran_content_with_cert_errors);
   EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_RAN;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.ran_content_with_cert_errors = true;
+  visible_security_state.displayed_content_with_cert_errors = false;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_TRUE(explanations.ran_content_with_cert_errors);
   EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = true;
+  visible_security_state.ran_content_with_cert_errors = false;
+  GetSecurityStyle(security_state::NONE, visible_security_state, &explanations);
   EXPECT_FALSE(explanations.ran_content_with_cert_errors);
   EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_NONE;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = false;
+  visible_security_state.ran_content_with_cert_errors = false;
+  GetSecurityStyle(security_state::NONE, visible_security_state, &explanations);
   EXPECT_FALSE(explanations.ran_content_with_cert_errors);
   EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
 }
@@ -71,31 +73,35 @@
 TEST(SecurityStateContentUtilsTest,
      SubresourcesAndMainResourceWithMajorCertErrors) {
   content::SecurityStyleExplanations explanations;
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = net::CERT_STATUS_DATE_INVALID;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = net::CERT_STATUS_DATE_INVALID;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = true;
+  visible_security_state.ran_content_with_cert_errors = true;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_FALSE(explanations.ran_content_with_cert_errors);
   EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_RAN;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = false;
+  visible_security_state.ran_content_with_cert_errors = true;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_FALSE(explanations.ran_content_with_cert_errors);
   EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = true;
+  visible_security_state.ran_content_with_cert_errors = false;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_FALSE(explanations.ran_content_with_cert_errors);
   EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_NONE;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = false;
+  visible_security_state.ran_content_with_cert_errors = false;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_FALSE(explanations.ran_content_with_cert_errors);
   EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
 }
@@ -107,115 +113,121 @@
 TEST(SecurityStateContentUtilsTest,
      SubresourcesAndMainResourceWithMinorCertErrors) {
   content::SecurityStyleExplanations explanations;
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status =
+      net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = true;
+  visible_security_state.ran_content_with_cert_errors = true;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_TRUE(explanations.ran_content_with_cert_errors);
   EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_RAN;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = false;
+  visible_security_state.ran_content_with_cert_errors = true;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_TRUE(explanations.ran_content_with_cert_errors);
   EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = true;
+  visible_security_state.ran_content_with_cert_errors = false;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_FALSE(explanations.ran_content_with_cert_errors);
   EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_NONE;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_content_with_cert_errors = false;
+  visible_security_state.ran_content_with_cert_errors = false;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_FALSE(explanations.ran_content_with_cert_errors);
   EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
 }
 
-// Tests that SecurityInfo flags for mixed content are reflected in the
+// Tests that VisibleSecurityState flags for mixed content are reflected in the
 // SecurityStyleExplanations produced by GetSecurityStyle.
 TEST(SecurityStateContentUtilsTest, GetSecurityStyleForMixedContent) {
   content::SecurityStyleExplanations explanations;
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = 0;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = 0;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
 
-  security_info.contained_mixed_form = true;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.contained_mixed_form = true;
+  GetSecurityStyle(security_state::NONE, visible_security_state, &explanations);
   EXPECT_TRUE(explanations.contained_mixed_form);
   EXPECT_FALSE(explanations.ran_mixed_content);
   EXPECT_FALSE(explanations.displayed_mixed_content);
 
-  security_info.contained_mixed_form = false;
-  security_info.mixed_content_status = security_state::CONTENT_STATUS_DISPLAYED;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.contained_mixed_form = false;
+  visible_security_state.displayed_mixed_content = true;
+  GetSecurityStyle(security_state::NONE, visible_security_state, &explanations);
   EXPECT_FALSE(explanations.contained_mixed_form);
   EXPECT_TRUE(explanations.displayed_mixed_content);
 }
 
-// Tests that malicious safe browsing data in SecurityInfo triggers an
+// Tests that malicious safe browsing data in VisibleSecurityState triggers an
 // appropriate summary in SecurityStyleExplanations.
 TEST(SecurityStateContentUtilsTest, GetSecurityStyleForSafeBrowsing) {
   content::SecurityStyleExplanations explanations;
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = 0;
-  security_info.scheme_is_cryptographic = true;
-  security_info.malicious_content_status =
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = 0;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
+  visible_security_state.malicious_content_status =
       security_state::MALICIOUS_CONTENT_STATUS_MALWARE;
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.displayed_mixed_content = true;
+  visible_security_state.ran_mixed_content = true;
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SAFEBROWSING_WARNING),
             explanations.summary);
 }
 
-// Tests that a non-cryptographic secure origin in SecurityInfo triggers an
-// appropriate summary in SecurityStyleExplanations.
+// Tests that a non-cryptographic secure origin triggers an appropriate summary
+// in SecurityStyleExplanations.
 TEST(SecurityStateContentUtilsTest,
      GetSecurityStyleForNonCryptographicSecureOrigin) {
   content::SecurityStyleExplanations explanations;
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = 0;
-  security_info.scheme_is_cryptographic = false;
-  security_info.origin_is_secure = true;
-
-  GetSecurityStyle(security_info, &explanations);
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = 0;
+  visible_security_state.url = GURL("chrome://test");
+  GetSecurityStyle(security_state::NONE, visible_security_state, &explanations);
   EXPECT_EQ(l10n_util::GetStringUTF8(IDS_NON_CRYPTO_SECURE_SUMMARY),
             explanations.summary);
 }
 
-// Tests that SecurityInfo flags for non cert errors result in an appropriate
-// summary in SecurityStyleExplanations.
+// Tests that non cert errors result in an appropriate summary in
+// SecurityStyleExplanations.
 TEST(SecurityStateContentUtilsTest, GetSecurityStyleForNonCertErrors) {
   content::SecurityStyleExplanations explanations;
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = 0;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = 0;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
 
-  security_info.is_non_cert_error_page = true;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.is_error_page = true;
+  GetSecurityStyle(security_state::NONE, visible_security_state, &explanations);
   EXPECT_EQ(l10n_util::GetStringUTF8(IDS_ERROR_PAGE_SUMMARY),
             explanations.summary);
 }
 
-// Tests that malicious safe browsing data in SecurityInfo triggers the Safe
-// Browsing warning summary when |is_non_cert_error_page| is set to true.
+// Tests that malicious safe browsing data triggers the Safe Browsing warning
+// summary when |is_error_page| is set to true.
 TEST(SecurityStateContentUtilsTest,
      GetSecurityStyleForSafeBrowsingNonCertError) {
   content::SecurityStyleExplanations explanations;
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = 0;
-  security_info.scheme_is_cryptographic = true;
-  security_info.malicious_content_status =
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = 0;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
+
+  visible_security_state.is_error_page = true;
+  visible_security_state.malicious_content_status =
       security_state::MALICIOUS_CONTENT_STATUS_MALWARE;
 
-  security_info.is_non_cert_error_page = true;
-  GetSecurityStyle(security_info, &explanations);
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SAFEBROWSING_WARNING),
             explanations.summary);
 }
@@ -239,22 +251,24 @@
 // are not translated and so will be the same in any locale.
 TEST(SecurityStateContentUtilsTest, ConnectionExplanation) {
   // Test a modern configuration with a key exchange group.
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status =
+      net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
   net::SSLConnectionStatusSetCipherSuite(
       0xcca8 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */,
-      &security_info.connection_status);
+      &visible_security_state.connection_status);
   net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
-                                     &security_info.connection_status);
-  security_info.key_exchange_group = 29;  // X25519
+                                     &visible_security_state.connection_status);
+  visible_security_state.key_exchange_group = 29;  // X25519
 
   std::string connection_title =
       l10n_util::GetStringUTF8(IDS_SSL_CONNECTION_TITLE);
 
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::NONE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     ASSERT_TRUE(FindSecurityStyleExplanation(
         explanations.secure_explanations, connection_title,
@@ -267,10 +281,11 @@
 
   // Some older cache entries may be missing the key exchange group, despite
   // having a cipher which should supply one.
-  security_info.key_exchange_group = 0;
+  visible_security_state.key_exchange_group = 0;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::NONE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     ASSERT_TRUE(FindSecurityStyleExplanation(
         explanations.secure_explanations, connection_title,
@@ -282,14 +297,16 @@
   }
 
   // TLS 1.3 ciphers use the key exchange group exclusively.
-  net::SSLConnectionStatusSetCipherSuite(0x1301 /* TLS_AES_128_GCM_SHA256 */,
-                                         &security_info.connection_status);
+  net::SSLConnectionStatusSetCipherSuite(
+      0x1301 /* TLS_AES_128_GCM_SHA256 */,
+      &visible_security_state.connection_status);
   net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_3,
-                                     &security_info.connection_status);
-  security_info.key_exchange_group = 29;  // X25519
+                                     &visible_security_state.connection_status);
+  visible_security_state.key_exchange_group = 29;  // X25519
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::NONE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
 
     ASSERT_TRUE(FindSecurityStyleExplanation(
@@ -302,11 +319,6 @@
   }
 }
 
-void UpdateObsoleteSSLStatus(security_state::SecurityInfo* info) {
-  info->obsolete_ssl_status = net::ObsoleteSSLStatus(
-      info->connection_status, info->peer_signature_algorithm);
-}
-
 bool IsProtocolRecommendation(const std::string& recommendation,
                               const std::string& bad_protocol) {
   return recommendation.find(bad_protocol) != std::string::npos &&
@@ -332,19 +344,20 @@
 // Test that obsolete connection explanations are formatted as expected.
 TEST(SecurityStateContentUtilsTest, ObsoleteConnectionExplanation) {
   // Obsolete cipher.
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status =
+      net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
   net::SSLConnectionStatusSetCipherSuite(
       0xc013 /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */,
-      &security_info.connection_status);
+      &visible_security_state.connection_status);
   net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
-                                     &security_info.connection_status);
-  security_info.key_exchange_group = 29;  // X25519
-  UpdateObsoleteSSLStatus(&security_info);
+                                     &visible_security_state.connection_status);
+  visible_security_state.key_exchange_group = 29;  // X25519
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::SECURE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     ASSERT_TRUE(FindSecurityStyleExplanation(
         explanations.info_explanations,
@@ -362,11 +375,11 @@
   }
 
   // Obsolete cipher and signature.
-  security_info.peer_signature_algorithm = 0x0201;  // rsa_pkcs1_sha1
-  UpdateObsoleteSSLStatus(&security_info);
+  visible_security_state.peer_signature_algorithm = 0x0201;  // rsa_pkcs1_sha1
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::SECURE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     ASSERT_TRUE(FindSecurityStyleExplanation(
         explanations.info_explanations,
@@ -382,14 +395,14 @@
   }
 
   // Obsolete protocol version and cipher.
-  security_info.peer_signature_algorithm = 0;  // TLS 1.0 doesn't negotiate a
-                                               // signature algorithm.
   net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1,
-                                     &security_info.connection_status);
-  UpdateObsoleteSSLStatus(&security_info);
+                                     &visible_security_state.connection_status);
+  // TLS 1.0 doesn't negotiate a signature algorithm.
+  visible_security_state.peer_signature_algorithm = 0;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::SECURE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     ASSERT_TRUE(FindSecurityStyleExplanation(
         explanations.info_explanations,
@@ -408,11 +421,11 @@
   // Obsolete protocol version, cipher, and key exchange.
   net::SSLConnectionStatusSetCipherSuite(
       0x000a /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */,
-      &security_info.connection_status);
-  UpdateObsoleteSSLStatus(&security_info);
+      &visible_security_state.connection_status);
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::SECURE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     ASSERT_TRUE(FindSecurityStyleExplanation(
         explanations.info_explanations,
@@ -433,14 +446,15 @@
   // Obsolete key exchange.
   net::SSLConnectionStatusSetCipherSuite(
       0x009c /* TLS_RSA_WITH_AES_128_GCM_SHA256 */,
-      &security_info.connection_status);
+      &visible_security_state.connection_status);
   net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
-                                     &security_info.connection_status);
-  security_info.peer_signature_algorithm = 0x0804;  // rsa_pss_rsae_sha256
-  UpdateObsoleteSSLStatus(&security_info);
+                                     &visible_security_state.connection_status);
+  visible_security_state.peer_signature_algorithm =
+      0x0804;  // rsa_pss_rsae_sha256
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::SECURE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     ASSERT_TRUE(FindSecurityStyleExplanation(
         explanations.info_explanations,
@@ -455,12 +469,12 @@
   // Obsolete signature.
   net::SSLConnectionStatusSetCipherSuite(
       0xc02f /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */,
-      &security_info.connection_status);
-  security_info.peer_signature_algorithm = 0x0201;  // rsa_pkcs1_sha1
-  UpdateObsoleteSSLStatus(&security_info);
+      &visible_security_state.connection_status);
+  visible_security_state.peer_signature_algorithm = 0x0201;  // rsa_pkcs1_sha1
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::SECURE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     ASSERT_TRUE(FindSecurityStyleExplanation(
         explanations.info_explanations,
@@ -476,19 +490,21 @@
 // Test that a secure content explanation is added as expected.
 TEST(SecurityStateContentUtilsTest, SecureContentExplanation) {
   // Test a modern configuration with a key exchange group.
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status =
+      net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
   net::SSLConnectionStatusSetCipherSuite(
       0xcca8 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */,
-      &security_info.connection_status);
+      &visible_security_state.connection_status);
   net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
-                                     &security_info.connection_status);
-  security_info.key_exchange_group = 29;  // X25519
+                                     &visible_security_state.connection_status);
+  visible_security_state.key_exchange_group = 29;  // X25519
 
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::SECURE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     EXPECT_TRUE(FindSecurityStyleExplanation(
         explanations.secure_explanations,
@@ -502,24 +518,26 @@
 // Test that mixed content explanations are added as expected.
 TEST(SecurityStateContentUtilsTest, MixedContentExplanations) {
   // Test a modern configuration with a key exchange group.
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status =
+      net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
   net::SSLConnectionStatusSetCipherSuite(
       0xcca8 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */,
-      &security_info.connection_status);
+      &visible_security_state.connection_status);
   net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
-                                     &security_info.connection_status);
-  security_info.key_exchange_group = 29;  // X25519
+                                     &visible_security_state.connection_status);
+  visible_security_state.key_exchange_group = 29;  // X25519
 
   std::string content_title =
       l10n_util::GetStringUTF8(IDS_RESOURCE_SECURITY_TITLE);
 
-  security_info.mixed_content_status =
-      security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
+  visible_security_state.displayed_mixed_content = true;
+  visible_security_state.ran_mixed_content = true;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     EXPECT_TRUE(FindSecurityStyleExplanation(
         explanations.neutral_explanations, content_title,
@@ -535,10 +553,12 @@
               explanation.description);
   }
 
-  security_info.mixed_content_status = security_state::CONTENT_STATUS_DISPLAYED;
+  visible_security_state.displayed_mixed_content = true;
+  visible_security_state.ran_mixed_content = false;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::NONE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     EXPECT_TRUE(FindSecurityStyleExplanation(
         explanations.neutral_explanations, content_title,
@@ -550,10 +570,12 @@
         &explanation));
   }
 
-  security_info.mixed_content_status = security_state::CONTENT_STATUS_RAN;
+  visible_security_state.displayed_mixed_content = false;
+  visible_security_state.ran_mixed_content = true;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     EXPECT_FALSE(FindSecurityStyleExplanation(
         explanations.neutral_explanations, content_title,
@@ -565,10 +587,11 @@
         &explanation));
   }
 
-  security_info.contained_mixed_form = true;
+  visible_security_state.contained_mixed_form = true;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     EXPECT_TRUE(FindSecurityStyleExplanation(
         explanations.neutral_explanations, content_title,
@@ -581,24 +604,26 @@
 // Test that cert error explanations are formatted as expected.
 TEST(SecurityStateContentUtilsTest, CertErrorContentExplanations) {
   // Test a modern configuration with a key exchange group.
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status =
+      net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
   net::SSLConnectionStatusSetCipherSuite(
       0xcca8 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */,
-      &security_info.connection_status);
+      &visible_security_state.connection_status);
   net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
-                                     &security_info.connection_status);
-  security_info.key_exchange_group = 29;  // X25519
+                                     &visible_security_state.connection_status);
+  visible_security_state.key_exchange_group = 29;  // X25519
 
   std::string content_title =
       l10n_util::GetStringUTF8(IDS_RESOURCE_SECURITY_TITLE);
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
+  visible_security_state.displayed_content_with_cert_errors = true;
+  visible_security_state.ran_content_with_cert_errors = true;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     EXPECT_TRUE(FindSecurityStyleExplanation(
         explanations.neutral_explanations, content_title,
@@ -616,11 +641,12 @@
         explanation.description);
   }
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED;
+  visible_security_state.displayed_content_with_cert_errors = true;
+  visible_security_state.ran_content_with_cert_errors = false;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::NONE, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     EXPECT_TRUE(FindSecurityStyleExplanation(
         explanations.neutral_explanations, content_title,
@@ -632,11 +658,12 @@
         &explanation));
   }
 
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_RAN;
+  visible_security_state.displayed_content_with_cert_errors = false;
+  visible_security_state.ran_content_with_cert_errors = true;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     ASSERT_FALSE(FindSecurityStyleExplanation(
         explanations.neutral_explanations, content_title,
@@ -655,26 +682,28 @@
 // Test that all mixed content explanations can appear together.
 TEST(SecurityStateContentUtilsTest, MixedContentAndCertErrorExplanations) {
   // Test a modern configuration with a key exchange group.
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
-  security_info.scheme_is_cryptographic = true;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status =
+      net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
   net::SSLConnectionStatusSetCipherSuite(
       0xcca8 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */,
-      &security_info.connection_status);
+      &visible_security_state.connection_status);
   net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
-                                     &security_info.connection_status);
-  security_info.key_exchange_group = 29;  // X25519
+                                     &visible_security_state.connection_status);
+  visible_security_state.key_exchange_group = 29;  // X25519
 
   std::string content_title =
       l10n_util::GetStringUTF8(IDS_RESOURCE_SECURITY_TITLE);
 
-  security_info.mixed_content_status =
-      security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_DISPLAYED_AND_RAN;
+  visible_security_state.displayed_mixed_content = true;
+  visible_security_state.ran_mixed_content = true;
+  visible_security_state.displayed_content_with_cert_errors = true;
+  visible_security_state.ran_content_with_cert_errors = true;
   {
     content::SecurityStyleExplanations explanations;
-    GetSecurityStyle(security_info, &explanations);
+    GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                     &explanations);
     content::SecurityStyleExplanation explanation;
     EXPECT_TRUE(FindSecurityStyleExplanation(
         explanations.neutral_explanations, content_title,
@@ -696,28 +725,27 @@
 }
 
 // Tests that a security level of HTTP_SHOW_WARNING produces
-// blink::WebSecurityStyleNeutral and an explanation if appropriate.
+// blink::WebSecurityStyleNeutral.
 TEST(SecurityStateContentUtilsTest, HTTPWarning) {
-  security_state::SecurityInfo security_info;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.url = GURL("http://scheme-is-not-cryptographic.test");
   content::SecurityStyleExplanations explanations;
-  security_info.security_level = security_state::HTTP_SHOW_WARNING;
-  blink::WebSecurityStyle security_style =
-      GetSecurityStyle(security_info, &explanations);
+  blink::WebSecurityStyle security_style = GetSecurityStyle(
+      security_state::HTTP_SHOW_WARNING, visible_security_state, &explanations);
   EXPECT_EQ(blink::kWebSecurityStyleNeutral, security_style);
-  // Verify no explanation was shown, because Form Not Secure was not triggered.
+  // Verify no explanation was shown.
   EXPECT_EQ(0u, explanations.neutral_explanations.size());
 }
 
 // Tests that a security level of DANGEROUS on an HTTP page with insecure form
 // edits produces blink::WebSecurityStyleInsecure and an explanation.
 TEST(SecurityStateContentUtilsTest, HTTPDangerous) {
-  security_state::SecurityInfo security_info;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.url = GURL("http://scheme-is-not-cryptographic.test");
   content::SecurityStyleExplanations explanations;
-  security_info.security_level = security_state::DANGEROUS;
-  security_info.scheme_is_cryptographic = false;
-  security_info.insecure_input_events.insecure_field_edited = true;
-  blink::WebSecurityStyle security_style =
-      GetSecurityStyle(security_info, &explanations);
+  visible_security_state.insecure_input_events.insecure_field_edited = true;
+  blink::WebSecurityStyle security_style = GetSecurityStyle(
+      security_state::DANGEROUS, visible_security_state, &explanations);
   // Verify that the security style was downgraded and an explanation shown
   // because a form was edited.
   EXPECT_EQ(blink::kWebSecurityStyleInsecure, security_style);
@@ -727,39 +755,39 @@
 // Tests that an explanation is provided if a certificate is missing a
 // subjectAltName extension containing a domain name or IP address.
 TEST(SecurityStateContentUtilsTest, SubjectAltNameWarning) {
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = 0;
-  security_info.scheme_is_cryptographic = true;
-
-  security_info.certificate = net::ImportCertFromFile(
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = 0;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
+  visible_security_state.certificate = net::ImportCertFromFile(
       net::GetTestCertsDirectory(), "salesforce_com_test.pem");
-  ASSERT_TRUE(security_info.certificate);
+  ASSERT_TRUE(visible_security_state.certificate);
 
   content::SecurityStyleExplanations explanations;
-  security_info.cert_missing_subject_alt_name = true;
-  GetSecurityStyle(security_info, &explanations);
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   // Verify that an explanation was shown for a missing subjectAltName.
   EXPECT_EQ(1u, explanations.insecure_explanations.size());
 
   explanations.insecure_explanations.clear();
-  security_info.cert_missing_subject_alt_name = false;
-  GetSecurityStyle(security_info, &explanations);
+  visible_security_state.certificate =
+      net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
+  GetSecurityStyle(security_state::SECURE, visible_security_state,
+                   &explanations);
   // Verify that no explanation is shown if the subjectAltName is present.
   EXPECT_EQ(0u, explanations.insecure_explanations.size());
 }
 
-// Tests that malicious safe browsing data in SecurityInfo causes an insecure
-// explanation to be set.
+// Tests that malicious safe browsing data in VisibleSecurityState causes an
+// insecure explanation to be set.
 TEST(SecurityStateContentUtilsTest, SafeBrowsingExplanation) {
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = 0;
-  security_info.scheme_is_cryptographic = true;
-  security_info.malicious_content_status =
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = 0;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
+  visible_security_state.malicious_content_status =
       security_state::MALICIOUS_CONTENT_STATUS_MALWARE;
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_NONE;
   content::SecurityStyleExplanations explanations;
-  GetSecurityStyle(security_info, &explanations);
+  GetSecurityStyle(security_state::DANGEROUS, visible_security_state,
+                   &explanations);
   EXPECT_EQ(1u, explanations.insecure_explanations.size());
 }
 
@@ -786,36 +814,37 @@
 // Tests that an info explanation is provided only if the certificate is
 // expiring soon.
 TEST(SecurityStateContentUtilsTest, ExpiringCertificateWarning) {
-  security_state::SecurityInfo security_info;
-  security_info.cert_status = 0;
-  security_info.scheme_is_cryptographic = true;
-  security_info.content_with_cert_errors_status =
-      security_state::CONTENT_STATUS_NONE;
+  security_state::VisibleSecurityState visible_security_state;
+  visible_security_state.cert_status = 0;
+  visible_security_state.url = GURL("https://scheme-is-cryptographic.test");
 
   // Check that an info explanation is provided if the certificate is expiring
   // in less than 48 hours.
   content::SecurityStyleExplanations explanations;
-  security_info.certificate = scoped_refptr<net::X509Certificate>(
+  visible_security_state.certificate = scoped_refptr<net::X509Certificate>(
       CreateFakeCert(base::TimeDelta::FromHours(30)));
-  ASSERT_TRUE(security_info.certificate);
-  GetSecurityStyle(security_info, &explanations);
+  ASSERT_TRUE(visible_security_state.certificate);
+  GetSecurityStyle(security_state::SECURE, visible_security_state,
+                   &explanations);
   EXPECT_EQ(1u, explanations.info_explanations.size());
 
   // Check that no explanation is set if the certificate is expiring in more
   // than 48 hours.
   explanations.info_explanations.clear();
-  security_info.certificate = scoped_refptr<net::X509Certificate>(
+  visible_security_state.certificate = scoped_refptr<net::X509Certificate>(
       CreateFakeCert(base::TimeDelta::FromHours(72)));
-  ASSERT_TRUE(security_info.certificate);
-  GetSecurityStyle(security_info, &explanations);
+  ASSERT_TRUE(visible_security_state.certificate);
+  GetSecurityStyle(security_state::SECURE, visible_security_state,
+                   &explanations);
   EXPECT_EQ(0u, explanations.info_explanations.size());
 
   // Check that no explanation is set if the certificate has already expired.
   explanations.info_explanations.clear();
-  security_info.certificate = scoped_refptr<net::X509Certificate>(
+  visible_security_state.certificate = scoped_refptr<net::X509Certificate>(
       CreateFakeCert(base::TimeDelta::FromHours(-10)));
-  ASSERT_TRUE(security_info.certificate);
-  GetSecurityStyle(security_info, &explanations);
+  ASSERT_TRUE(visible_security_state.certificate);
+  GetSecurityStyle(security_state::SECURE, visible_security_state,
+                   &explanations);
   EXPECT_EQ(0u, explanations.info_explanations.size());
 }
 
diff --git a/components/security_state/core/security_state.cc b/components/security_state/core/security_state.cc
index ce5fd86..4890135 100644
--- a/components/security_state/core/security_state.cc
+++ b/components/security_state/core/security_state.cc
@@ -31,225 +31,24 @@
   return !is_origin_secure_callback.Run(inner_url);
 }
 
-// For nonsecure pages, sets |security_level| in |*security_info| based on the
+// For nonsecure pages, returns a SecurityLevel based on the
 // provided information and the kMarkHttpAsFeature field trial.
-void SetSecurityLevelAndRelatedFieldsForNonSecureFieldTrial(
+SecurityLevel GetSecurityLevelForNonSecureFieldTrial(
     bool is_error_page,
-    const InsecureInputEventData& input_events,
-    SecurityInfo* security_info) {
+    const InsecureInputEventData& input_events) {
   if (base::FeatureList::IsEnabled(features::kMarkHttpAsFeature)) {
     std::string parameter = base::GetFieldTrialParamValueByFeature(
         features::kMarkHttpAsFeature,
         features::kMarkHttpAsFeatureParameterName);
 
     if (parameter == features::kMarkHttpAsParameterDangerous) {
-      security_info->security_level = DANGEROUS;
-      return;
+      return DANGEROUS;
     }
   }
 
   // Default to dangerous on editing form fields and otherwise
   // warning.
-  security_info->security_level =
-      input_events.insecure_field_edited ? DANGEROUS : HTTP_SHOW_WARNING;
-}
-
-ContentStatus GetContentStatus(bool displayed, bool ran) {
-  if (ran && displayed)
-    return CONTENT_STATUS_DISPLAYED_AND_RAN;
-  if (ran)
-    return CONTENT_STATUS_RAN;
-  if (displayed)
-    return CONTENT_STATUS_DISPLAYED;
-  return CONTENT_STATUS_NONE;
-}
-
-// Sets |security_level| in |*security_info| based on the provided information.
-void SetSecurityLevelAndRelatedFields(
-    const VisibleSecurityState& visible_security_state,
-    bool used_policy_installed_certificate,
-    const IsOriginSecureCallback& is_origin_secure_callback,
-    bool sha1_in_chain,
-    ContentStatus mixed_content_status,
-    ContentStatus content_with_cert_errors_status,
-    SecurityInfo* security_info) {
-  DCHECK(visible_security_state.connection_info_initialized ||
-         visible_security_state.malicious_content_status !=
-             MALICIOUS_CONTENT_STATUS_NONE);
-
-  // Override the connection security information if the website failed the
-  // browser's malware checks.
-  if (visible_security_state.malicious_content_status !=
-      MALICIOUS_CONTENT_STATUS_NONE) {
-    security_info->security_level = DANGEROUS;
-    return;
-  }
-
-  const GURL url = visible_security_state.url;
-
-  const bool is_cryptographic_with_certificate =
-      (url.SchemeIsCryptographic() && visible_security_state.certificate);
-
-  const bool is_major_cert_error =
-      net::IsCertStatusError(visible_security_state.cert_status) &&
-      !net::IsCertStatusMinorError(visible_security_state.cert_status);
-
-  // Set the security level to DANGEROUS for major certificate errors.
-  if (is_cryptographic_with_certificate && is_major_cert_error) {
-    security_info->security_level = DANGEROUS;
-    return;
-  }
-
-  // Set the field indicating when an error page is not a cert error.
-  if (visible_security_state.is_error_page && !is_major_cert_error) {
-    security_info->is_non_cert_error_page = true;
-  }
-
-  // data: URLs don't define a secure context, and are a vector for spoofing.
-  // Likewise, ftp: URLs are always non-secure, and are uncommon enough that
-  // we can treat them as such without significant user impact.
-  //
-  // Display a "Not secure" badge for all these URLs.
-  if (url.SchemeIs(url::kDataScheme) || url.SchemeIs(url::kFtpScheme)) {
-    security_info->security_level = SecurityLevel::HTTP_SHOW_WARNING;
-    return;
-  }
-
-  // Choose the appropriate security level for requests to HTTP and remaining
-  // pseudo URLs (blob:, filesystem:). filesystem: is a standard scheme so does
-  // not need to be explicitly listed here.
-  // TODO(meacer): Remove special case for blob (crbug.com/684751).
-  if (!is_cryptographic_with_certificate) {
-    if (!visible_security_state.is_error_page &&
-        !is_origin_secure_callback.Run(url) &&
-        (url.IsStandard() ||
-         IsNonsecureBlobUrl(url, is_origin_secure_callback))) {
-      SetSecurityLevelAndRelatedFieldsForNonSecureFieldTrial(
-          visible_security_state.is_error_page,
-          visible_security_state.insecure_input_events, security_info);
-      return;
-    }
-    security_info->security_level = NONE;
-    return;
-  }
-
-  // Downgrade the security level for active insecure subresources.
-  if (mixed_content_status == CONTENT_STATUS_RAN ||
-      mixed_content_status == CONTENT_STATUS_DISPLAYED_AND_RAN ||
-      content_with_cert_errors_status == CONTENT_STATUS_RAN ||
-      content_with_cert_errors_status == CONTENT_STATUS_DISPLAYED_AND_RAN) {
-    security_info->security_level = kRanInsecureContentLevel;
-    return;
-  }
-
-  // In most cases, SHA1 use is treated as a certificate error, in which case
-  // DANGEROUS will have been returned above. If SHA1 was permitted by policy,
-  // downgrade the security level to Neutral.
-  if (sha1_in_chain) {
-    security_info->security_level = NONE;
-    return;
-  }
-
-  // Active mixed content is handled above.
-  DCHECK_NE(CONTENT_STATUS_RAN, mixed_content_status);
-  DCHECK_NE(CONTENT_STATUS_DISPLAYED_AND_RAN, mixed_content_status);
-
-  if (visible_security_state.contained_mixed_form ||
-      mixed_content_status == CONTENT_STATUS_DISPLAYED ||
-      content_with_cert_errors_status == CONTENT_STATUS_DISPLAYED) {
-    security_info->security_level = kDisplayedInsecureContentLevel;
-    return;
-  }
-
-  if (net::IsCertStatusError(visible_security_state.cert_status)) {
-    // Major cert errors are handled above.
-    DCHECK(net::IsCertStatusMinorError(visible_security_state.cert_status));
-    security_info->security_level = NONE;
-    return;
-  }
-
-  if (visible_security_state.is_view_source) {
-    security_info->security_level = NONE;
-    return;
-  }
-
-  // Any prior observation of a policy-installed cert is a strong indicator
-  // of a MITM being present (the enterprise), so a "secure-but-inspected"
-  // security level is returned.
-  if (used_policy_installed_certificate) {
-    security_info->security_level = SECURE_WITH_POLICY_INSTALLED_CERT;
-    return;
-  }
-
-  if ((visible_security_state.cert_status & net::CERT_STATUS_IS_EV) &&
-      visible_security_state.certificate) {
-    security_info->security_level = EV_SECURE;
-    return;
-  }
-  security_info->security_level = SECURE;
-}
-
-void SecurityInfoForRequest(
-    const VisibleSecurityState& visible_security_state,
-    bool used_policy_installed_certificate,
-    const IsOriginSecureCallback& is_origin_secure_callback,
-    SecurityInfo* security_info) {
-  if (!visible_security_state.connection_info_initialized) {
-    *security_info = SecurityInfo();
-    security_info->connection_info_initialized = false;
-    security_info->malicious_content_status =
-        visible_security_state.malicious_content_status;
-    if (security_info->malicious_content_status !=
-        MALICIOUS_CONTENT_STATUS_NONE) {
-      SetSecurityLevelAndRelatedFields(
-          visible_security_state, used_policy_installed_certificate,
-          is_origin_secure_callback, false, CONTENT_STATUS_UNKNOWN,
-          CONTENT_STATUS_UNKNOWN, security_info);
-    }
-    return;
-  }
-  security_info->connection_info_initialized = true;
-  security_info->certificate = visible_security_state.certificate;
-
-  security_info->sha1_in_chain = IsSHA1InChain(visible_security_state);
-  security_info->mixed_content_status =
-      GetContentStatus(visible_security_state.displayed_mixed_content,
-                       visible_security_state.ran_mixed_content);
-  security_info->content_with_cert_errors_status = GetContentStatus(
-      visible_security_state.displayed_content_with_cert_errors,
-      visible_security_state.ran_content_with_cert_errors);
-  security_info->connection_status = visible_security_state.connection_status;
-  security_info->key_exchange_group = visible_security_state.key_exchange_group;
-  security_info->peer_signature_algorithm =
-      visible_security_state.peer_signature_algorithm;
-  security_info->cert_status = visible_security_state.cert_status;
-  security_info->scheme_is_cryptographic =
-      visible_security_state.url.SchemeIsCryptographic();
-  security_info->origin_is_secure =
-      is_origin_secure_callback.Run(visible_security_state.url);
-  security_info->obsolete_ssl_status =
-      net::ObsoleteSSLStatus(security_info->connection_status,
-                             security_info->peer_signature_algorithm);
-  security_info->pkp_bypassed = visible_security_state.pkp_bypassed;
-
-  security_info->malicious_content_status =
-      visible_security_state.malicious_content_status;
-
-  security_info->cert_missing_subject_alt_name =
-      visible_security_state.certificate &&
-      !visible_security_state.certificate->GetSubjectAltName(nullptr, nullptr);
-
-  security_info->contained_mixed_form =
-      visible_security_state.contained_mixed_form;
-
-  SetSecurityLevelAndRelatedFields(
-      visible_security_state, used_policy_installed_certificate,
-      is_origin_secure_callback, security_info->sha1_in_chain,
-      security_info->mixed_content_status,
-      security_info->content_with_cert_errors_status, security_info);
-
-  security_info->insecure_input_events =
-      visible_security_state.insecure_input_events;
+  return input_events.insecure_field_edited ? DANGEROUS : HTTP_SHOW_WARNING;
 }
 
 std::string GetHistogramSuffixForSecurityLevel(
@@ -274,35 +73,105 @@
 
 }  // namespace
 
-SecurityInfo::SecurityInfo()
-    : connection_info_initialized(false),
-      security_level(NONE),
-      malicious_content_status(MALICIOUS_CONTENT_STATUS_NONE),
-      sha1_in_chain(false),
-      mixed_content_status(CONTENT_STATUS_NONE),
-      content_with_cert_errors_status(CONTENT_STATUS_NONE),
-      scheme_is_cryptographic(false),
-      origin_is_secure(false),
-      cert_status(0),
-      connection_status(0),
-      key_exchange_group(0),
-      peer_signature_algorithm(0),
-      obsolete_ssl_status(net::OBSOLETE_SSL_NONE),
-      pkp_bypassed(false),
-      contained_mixed_form(false),
-      cert_missing_subject_alt_name(false),
-      is_non_cert_error_page(false) {}
-
-SecurityInfo::~SecurityInfo() {}
-
-void GetSecurityInfo(
-    std::unique_ptr<VisibleSecurityState> visible_security_state,
+SecurityLevel GetSecurityLevel(
+    const VisibleSecurityState& visible_security_state,
     bool used_policy_installed_certificate,
-    IsOriginSecureCallback is_origin_secure_callback,
-    SecurityInfo* result) {
-  SecurityInfoForRequest(*visible_security_state,
-                         used_policy_installed_certificate,
-                         is_origin_secure_callback, result);
+    IsOriginSecureCallback is_origin_secure_callback) {
+  // Override the connection security information if the website failed the
+  // browser's malware checks.
+  if (visible_security_state.malicious_content_status !=
+      MALICIOUS_CONTENT_STATUS_NONE) {
+    return DANGEROUS;
+  }
+
+  if (!visible_security_state.connection_info_initialized) {
+    return NONE;
+  }
+
+  const GURL url = visible_security_state.url;
+
+  const bool is_cryptographic_with_certificate =
+      (url.SchemeIsCryptographic() && visible_security_state.certificate);
+
+  const bool is_major_cert_error =
+      net::IsCertStatusError(visible_security_state.cert_status) &&
+      !net::IsCertStatusMinorError(visible_security_state.cert_status);
+
+  // Set the security level to DANGEROUS for major certificate errors.
+  if (is_cryptographic_with_certificate && is_major_cert_error) {
+    return DANGEROUS;
+  }
+
+  // data: URLs don't define a secure context, and are a vector for spoofing.
+  // Likewise, ftp: URLs are always non-secure, and are uncommon enough that
+  // we can treat them as such without significant user impact.
+  //
+  // Display a "Not secure" badge for all these URLs.
+  if (url.SchemeIs(url::kDataScheme) || url.SchemeIs(url::kFtpScheme)) {
+    return HTTP_SHOW_WARNING;
+  }
+
+  // Choose the appropriate security level for requests to HTTP and remaining
+  // pseudo URLs (blob:, filesystem:). filesystem: is a standard scheme so does
+  // not need to be explicitly listed here.
+  // TODO(meacer): Remove special case for blob (crbug.com/684751).
+  if (!is_cryptographic_with_certificate) {
+    if (!visible_security_state.is_error_page &&
+        !is_origin_secure_callback.Run(url) &&
+        (url.IsStandard() ||
+         IsNonsecureBlobUrl(url, is_origin_secure_callback))) {
+      return GetSecurityLevelForNonSecureFieldTrial(
+          visible_security_state.is_error_page,
+          visible_security_state.insecure_input_events);
+    }
+    return NONE;
+  }
+
+  // Downgrade the security level for active insecure subresources.
+  if (visible_security_state.ran_mixed_content ||
+      visible_security_state.ran_content_with_cert_errors) {
+    return kRanInsecureContentLevel;
+  }
+
+  // In most cases, SHA1 use is treated as a certificate error, in which case
+  // DANGEROUS will have been returned above. If SHA1 was permitted by policy,
+  // downgrade the security level to Neutral.
+  if (IsSHA1InChain(visible_security_state)) {
+    return NONE;
+  }
+
+  // Active mixed content is handled above.
+  DCHECK(!visible_security_state.ran_mixed_content);
+  DCHECK(!visible_security_state.ran_content_with_cert_errors);
+
+  if (visible_security_state.contained_mixed_form ||
+      visible_security_state.displayed_mixed_content ||
+      visible_security_state.displayed_content_with_cert_errors) {
+    return kDisplayedInsecureContentLevel;
+  }
+
+  if (net::IsCertStatusError(visible_security_state.cert_status)) {
+    // Major cert errors are handled above.
+    DCHECK(net::IsCertStatusMinorError(visible_security_state.cert_status));
+    return NONE;
+  }
+
+  if (visible_security_state.is_view_source) {
+    return NONE;
+  }
+
+  // Any prior observation of a policy-installed cert is a strong indicator
+  // of a MITM being present (the enterprise), so a "secure-but-inspected"
+  // security level is returned.
+  if (used_policy_installed_certificate) {
+    return SECURE_WITH_POLICY_INSTALLED_CERT;
+  }
+
+  if ((visible_security_state.cert_status & net::CERT_STATUS_IS_EV) &&
+      visible_security_state.certificate) {
+    return EV_SECURE;
+  }
+  return SECURE;
 }
 
 VisibleSecurityState::VisibleSecurityState()
diff --git a/components/security_state/core/security_state.h b/components/security_state/core/security_state.h
index 7e88c09..a4cf2a4 100644
--- a/components/security_state/core/security_state.h
+++ b/components/security_state/core/security_state.h
@@ -21,8 +21,8 @@
 // Provides helper methods and data types that are used to determine the
 // high-level security information about a page or request.
 //
-// SecurityInfo is the main data structure, describing a page's or request's
-// security state. It is computed by the platform-independent GetSecurityInfo()
+// SecurityLevel is the main result, describing a page's or request's
+// security state. It is computed by the platform-independent GetSecurityLevel()
 // helper method, which receives platform-specific inputs from its callers in
 // the form of a VisibleSecurityState struct.
 namespace security_state {
@@ -95,66 +95,8 @@
   MALICIOUS_CONTENT_STATUS_BILLING,
 };
 
-// Describes the security status of a page or request. This is the
-// main data structure provided by this class. SecurityInfo contains a
-// SecurityLevel (which
-// is a single value describing the overall security state) along with
-// information that a consumer might want to display in UI to explain or
-// elaborate on the SecurityLevel.
-struct SecurityInfo {
-  SecurityInfo();
-  ~SecurityInfo();
-  // Whether the connection security fields are initialized.
-  bool connection_info_initialized;
-  // Describes the overall security state of the page.
-  SecurityLevel security_level;
-  // Describes the nature of the page's malicious content, if any.
-  MaliciousContentStatus malicious_content_status;
-  // True if a SHA1 signature was observed anywhere in the certificate chain.
-  bool sha1_in_chain;
-  // |mixed_content_status| describes the presence of content that was
-  // loaded over a nonsecure (HTTP) connection.
-  ContentStatus mixed_content_status;
-  // |content_with_cert_errors_status| describes the presence of
-  // content that was loaded over an HTTPS connection with
-  // certificate errors.
-  ContentStatus content_with_cert_errors_status;
-  bool scheme_is_cryptographic;
-  // Some origins are considered secure even if they aren't cryptographic. This
-  // field marks such origins so that they can be treated differently in the UI.
-  bool origin_is_secure;
-  net::CertStatus cert_status;
-  scoped_refptr<net::X509Certificate> certificate;
-  // Information about the SSL connection, such as protocol and
-  // ciphersuite. See ssl_connection_flags.h in net.
-  int connection_status;
-  // The ID of the (EC)DH group used by the key exchange. The value is zero if
-  // unknown (older cache entries may not store the value) or not applicable.
-  uint16_t key_exchange_group;
-  // The signature algorithm used by the peer in the TLS handshake, or zero if
-  // unknown (older cache entries may not store the value) or not applicable.
-  uint16_t peer_signature_algorithm;
-  // A mask that indicates which of the protocol version,
-  // key exchange, or cipher for the connection is considered
-  // obsolete. See net::ObsoleteSSLMask for specific mask values.
-  int obsolete_ssl_status;
-  // True if pinning was bypassed due to a local trust anchor.
-  bool pkp_bypassed;
-  // True if the secure page contained a form with a nonsecure target.
-  bool contained_mixed_form;
-  // True if the server's certificate does not contain a
-  // subjectAltName extension with a domain name or IP address.
-  bool cert_missing_subject_alt_name;
-  // Contains information about input events that may impact the security
-  // level of the page.
-  InsecureInputEventData insecure_input_events;
-  // True if the page is an error page, for an error other than a certificate
-  // error.
-  bool is_non_cert_error_page;
-};
-
-// Contains the security state relevant to computing the SecurityInfo
-// for a page. This is the input to GetSecurityInfo().
+// Contains the security state relevant to computing the SecurityLevel
+// for a page. This is the input to GetSecurityLevel().
 struct VisibleSecurityState {
   VisibleSecurityState();
   ~VisibleSecurityState();
@@ -207,17 +149,16 @@
 // Returns true if the given |url|'s origin should be considered secure.
 using IsOriginSecureCallback = base::Callback<bool(const GURL& url)>;
 
-// Populates |result| to describe the current page.
+// Returns a SecurityLevel to describe the current page.
 // |visible_security_state| contains the relevant security state.
 // |used_policy_installed_certificate| indicates whether the page or request
 // is known to be loaded with a certificate installed by the system admin.
 // |is_origin_secure_callback| determines whether a URL's origin should be
 // considered secure.
-void GetSecurityInfo(
-    std::unique_ptr<VisibleSecurityState> visible_security_state,
+SecurityLevel GetSecurityLevel(
+    const VisibleSecurityState& visible_security_state,
     bool used_policy_installed_certificate,
-    IsOriginSecureCallback is_origin_secure_callback,
-    SecurityInfo* result);
+    IsOriginSecureCallback is_origin_secure_callback);
 
 // Returns true for a valid |url| with a cryptographic scheme, e.g., HTTPS, WSS.
 bool IsSchemeCryptographic(const GURL& url);
diff --git a/components/security_state/core/security_state_unittest.cc b/components/security_state/core/security_state_unittest.cc
index 317b447c..fffe7dc1 100644
--- a/components/security_state/core/security_state_unittest.cc
+++ b/components/security_state/core/security_state_unittest.cc
@@ -120,10 +120,10 @@
     return state;
   }
 
-  void GetSecurityInfo(SecurityInfo* security_info) const {
-    security_state::GetSecurityInfo(GetVisibleSecurityState(),
-                                    has_policy_certificate_,
-                                    base::Bind(&IsOriginSecure), security_info);
+  security_state::SecurityLevel GetSecurityLevel() const {
+    return security_state::GetSecurityLevel(
+        *GetVisibleSecurityState(), has_policy_certificate_,
+        base::BindRepeating(&IsOriginSecure));
   }
 
  private:
@@ -149,34 +149,26 @@
   TestSecurityStateHelper helper;
   helper.AddCertStatus(net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
   helper.AddCertStatus(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT);
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_TRUE(security_info.sha1_in_chain);
-  EXPECT_EQ(DANGEROUS, security_info.security_level);
+  EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 
   // Ensure that policy-installed certificates do not interfere.
   helper.set_has_policy_certificate(true);
-  SecurityInfo policy_cert_security_info;
-  helper.GetSecurityInfo(&policy_cert_security_info);
-  EXPECT_TRUE(policy_cert_security_info.sha1_in_chain);
-  EXPECT_EQ(DANGEROUS, policy_cert_security_info.security_level);
+  EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 // Tests that SHA1-signed certificates, when allowed by policy, downgrade the
 // security state of the page to NONE.
 TEST(SecurityStateTest, SHA1Warning) {
   TestSecurityStateHelper helper;
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_TRUE(security_info.sha1_in_chain);
-  EXPECT_EQ(NONE, security_info.security_level);
+  EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
+  EXPECT_EQ(NONE, helper.GetSecurityLevel());
 
   // Ensure that policy-installed certificates do not interfere.
   helper.set_has_policy_certificate(true);
-  SecurityInfo policy_cert_security_info;
-  helper.GetSecurityInfo(&policy_cert_security_info);
-  EXPECT_TRUE(policy_cert_security_info.sha1_in_chain);
-  EXPECT_EQ(NONE, policy_cert_security_info.security_level);
+  EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
+  EXPECT_EQ(NONE, helper.GetSecurityLevel());
 }
 
 // Tests that SHA1-signed certificates, when allowed by policy, don't interfere
@@ -184,19 +176,13 @@
 TEST(SecurityStateTest, SHA1WarningMixedContent) {
   TestSecurityStateHelper helper;
   helper.set_displayed_mixed_content(true);
-  SecurityInfo security_info1;
-  helper.GetSecurityInfo(&security_info1);
-  EXPECT_TRUE(security_info1.sha1_in_chain);
-  EXPECT_EQ(CONTENT_STATUS_DISPLAYED, security_info1.mixed_content_status);
-  EXPECT_EQ(NONE, security_info1.security_level);
+  EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
+  EXPECT_EQ(NONE, helper.GetSecurityLevel());
 
   helper.set_displayed_mixed_content(false);
   helper.set_ran_mixed_content(true);
-  SecurityInfo security_info2;
-  helper.GetSecurityInfo(&security_info2);
-  EXPECT_TRUE(security_info2.sha1_in_chain);
-  EXPECT_EQ(CONTENT_STATUS_RAN, security_info2.mixed_content_status);
-  EXPECT_EQ(DANGEROUS, security_info2.security_level);
+  EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 // Tests that SHA1-signed certificates, when allowed by policy,
@@ -204,55 +190,11 @@
 TEST(SecurityStateTest, SHA1WarningBrokenHTTPS) {
   TestSecurityStateHelper helper;
   helper.AddCertStatus(net::CERT_STATUS_DATE_INVALID);
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_TRUE(security_info.sha1_in_chain);
-  EXPECT_EQ(DANGEROUS, security_info.security_level);
+  EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
-// Tests that |security_info.is_secure_protocol_and_ciphersuite| is
-// computed correctly.
-TEST(SecurityStateTest, SecureProtocolAndCiphersuite) {
-  TestSecurityStateHelper helper;
-  // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from
-  // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-4
-  const uint16_t ciphersuite = 0xc02f;
-  helper.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2
-                               << net::SSL_CONNECTION_VERSION_SHIFT);
-  helper.SetCipherSuite(ciphersuite);
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(net::OBSOLETE_SSL_NONE, security_info.obsolete_ssl_status);
-}
-
-TEST(SecurityStateTest, NonsecureProtocol) {
-  TestSecurityStateHelper helper;
-  // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from
-  // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-4
-  const uint16_t ciphersuite = 0xc02f;
-  helper.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_1
-                               << net::SSL_CONNECTION_VERSION_SHIFT);
-  helper.SetCipherSuite(ciphersuite);
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(net::OBSOLETE_SSL_MASK_PROTOCOL, security_info.obsolete_ssl_status);
-}
-
-TEST(SecurityStateTest, NonsecureCiphersuite) {
-  TestSecurityStateHelper helper;
-  // TLS_RSA_WITH_AES_128_CCM_8 from
-  // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-4
-  const uint16_t ciphersuite = 0xc0a0;
-  helper.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2
-                               << net::SSL_CONNECTION_VERSION_SHIFT);
-  helper.SetCipherSuite(ciphersuite);
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(net::OBSOLETE_SSL_MASK_KEY_EXCHANGE | net::OBSOLETE_SSL_MASK_CIPHER,
-            security_info.obsolete_ssl_status);
-}
-
-// Tests that the malware/phishing status is set, and it overrides valid HTTPS.
+// Tests that the malware/phishing status overrides valid HTTPS.
 TEST(SecurityStateTest, MalwareOverride) {
   TestSecurityStateHelper helper;
   // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from
@@ -262,17 +204,9 @@
                                << net::SSL_CONNECTION_VERSION_SHIFT);
   helper.SetCipherSuite(ciphersuite);
 
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(MALICIOUS_CONTENT_STATUS_NONE,
-            security_info.malicious_content_status);
-
   helper.set_malicious_content_status(MALICIOUS_CONTENT_STATUS_MALWARE);
-  helper.GetSecurityInfo(&security_info);
 
-  EXPECT_EQ(MALICIOUS_CONTENT_STATUS_MALWARE,
-            security_info.malicious_content_status);
-  EXPECT_EQ(DANGEROUS, security_info.security_level);
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 // Tests that the malware/phishing status is set, even if other connection info
@@ -281,29 +215,21 @@
   TestSecurityStateHelper helper;
   helper.set_malicious_content_status(
       MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING);
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING,
-            security_info.malicious_content_status);
-  EXPECT_EQ(DANGEROUS, security_info.security_level);
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 // Tests that pseudo URLs always cause an HTTP_SHOW_WARNING to be shown.
 TEST(SecurityStateTest, AlwaysWarnOnDataUrls) {
   TestSecurityStateHelper helper;
   helper.SetUrl(GURL("data:text/html,<html>test</html>"));
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level);
+  EXPECT_EQ(HTTP_SHOW_WARNING, helper.GetSecurityLevel());
 }
 
 // Tests that FTP URLs always cause an HTTP_SHOW_WARNING to be shown.
 TEST(SecurityStateTest, AlwaysWarnOnFtpUrls) {
   TestSecurityStateHelper helper;
   helper.SetUrl(GURL("ftp://example.test/"));
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level);
+  EXPECT_EQ(HTTP_SHOW_WARNING, helper.GetSecurityLevel());
 }
 
 // Tests that the security level is downgraded to HTTP_SHOW_WARNING on pseudo
@@ -312,83 +238,40 @@
   for (const char* const url : kPseudoUrls) {
     TestSecurityStateHelper helper;
     helper.SetUrl(GURL(url));
-    SecurityInfo security_info;
-    helper.GetSecurityInfo(&security_info);
-    EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level);
+    EXPECT_EQ(HTTP_SHOW_WARNING, helper.GetSecurityLevel());
   }
 }
 
-// Tests that if |is_view_source| NONE is returned for a secure site.
+// Tests that if |is_view_source| is set, NONE is returned for a secure site.
 TEST(SecurityStateTest, ViewSourceRemovesSecure) {
   TestSecurityStateHelper helper;
-  SecurityInfo security_info;
   helper.set_cert_status(0);
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(SECURE, security_info.security_level);
+  EXPECT_EQ(SECURE, helper.GetSecurityLevel());
   helper.set_is_view_source(true);
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(NONE, security_info.security_level);
+  EXPECT_EQ(NONE, helper.GetSecurityLevel());
 }
 
-// Tests that if |is_view_source|, DANGEROUS is still returned for a site
+// Tests that if |is_view_source| is set, DANGEROUS is still returned for a site
 // flagged by SafeBrowsing.
 TEST(SecurityStateTest, ViewSourceKeepsWarning) {
   TestSecurityStateHelper helper;
   helper.set_malicious_content_status(
       MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING);
   helper.set_is_view_source(true);
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING,
-            security_info.malicious_content_status);
-  EXPECT_EQ(DANGEROUS, security_info.security_level);
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
-TEST(SecurityStateTest, DetectSubjectAltName) {
-  TestSecurityStateHelper helper;
-
-  // Ensure subjectAltName is detected as present when the cert includes it.
-  SecurityInfo san_security_info;
-  helper.GetSecurityInfo(&san_security_info);
-  EXPECT_FALSE(san_security_info.cert_missing_subject_alt_name);
-
-  // Ensure subjectAltName is detected as missing when the cert doesn't
-  // include it.
-  scoped_refptr<net::X509Certificate> cert = net::ImportCertFromFile(
-      net::GetTestCertsDirectory(), "salesforce_com_test.pem");
-  ASSERT_TRUE(cert);
-  helper.SetCertificate(std::move(cert));
-
-  SecurityInfo no_san_security_info;
-  helper.GetSecurityInfo(&no_san_security_info);
-  EXPECT_TRUE(no_san_security_info.cert_missing_subject_alt_name);
-}
-
-// Tests that a mixed form is reflected in the SecurityInfo.
+// Tests that a mixed form is reflected in the security level.
 TEST(SecurityStateTest, MixedForm) {
   TestSecurityStateHelper helper;
-
-  SecurityInfo no_mixed_form_security_info;
-  helper.GetSecurityInfo(&no_mixed_form_security_info);
-  EXPECT_FALSE(no_mixed_form_security_info.contained_mixed_form);
-
   helper.set_contained_mixed_form(true);
 
   // Verify that a mixed form downgrades the security level.
-  SecurityInfo mixed_form_security_info;
-  helper.GetSecurityInfo(&mixed_form_security_info);
-  EXPECT_TRUE(mixed_form_security_info.contained_mixed_form);
-  EXPECT_EQ(CONTENT_STATUS_NONE, mixed_form_security_info.mixed_content_status);
-  EXPECT_EQ(NONE, mixed_form_security_info.security_level);
+  EXPECT_EQ(NONE, helper.GetSecurityLevel());
 
   // Ensure that active mixed content trumps the mixed form warning.
   helper.set_ran_mixed_content(true);
-  SecurityInfo mixed_form_and_active_security_info;
-  helper.GetSecurityInfo(&mixed_form_and_active_security_info);
-  EXPECT_TRUE(mixed_form_and_active_security_info.contained_mixed_form);
-  EXPECT_EQ(CONTENT_STATUS_RAN,
-            mixed_form_and_active_security_info.mixed_content_status);
-  EXPECT_EQ(DANGEROUS, mixed_form_and_active_security_info.security_level);
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 // Tests that policy-installed-certificates do not interfere with mixed content
@@ -399,51 +282,24 @@
   helper.set_has_policy_certificate(true);
   helper.set_cert_status(0);
 
-  {
-    // Verify that if no mixed content is present, the policy-installed
-    // certificate is recorded.
-    SecurityInfo no_mixed_content_security_info;
-    helper.GetSecurityInfo(&no_mixed_content_security_info);
-    EXPECT_FALSE(no_mixed_content_security_info.contained_mixed_form);
-    EXPECT_EQ(CONTENT_STATUS_NONE,
-              no_mixed_content_security_info.mixed_content_status);
-    EXPECT_EQ(SECURE_WITH_POLICY_INSTALLED_CERT,
-              no_mixed_content_security_info.security_level);
-  }
+  // Verify that if no mixed content is present, the policy-installed
+  // certificate is recorded.
+  EXPECT_EQ(SECURE_WITH_POLICY_INSTALLED_CERT, helper.GetSecurityLevel());
 
-  {
-    // Verify that a mixed form downgrades the security level.
-    SecurityInfo mixed_form_security_info;
-    helper.set_contained_mixed_form(true);
-    helper.GetSecurityInfo(&mixed_form_security_info);
-    EXPECT_TRUE(mixed_form_security_info.contained_mixed_form);
-    EXPECT_EQ(CONTENT_STATUS_NONE,
-              mixed_form_security_info.mixed_content_status);
-    EXPECT_EQ(NONE, mixed_form_security_info.security_level);
-  }
+  // Verify that a mixed form downgrades the security level.
+  helper.set_contained_mixed_form(true);
+  EXPECT_EQ(NONE, helper.GetSecurityLevel());
 
-  {
-    // Verify that passive mixed content downgrades the security level.
-    helper.set_contained_mixed_form(false);
-    helper.set_displayed_mixed_content(true);
-    SecurityInfo passive_mixed_security_info;
-    helper.GetSecurityInfo(&passive_mixed_security_info);
-    EXPECT_EQ(CONTENT_STATUS_DISPLAYED,
-              passive_mixed_security_info.mixed_content_status);
-    EXPECT_EQ(NONE, passive_mixed_security_info.security_level);
-  }
+  // Verify that passive mixed content downgrades the security level.
+  helper.set_contained_mixed_form(false);
+  helper.set_displayed_mixed_content(true);
+  EXPECT_EQ(NONE, helper.GetSecurityLevel());
 
-  {
-    // Ensure that active mixed content downgrades the security level.
-    helper.set_contained_mixed_form(false);
-    helper.set_displayed_mixed_content(false);
-    helper.set_ran_mixed_content(true);
-    SecurityInfo active_mixed_security_info;
-    helper.GetSecurityInfo(&active_mixed_security_info);
-    EXPECT_EQ(CONTENT_STATUS_RAN,
-              active_mixed_security_info.mixed_content_status);
-    EXPECT_EQ(DANGEROUS, active_mixed_security_info.security_level);
-  }
+  // Ensure that active mixed content downgrades the security level.
+  helper.set_contained_mixed_form(false);
+  helper.set_displayed_mixed_content(false);
+  helper.set_ran_mixed_content(true);
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 // Tests that HTTP_SHOW_WARNING is set on normal http pages but DANGEROUS on
@@ -455,21 +311,10 @@
   scoped_feature_list.InitAndEnableFeature(
       security_state::features::kMarkHttpAsFeature);
 
-  {
-    SecurityInfo security_info;
-    helper.GetSecurityInfo(&security_info);
-    EXPECT_FALSE(security_info.insecure_input_events.insecure_field_edited);
-    EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
-  }
+  EXPECT_EQ(security_state::HTTP_SHOW_WARNING, helper.GetSecurityLevel());
 
   helper.set_insecure_field_edit(true);
-
-  {
-    SecurityInfo security_info;
-    helper.GetSecurityInfo(&security_info);
-    EXPECT_TRUE(security_info.insecure_input_events.insecure_field_edited);
-    EXPECT_EQ(DANGEROUS, security_info.security_level);
-  }
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 // Tests that HTTP_SHOW_WARNING is set on normal http pages but DANGEROUS on
@@ -481,21 +326,10 @@
   scoped_feature_list.InitAndDisableFeature(
       security_state::features::kMarkHttpAsFeature);
 
-  {
-    SecurityInfo security_info;
-    helper.GetSecurityInfo(&security_info);
-    EXPECT_FALSE(security_info.insecure_input_events.insecure_field_edited);
-    EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level);
-  }
+  EXPECT_EQ(HTTP_SHOW_WARNING, helper.GetSecurityLevel());
 
   helper.set_insecure_field_edit(true);
-
-  {
-    SecurityInfo security_info;
-    helper.GetSecurityInfo(&security_info);
-    EXPECT_TRUE(security_info.insecure_input_events.insecure_field_edited);
-    EXPECT_EQ(DANGEROUS, security_info.security_level);
-  }
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 // Tests that DANGEROUS is set on normal http pages regardless of form edits
@@ -509,21 +343,10 @@
       {{security_state::features::kMarkHttpAsFeatureParameterName,
         security_state::features::kMarkHttpAsParameterDangerous}});
 
-  {
-    SecurityInfo security_info;
-    helper.GetSecurityInfo(&security_info);
-    EXPECT_FALSE(security_info.insecure_input_events.insecure_field_edited);
-    EXPECT_EQ(DANGEROUS, security_info.security_level);
-  }
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 
   helper.set_insecure_field_edit(true);
-
-  {
-    SecurityInfo security_info;
-    helper.GetSecurityInfo(&security_info);
-    EXPECT_TRUE(security_info.insecure_input_events.insecure_field_edited);
-    EXPECT_EQ(DANGEROUS, security_info.security_level);
-  }
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 // Tests IsSchemeCryptographic function.
@@ -560,33 +383,14 @@
 // Tests that HTTP_SHOW_WARNING is not set for error pages.
 TEST(SecurityStateTest, ErrorPage) {
   TestSecurityStateHelper helper;
-  SecurityInfo security_info;
   helper.SetUrl(GURL("http://nonexistent.test"));
   helper.set_is_error_page(true);
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(SecurityLevel::NONE, security_info.security_level);
+  EXPECT_EQ(SecurityLevel::NONE, helper.GetSecurityLevel());
 
   // Sanity-check that if it's not an error page, the security level is
   // downgraded.
   helper.set_is_error_page(false);
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(SecurityLevel::HTTP_SHOW_WARNING, security_info.security_level);
-}
-
-// Tests that |is_non_cert_error_page| is properly set.
-TEST(SecurityStateTest, NonCertErrorPage) {
-  TestSecurityStateHelper helper;
-  SecurityInfo security_info;
-  helper.SetUrl(GURL("http://nonexistent.test"));
-  helper.set_is_error_page(true);
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_TRUE(security_info.is_non_cert_error_page);
-
-  // Should be false for cert errors.
-  helper.AddCertStatus(net::CERT_STATUS_DATE_INVALID);
-  SecurityInfo cert_error_security_info;
-  helper.GetSecurityInfo(&cert_error_security_info);
-  EXPECT_FALSE(cert_error_security_info.is_non_cert_error_page);
+  EXPECT_EQ(SecurityLevel::HTTP_SHOW_WARNING, helper.GetSecurityLevel());
 }
 
 // Tests that the billing status is set, and it overrides valid HTTPS.
@@ -599,36 +403,23 @@
                                << net::SSL_CONNECTION_VERSION_SHIFT);
   helper.SetCipherSuite(ciphersuite);
 
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_EQ(MALICIOUS_CONTENT_STATUS_NONE,
-            security_info.malicious_content_status);
-
   helper.set_malicious_content_status(MALICIOUS_CONTENT_STATUS_BILLING);
-  helper.GetSecurityInfo(&security_info);
 
-  EXPECT_EQ(MALICIOUS_CONTENT_STATUS_BILLING,
-            security_info.malicious_content_status);
-  EXPECT_EQ(DANGEROUS, security_info.security_level);
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
-// Tests that the billing status is set, and it overrides invalid HTTPS.
+// Tests that the billing status overrides HTTP warnings.
 TEST(SecurityStateTest, BillingOverridesHTTPWarning) {
   TestSecurityStateHelper helper;
   helper.SetUrl(GURL(kHttpUrl));
 
-  SecurityInfo security_info;
-  helper.GetSecurityInfo(&security_info);
   // Expect to see a warning for HTTP first.
-  EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+  EXPECT_EQ(security_state::HTTP_SHOW_WARNING, helper.GetSecurityLevel());
 
   // Now mark the URL as matching the billing list.
   helper.set_malicious_content_status(MALICIOUS_CONTENT_STATUS_BILLING);
-  helper.GetSecurityInfo(&security_info);
   // Expect to see a warning for billing now.
-  EXPECT_EQ(MALICIOUS_CONTENT_STATUS_BILLING,
-            security_info.malicious_content_status);
-  EXPECT_EQ(DANGEROUS, security_info.security_level);
+  EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
 }
 
 }  // namespace security_state
diff --git a/content/browser/DEPS b/content/browser/DEPS
index 893be17..ac47014 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -134,7 +134,6 @@
   "+third_party/blink/public/platform/modules/installedapp/related_application.mojom.h",
   "+third_party/blink/public/platform/modules/mediasession/media_session.mojom.h",
   "+third_party/blink/public/platform/modules/mediastream/media_devices.mojom.h",
-  "+third_party/blink/public/platform/modules/notifications/notification_service.mojom.h",
   "+third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom.h",
   "+third_party/blink/public/platform/modules/websockets/websocket.mojom.h",
 
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index 6c2a84c..1538039 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -2796,7 +2796,6 @@
   // This test simulates a scenario where RenderWidgetHostViewAura::SetSize
   // is not called again after its window is added to the root window.
   // Ensure that we still get a legacy HWND for accessibility.
-
   ASSERT_TRUE(embedded_test_server()->Start());
   WebContentsImpl* web_contents =
       static_cast<WebContentsImpl*>(shell()->web_contents());
@@ -2808,13 +2807,13 @@
   // RenderWidgetHostViewAura with a null parent view.
   web_contents_view_aura->set_init_rwhv_with_null_parent_for_testing(true);
 
-  // Navigate to a new page and wait for the accessibility tree to load.
-  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
-                                         ui::kAXModeComplete,
+  // Enable accessibility.
+  AccessibilityNotificationWaiter waiter(web_contents, ui::kAXModeComplete,
                                          ax::mojom::Event::kLoadComplete);
+
+  // Navigate to a new page.
   NavigateToURL(shell(), embedded_test_server()->GetURL(
                              "/accessibility/html/article.html"));
-  waiter.WaitForNotification();
 
   // At this point the root of the accessibility tree shouldn't have an HWND
   // because we never gave a parent window to the RWHVA.
@@ -2827,6 +2826,8 @@
   // an HWND for accessibility now.
   web_contents_view->GetNativeView()->AddChild(
       web_contents->GetRenderWidgetHostView()->GetNativeView());
+  // The load event will only fire after the page is attached.
+  waiter.WaitForNotification();
   ASSERT_NE(nullptr, manager->GetParentHWND());
 }
 
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
index 8138c80..4e0be16d 100644
--- a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
@@ -125,6 +125,13 @@
   BrowserAccessibilityManager::FireGeneratedEvent(event_type, node);
 
   switch (event_type) {
+    case ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED: {
+      int32_t focus_id = GetTreeData().sel_focus_object_id;
+      BrowserAccessibility* focus_object = GetFromID(focus_id);
+      if (focus_object)
+        FireEvent(focus_object, ax::mojom::Event::kTextSelectionChanged);
+      break;
+    }
     case ui::AXEventGenerator::Event::CHECKED_STATE_CHANGED:
       FireEvent(node, ax::mojom::Event::kCheckedStateChanged);
       break;
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index 9e1db80..7fc5256 100644
--- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -236,8 +236,9 @@
   RunEventTest(FILE_PATH_LITERAL("aria-combo-box-focus.html"));
 }
 
+// TODO(aboxhall): Fix flaky test
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
-                       AccessibilityEventsAriaComboBoxDelayAddList) {
+                       DISABLED_AccessibilityEventsAriaComboBoxDelayAddList) {
   RunEventTest(FILE_PATH_LITERAL("aria-combo-box-delay-add-list.html"));
 }
 
@@ -414,8 +415,9 @@
   RunEventTest(FILE_PATH_LITERAL("live-region-elem-reparent.html"));
 }
 
+// TODO(aboxhall): Fix flakiness.
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
-                       AccessibilityEventsLiveRegionIgnoresClick) {
+                       DISABLED_AccessibilityEventsLiveRegionIgnoresClick) {
   RunEventTest(FILE_PATH_LITERAL("live-region-ignores-click.html"));
 }
 
@@ -478,8 +480,16 @@
   RunEventTest(FILE_PATH_LITERAL("remove-hidden-attribute.html"));
 }
 
+// TODO(aboxhall): Fix flakiness on Windows
+#if defined(OS_WIN)
+#define MAYBE_AccessibilityEventsReportValidityInvalidField \
+  DISABLED_AccessibilityEventsReportValidityInvalidField
+#else
+#define MAYBE_AccessibilityEventsReportValidityInvalidField \
+  AccessibilityEventsReportValidityInvalidField
+#endif
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
-                       AccessibilityEventsReportValidityInvalidField) {
+                       MAYBE_AccessibilityEventsReportValidityInvalidField) {
   RunEventTest(FILE_PATH_LITERAL("report-validity-invalid-field.html"));
 }
 
@@ -543,8 +553,18 @@
   RunEventTest(FILE_PATH_LITERAL("tbody-focus.html"));
 }
 
+// Even with the deflaking in WaitForAccessibilityTreeToContainNodeWithName,
+// this test is still flaky on Windows.
+// TODO(aboxhall, dmazzoni, meredithl): re-enable with better fix for above.
+#if defined(OS_WIN)
+#define MAYBE_AccessibilityEventsAriaSelectedChanged \
+  DISABLED_AccessibilityEventsAriaSelectedChanged
+#else
+#define MAYBE_AccessibilityEventsAriaSelectedChanged \
+  AccessibilityEventsAriaSelectedChanged
+#endif
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
-                       AccessibilityEventsAriaSelectedChanged) {
+                       MAYBE_AccessibilityEventsAriaSelectedChanged) {
   RunEventTest(FILE_PATH_LITERAL("aria-selected-changed.html"));
 }
 
diff --git a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
index 241e5fa6..be09e2e 100644
--- a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
+++ b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
@@ -136,8 +136,9 @@
   EXPECT_EQ(ax_child_frame_root->PlatformGetParent(), ax_iframe);
 }
 
+// TODO(aboxhall): Flaky test, discuss with dmazzoni
 IN_PROC_BROWSER_TEST_F(MAYBE_SitePerProcessAccessibilityBrowserTest,
-                       TwoCrossSiteNavigations) {
+                       DISABLED_TwoCrossSiteNavigations) {
   // Enable full accessibility for all current and future WebContents.
   BrowserAccessibilityState::GetInstance()->EnableAccessibility();
 
diff --git a/content/browser/browsing_data/conditional_cache_deletion_helper.cc b/content/browser/browsing_data/conditional_cache_deletion_helper.cc
index 1f64abc..c74b8e1 100644
--- a/content/browser/browsing_data/conditional_cache_deletion_helper.cc
+++ b/content/browser/browsing_data/conditional_cache_deletion_helper.cc
@@ -69,10 +69,10 @@
 }
 
 int ConditionalCacheDeletionHelper::DeleteAndDestroySelfWhenFinished(
-    const net::CompletionCallback& completion_callback) {
+    net::CompletionOnceCallback completion_callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  completion_callback_ = completion_callback;
+  completion_callback_ = std::move(completion_callback);
   iterator_ = cache_->CreateIterator();
 
   IterateOverEntries(net::OK);
@@ -97,8 +97,9 @@
       // The iteration finished successfully or we can no longer iterate
       // (e.g. the cache was destroyed). We cannot distinguish between the two,
       // but we know that there is nothing more that we can do, so we return OK.
+      DCHECK(completion_callback_);
       base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::BindOnce(completion_callback_, net::OK));
+          FROM_HERE, base::BindOnce(std::move(completion_callback_), net::OK));
       base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
       return;
     }
diff --git a/content/browser/browsing_data/conditional_cache_deletion_helper.h b/content/browser/browsing_data/conditional_cache_deletion_helper.h
index 40f41c8..64fe715 100644
--- a/content/browser/browsing_data/conditional_cache_deletion_helper.h
+++ b/content/browser/browsing_data/conditional_cache_deletion_helper.h
@@ -10,7 +10,7 @@
 #include "base/callback_forward.h"
 #include "base/sequenced_task_runner_helpers.h"
 #include "content/common/content_export.h"
-#include "net/base/completion_callback.h"
+#include "net/base/completion_once_callback.h"
 #include "net/base/net_errors.h"
 #include "net/disk_cache/disk_cache.h"
 #include "url/gurl.h"
@@ -62,7 +62,7 @@
   // ERR_IO_PENDING, the |completion_callback| will be invoked when the
   // operation completes.
   int DeleteAndDestroySelfWhenFinished(
-      const net::CompletionCallback& completion_callback);
+      net::CompletionOnceCallback completion_callback);
 
  private:
   friend class base::DeleteHelper<ConditionalCacheDeletionHelper>;
@@ -73,7 +73,7 @@
   disk_cache::Backend* cache_;
   const base::Callback<bool(const disk_cache::Entry*)> condition_;
 
-  net::CompletionCallback completion_callback_;
+  net::CompletionOnceCallback completion_callback_;
 
   std::unique_ptr<disk_cache::Backend::Iterator> iterator_;
   disk_cache::Entry* current_entry_;
diff --git a/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc b/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc
index acd700f..cf50bc0e 100644
--- a/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc
+++ b/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc
@@ -58,8 +58,8 @@
         content::BrowserContext::GetDefaultStoragePartition(
             shell()->web_contents()->GetBrowserContext()));
     done_callback_ =
-        base::Bind(&ConditionalCacheDeletionHelperBrowserTest::DoneCallback,
-                   base::Unretained(this));
+        base::BindOnce(&ConditionalCacheDeletionHelperBrowserTest::DoneCallback,
+                       base::Unretained(this));
     // UI and IO thread synchronization.
     waitable_event_ = std::make_unique<base::WaitableEvent>(
         base::WaitableEvent::ResetPolicy::AUTOMATIC,
@@ -86,7 +86,7 @@
     auto* helper =
         new ConditionalCacheDeletionHelper(cache_util_->backend(), condition);
 
-    helper->DeleteAndDestroySelfWhenFinished(done_callback_);
+    helper->DeleteAndDestroySelfWhenFinished(std::move(done_callback_));
   }
 
   bool TestCacheEntry(const GURL& url) {
@@ -130,7 +130,7 @@
     return shell()->web_contents()->GetBrowserContext();
   }
 
-  base::Callback<void(int)> done_callback_;
+  base::OnceCallback<void(int)> done_callback_;
   std::unique_ptr<CacheTestUtil> cache_util_;
   std::unique_ptr<base::WaitableEvent> waitable_event_;
 };
diff --git a/content/browser/browsing_data/storage_partition_code_cache_data_remover.cc b/content/browser/browsing_data/storage_partition_code_cache_data_remover.cc
index 773878ac..d2628191 100644
--- a/content/browser/browsing_data/storage_partition_code_cache_data_remover.cc
+++ b/content/browser/browsing_data/storage_partition_code_cache_data_remover.cc
@@ -5,6 +5,7 @@
 #include "content/browser/browsing_data/storage_partition_code_cache_data_remover.h"
 
 #include "base/bind.h"
+#include "base/callback_helpers.h"
 #include "base/location.h"
 #include "base/sequenced_task_runner_helpers.h"
 #include "base/single_thread_task_runner.h"
@@ -17,6 +18,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/content_features.h"
+#include "net/base/completion_repeating_callback.h"
 #include "net/disk_cache/disk_cache.h"
 
 namespace content {
@@ -66,12 +68,17 @@
 }
 
 void StoragePartitionCodeCacheDataRemover::ClearCache(
-    net::CompletionCallback callback,
+    net::CompletionOnceCallback callback,
     disk_cache::Backend* backend) {
   if (backend == nullptr) {
     std::move(callback).Run(net::ERR_FAILED);
     return;
   }
+
+  // Create a callback that is copyable, even though it can only be called once,
+  // so that we can use it synchronously in case result != net::ERR_IO_PENDING.
+  net::CompletionRepeatingCallback copyable_callback =
+      base::AdaptCallbackForRepeating(std::move(callback));
   int result = net::ERR_FAILED;
   if (!url_predicate_.is_null()) {
     result =
@@ -82,16 +89,18 @@
                  base::BindRepeating(
                      &GeneratedCodeCache::GetResourceURLFromKey),
                  begin_time_, end_time_)))
-            ->DeleteAndDestroySelfWhenFinished(callback);
+            ->DeleteAndDestroySelfWhenFinished(copyable_callback);
   } else if (begin_time_.is_null() && end_time_.is_max()) {
-    result = backend->DoomAllEntries(callback);
+    result = backend->DoomAllEntries(copyable_callback);
   } else {
-    result = backend->DoomEntriesBetween(begin_time_, end_time_, callback);
+    result =
+        backend->DoomEntriesBetween(begin_time_, end_time_, copyable_callback);
   }
   // When result is ERR_IO_PENDING the callback would be called after the
   // operation has finished.
   if (result != net::ERR_IO_PENDING) {
-    std::move(callback).Run(result);
+    DCHECK(copyable_callback);
+    copyable_callback.Run(result);
   }
 }
 
diff --git a/content/browser/browsing_data/storage_partition_code_cache_data_remover.h b/content/browser/browsing_data/storage_partition_code_cache_data_remover.h
index 89fc1c1a..989b5966 100644
--- a/content/browser/browsing_data/storage_partition_code_cache_data_remover.h
+++ b/content/browser/browsing_data/storage_partition_code_cache_data_remover.h
@@ -10,7 +10,7 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/sequenced_task_runner_helpers.h"
-#include "net/base/completion_callback.h"
+#include "net/base/completion_once_callback.h"
 #include "url/gurl.h"
 
 namespace disk_cache {
@@ -70,7 +70,7 @@
   // Executed on IO thread.
   void ClearJSCodeCache();
   void ClearWASMCodeCache(int rv);
-  void ClearCache(net::CompletionCallback callback,
+  void ClearCache(net::CompletionOnceCallback callback,
                   disk_cache::Backend* backend);
   void DoneClearCodeCache(int rv);
 
diff --git a/content/browser/notifications/DEPS b/content/browser/notifications/DEPS
index a8b95f1..d3c1e80b 100644
--- a/content/browser/notifications/DEPS
+++ b/content/browser/notifications/DEPS
@@ -1,4 +1,4 @@
 include_rules = [
   "+third_party/leveldatabase",
-  "+third_party/blink/public/platform/modules/notifications/notification_service.mojom.h",
+  "+third_party/blink/public/mojom/notifications/notification_service.mojom.h",
 ]
diff --git a/content/browser/notifications/blink_notification_service_impl.h b/content/browser/notifications/blink_notification_service_impl.h
index cc5f8d1..f816022 100644
--- a/content/browser/notifications/blink_notification_service_impl.h
+++ b/content/browser/notifications/blink_notification_service_impl.h
@@ -12,8 +12,8 @@
 #include "content/public/browser/browser_context.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
+#include "third_party/blink/public/mojom/notifications/notification_service.mojom.h"
 #include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
-#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom.h"
 #include "url/origin.h"
 
 namespace blink {
diff --git a/content/browser/notifications/blink_notification_service_impl_unittest.cc b/content/browser/notifications/blink_notification_service_impl_unittest.cc
index 8beb9e51..ce9b731 100644
--- a/content/browser/notifications/blink_notification_service_impl_unittest.cc
+++ b/content/browser/notifications/blink_notification_service_impl_unittest.cc
@@ -36,8 +36,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/notifications/notification_resources.h"
+#include "third_party/blink/public/mojom/notifications/notification_service.mojom.h"
 #include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
-#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
 using ::testing::Return;
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.h b/content/browser/notifications/notification_event_dispatcher_impl.h
index 230c56d..92de011 100644
--- a/content/browser/notifications/notification_event_dispatcher_impl.h
+++ b/content/browser/notifications/notification_event_dispatcher_impl.h
@@ -13,7 +13,7 @@
 #include "content/common/content_export.h"
 #include "content/public/browser/notification_database_data.h"
 #include "content/public/browser/notification_event_dispatcher.h"
-#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom.h"
+#include "third_party/blink/public/mojom/notifications/notification_service.mojom.h"
 
 namespace content {
 
diff --git a/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc b/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc
index 325b65f1..4643bdca 100644
--- a/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc
+++ b/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc
@@ -16,7 +16,7 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom.h"
+#include "third_party/blink/public/mojom/notifications/notification_service.mojom.h"
 
 namespace content {
 
diff --git a/content/browser/notifications/platform_notification_context_impl.h b/content/browser/notifications/platform_notification_context_impl.h
index 24918ced..868d7da4 100644
--- a/content/browser/notifications/platform_notification_context_impl.h
+++ b/content/browser/notifications/platform_notification_context_impl.h
@@ -24,7 +24,7 @@
 #include "content/common/content_export.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/platform_notification_context.h"
-#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom.h"
+#include "third_party/blink/public/mojom/notifications/notification_service.mojom.h"
 
 class GURL;
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 72d9088..038a092b 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -284,6 +284,9 @@
   void CursorVisibilityChanged(bool visible) override {
     DLOG(WARNING) << "Input request on unbound interface";
   }
+  void FallbackCursorModeToggled(bool is_on) override {
+    DLOG(WARNING) << "Input request on unbound interface";
+  }
   void ImeSetComposition(const base::string16& text,
                          const std::vector<ui::ImeTextSpan>& ime_text_spans,
                          const gfx::Range& range,
@@ -1667,10 +1670,14 @@
   Send(new WidgetMsg_ShowContextMenu(GetRoutingID(), source_type, point));
 }
 
-void RenderWidgetHostImpl::SendCursorVisibilityState(bool is_visible) {
+void RenderWidgetHostImpl::OnCursorVisibilityStateChanged(bool is_visible) {
   GetWidgetInputHandler()->CursorVisibilityChanged(is_visible);
 }
 
+void RenderWidgetHostImpl::OnFallbackCursorModeToggled(bool is_on) {
+  GetWidgetInputHandler()->FallbackCursorModeToggled(is_on);
+}
+
 // static
 void RenderWidgetHostImpl::DisableResizeAckCheckForTesting() {
   g_check_for_pending_visual_properties_ack = false;
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index e79017f0..4e57f0e 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -351,8 +351,11 @@
     return is_last_unlocked_by_target_;
   }
 
-  // Noifies the RenderWidget of the current mouse cursor visibility state.
-  void SendCursorVisibilityState(bool is_visible);
+  // Notifies the RenderWidget of the current mouse cursor visibility state.
+  void OnCursorVisibilityStateChanged(bool is_visible);
+
+  // Notifies the RenderWidget when toggle fallback cursor mode on/off.
+  void OnFallbackCursorModeToggled(bool is_on);
 
   // Notifies the RenderWidgetHost that the View was destroyed.
   void ViewDestroyed();
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index b670ba9..2a1b59e 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -2224,11 +2224,15 @@
 }
 
 void RenderWidgetHostViewAndroid::OnCursorVisibilityChanged(bool visible) {
-  TRACE_EVENT0("browser",
-               "RenderWidgetHostViewAndroid::OnCursorVisibilityChanged");
   DCHECK(observing_root_window_);
   if (host())
-    host()->SendCursorVisibilityState(visible);
+    host()->OnCursorVisibilityStateChanged(visible);
+}
+
+void RenderWidgetHostViewAndroid::OnFallbackCursorModeToggled(bool is_on) {
+  DCHECK(observing_root_window_);
+  if (host())
+    host()->OnFallbackCursorModeToggled(is_on);
 }
 
 void RenderWidgetHostViewAndroid::OnLostResources() {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index ce2f0cf..c3cf148 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -221,6 +221,7 @@
   void OnActivityStopped() override;
   void OnActivityStarted() override;
   void OnCursorVisibilityChanged(bool visible) override;
+  void OnFallbackCursorModeToggled(bool is_on) override;
 
   // StylusTextSelectorClient implementation.
   void OnStylusSelectBegin(float x0, float y0, float x1, float y1) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index fbc0443..45c4dfa 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2281,7 +2281,7 @@
     return;
 
   cursor_visibility_state_in_renderer_ = is_visible ? VISIBLE : NOT_VISIBLE;
-  host()->SendCursorVisibilityState(is_visible);
+  host()->OnCursorVisibilityStateChanged(is_visible);
 }
 
 void RenderWidgetHostViewAura::SetOverscrollControllerEnabled(bool enabled) {
diff --git a/content/browser/renderer_interface_binders.cc b/content/browser/renderer_interface_binders.cc
index b317a37b..01e2d9ee 100644
--- a/content/browser/renderer_interface_binders.cc
+++ b/content/browser/renderer_interface_binders.cc
@@ -36,7 +36,7 @@
 #include "services/shape_detection/public/mojom/textdetection.mojom.h"
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h"
 #include "third_party/blink/public/mojom/cookie_store/cookie_store.mojom.h"
-#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom.h"
+#include "third_party/blink/public/mojom/notifications/notification_service.mojom.h"
 #include "url/origin.h"
 
 namespace content {
diff --git a/content/browser/service_worker/service_worker_no_best_effort_tasks_browsertest.cc b/content/browser/service_worker/service_worker_no_best_effort_tasks_browsertest.cc
new file mode 100644
index 0000000..b46a9fe
--- /dev/null
+++ b/content/browser/service_worker/service_worker_no_best_effort_tasks_browsertest.cc
@@ -0,0 +1,50 @@
+// 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 "base/base_switches.h"
+#include "base/command_line.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 "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "url/gurl.h"
+
+namespace content {
+
+class ServiceWorkerNoBestEffortTasksTest : public ContentBrowserTest {
+ public:
+  ServiceWorkerNoBestEffortTasksTest() = default;
+  ~ServiceWorkerNoBestEffortTasksTest() override = default;
+
+  void SetUp() override {
+    ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
+    ContentBrowserTest::SetUp();
+  }
+
+ private:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitch(switches::kDisableBestEffortTasks);
+    ContentBrowserTest::SetUpCommandLine(command_line);
+  }
+
+  void SetUpOnMainThread() override {
+    host_resolver()->AddRule("*", "127.0.0.1");
+    embedded_test_server()->StartAcceptingConnections();
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNoBestEffortTasksTest);
+};
+
+// Verify that the promise returned by navigator.serviceWorker.register()
+// settles without running BEST_EFFORT tasks.
+// This is a regression test for https://crbug.com/939250.
+IN_PROC_BROWSER_TEST_F(ServiceWorkerNoBestEffortTasksTest,
+                       RegisterServiceWorker) {
+  NavigateToURL(shell(), embedded_test_server()->GetURL(
+                             "/service_worker/create_service_worker.html"));
+  EXPECT_EQ("DONE", EvalJs(shell(), "register('empty.js');"));
+}
+
+}  // namespace content
diff --git a/content/common/input/input_handler.mojom b/content/common/input/input_handler.mojom
index 484d0ca..d299b98 100644
--- a/content/common/input/input_handler.mojom
+++ b/content/common/input/input_handler.mojom
@@ -226,6 +226,9 @@
   // Sends the cursor visibility state to the render widget.
   CursorVisibilityChanged(bool visible);
 
+  // Notifies the RenderWidget when toggle fallback cursor mode on/off.
+  FallbackCursorModeToggled(bool is_on);
+
   // This message sends a string being composed with an input method.
   ImeSetComposition(mojo_base.mojom.String16 text,
                     array<ui.mojom.ImeTextSpan> ime_text_spans,
diff --git a/content/public/test/fake_download_item.cc b/content/public/test/fake_download_item.cc
index 567d9a6..69cd6b64 100644
--- a/content/public/test/fake_download_item.cc
+++ b/content/public/test/fake_download_item.cc
@@ -261,7 +261,7 @@
   NOTREACHED();
 }
 
-void FakeDownloadItem::Rename(const std::string& name,
+void FakeDownloadItem::Rename(const base::FilePath& name,
                               RenameDownloadCallback callback) {
   NOTREACHED();
 }
diff --git a/content/public/test/fake_download_item.h b/content/public/test/fake_download_item.h
index 1603eac..7108311 100644
--- a/content/public/test/fake_download_item.h
+++ b/content/public/test/fake_download_item.h
@@ -109,7 +109,7 @@
   void ValidateDangerousDownload() override;
   void StealDangerousDownload(bool delete_file_afterward,
                               const AcquireFileCallback& callback) override;
-  void Rename(const std::string& name,
+  void Rename(const base::FilePath& name,
               RenameDownloadCallback callback) override;
 
   bool removed() const { return removed_; }
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc
index 5b0cd7c..ec7e2231 100644
--- a/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -692,7 +692,6 @@
       break;
     case ax::mojom::Action::kSetValue:
       target.SetValue(blink::WebString::FromUTF8(data.value));
-      HandleAXEvent(target, ax::mojom::Event::kValueChanged);
       break;
     case ax::mojom::Action::kShowContextMenu:
       target.ShowContextMenu();
@@ -723,6 +722,9 @@
       }
       break;
     case ax::mojom::Action::kSignalEndOfTest:
+      // Wait for 100ms to allow pending events to come in
+      base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
+
       HandleAXEvent(root, ax::mojom::Event::kEndOfTest);
       break;
   }
diff --git a/content/renderer/accessibility/render_accessibility_impl_browsertest.cc b/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
index 22eac1f..c1758309 100644
--- a/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
+++ b/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
@@ -292,7 +292,7 @@
   ExecuteJavaScriptForTests(
       "document.getElementById('B').style.visibility = 'hidden';");
   // Force layout now.
-  ExecuteJavaScriptForTests("document.getElementById('B').offsetLeft;");
+  root_obj.UpdateLayoutAndCheckValidity();
 
   // Send a childrenChanged on "A".
   sink_->ClearMessages();
@@ -328,17 +328,19 @@
 
   EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser());
 
-  // Show node "B", then send a childrenChanged on "A".
-  ExecuteJavaScriptForTests(
-      "document.getElementById('B').style.visibility = 'visible';");
-  ExecuteJavaScriptForTests("document.getElementById('B').offsetLeft;");
-
-  sink_->ClearMessages();
   WebDocument document = GetMainFrame()->GetDocument();
   WebAXObject root_obj = WebAXObject::FromWebDocument(document);
   WebAXObject node_a = root_obj.ChildAt(0);
+  WebAXObject node_c = node_a.ChildAt(0);
+
+  // Show node "B", then send a childrenChanged on "A".
+  ExecuteJavaScriptForTests(
+      "document.getElementById('B').style.visibility = 'visible';");
+
+  root_obj.UpdateLayoutAndCheckValidity();
+  sink_->ClearMessages();
+
   WebAXObject node_b = node_a.ChildAt(0);
-  WebAXObject node_c = node_b.ChildAt(0);
 
   render_accessibility().HandleAXEvent(node_a,
                                        ax::mojom::Event::kChildrenChanged);
@@ -415,14 +417,16 @@
   EXPECT_TRUE(mock_annotator().image_processors_[0].is_bound());
   EXPECT_EQ(1u, mock_annotator().callbacks_.size());
 
-  // Show node "B".
-  ExecuteJavaScriptForTests(
-      "document.getElementById('B').style.visibility = 'visible';");
-
-  sink_->ClearMessages();
   WebDocument document = GetMainFrame()->GetDocument();
   WebAXObject root_obj = WebAXObject::FromWebDocument(document);
   ASSERT_FALSE(root_obj.IsNull());
+
+  // Show node "B".
+  ExecuteJavaScriptForTests(
+      "document.getElementById('B').style.visibility = 'visible';");
+  sink_->ClearMessages();
+  root_obj.UpdateLayoutAndCheckValidity();
+
   // This should update the annotations of all images on the page, including the
   // already visible one.
   render_accessibility().MarkWebAXObjectDirty(root_obj, true /* subtree */);
diff --git a/content/renderer/input/widget_input_handler_impl.cc b/content/renderer/input/widget_input_handler_impl.cc
index cb27c98..ed5274a0 100644
--- a/content/renderer/input/widget_input_handler_impl.cc
+++ b/content/renderer/input/widget_input_handler_impl.cc
@@ -99,6 +99,11 @@
                                  render_widget_, visible));
 }
 
+void WidgetInputHandlerImpl::FallbackCursorModeToggled(bool is_on) {
+  RunOnMainThread(base::BindOnce(&RenderWidget::OnFallbackCursorModeToggled,
+                                 render_widget_, is_on));
+}
+
 void WidgetInputHandlerImpl::ImeSetComposition(
     const base::string16& text,
     const std::vector<ui::ImeTextSpan>& ime_text_spans,
diff --git a/content/renderer/input/widget_input_handler_impl.h b/content/renderer/input/widget_input_handler_impl.h
index f704aed..d921ca1 100644
--- a/content/renderer/input/widget_input_handler_impl.h
+++ b/content/renderer/input/widget_input_handler_impl.h
@@ -38,6 +38,7 @@
   void SetEditCommandsForNextKeyEvent(
       const std::vector<EditCommand>& commands) override;
   void CursorVisibilityChanged(bool visible) override;
+  void FallbackCursorModeToggled(bool is_on) override;
   void ImeSetComposition(const base::string16& text,
                          const std::vector<ui::ImeTextSpan>& ime_text_spans,
                          const gfx::Range& range,
diff --git a/content/renderer/loader/web_worker_fetch_context_impl.cc b/content/renderer/loader/web_worker_fetch_context_impl.cc
index 382e629..64cae48 100644
--- a/content/renderer/loader/web_worker_fetch_context_impl.cc
+++ b/content/renderer/loader/web_worker_fetch_context_impl.cc
@@ -366,7 +366,7 @@
 
 void WebWorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
   if (renderer_preferences_.enable_do_not_track) {
-    request.SetHTTPHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
+    request.SetHttpHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
                                "1");
   }
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index d2c7852..21016bc 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5166,7 +5166,7 @@
 void RenderFrameImpl::WillSendRequestInternal(blink::WebURLRequest& request,
                                               ResourceType resource_type) {
   if (render_view_->renderer_preferences_.enable_do_not_track)
-    request.SetHTTPHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
+    request.SetHttpHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
                                "1");
 
   WebDocumentLoader* provisional_document_loader =
@@ -5216,7 +5216,7 @@
       if (custom_user_agent.IsEmpty())
         request.ClearHttpHeaderField("User-Agent");
       else
-        request.SetHTTPHeaderField("User-Agent", custom_user_agent);
+        request.SetHttpHeaderField("User-Agent", custom_user_agent);
     }
     response_override =
         old_extra_data->TakeNavigationResponseOverrideOwnership();
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index a82b787..24c0b803 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1027,6 +1027,11 @@
     GetWebWidget()->SetCursorVisibilityState(is_visible);
 }
 
+void RenderWidget::OnFallbackCursorModeToggled(bool is_on) {
+  if (GetWebWidget())
+    GetWebWidget()->OnFallbackCursorModeToggled(is_on);
+}
+
 void RenderWidget::OnMouseCaptureLost() {
   if (GetWebWidget())
     GetWebWidget()->MouseCaptureLost();
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index 41066fb..8e8f82d 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -568,6 +568,7 @@
   void OnSetFocus(bool enable);
   void OnMouseCaptureLost();
   void OnCursorVisibilityChange(bool is_visible);
+  void OnFallbackCursorModeToggled(bool is_on);
   void OnSetEditCommandsForNextKeyEvent(const EditCommands& edit_commands);
   void OnImeSetComposition(
       const base::string16& text,
diff --git a/content/renderer/service_worker/service_worker_fetch_context_impl.cc b/content/renderer/service_worker/service_worker_fetch_context_impl.cc
index 636ac88..e989d73 100644
--- a/content/renderer/service_worker/service_worker_fetch_context_impl.cc
+++ b/content/renderer/service_worker/service_worker_fetch_context_impl.cc
@@ -97,7 +97,7 @@
 void ServiceWorkerFetchContextImpl::WillSendRequest(
     blink::WebURLRequest& request) {
   if (renderer_preferences_.enable_do_not_track) {
-    request.SetHTTPHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
+    request.SetHttpHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
                                "1");
   }
   auto extra_data = std::make_unique<RequestExtraData>();
diff --git a/content/shell/test_runner/web_ax_object_proxy.cc b/content/shell/test_runner/web_ax_object_proxy.cc
index e2804d5..b133f3ff 100644
--- a/content/shell/test_runner/web_ax_object_proxy.cc
+++ b/content/shell/test_runner/web_ax_object_proxy.cc
@@ -843,6 +843,8 @@
                               notification_name.size())
           .ToLocalChecked(),
   };
+  // TODO(aboxhall): Can we force this to run in a new task, to avoid
+  // dirtying layout during post-layout hooks?
   frame->CallFunctionEvenIfScriptDisabled(
       v8::Local<v8::Function>::New(isolate, notification_callback_),
       context->Global(), base::size(argv), argv);
@@ -1961,7 +1963,6 @@
 
 bool WebAXObjectProxy::HasNonIdentityTransform() {
   accessibility_object_.UpdateLayoutAndCheckValidity();
-  accessibility_object_.UpdateLayoutAndCheckValidity();
   blink::WebAXObject container;
   blink::WebFloatRect bounds;
   SkMatrix44 matrix;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 212e7766..b70d309 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -894,6 +894,7 @@
     "../browser/service_worker/service_worker_browsertest.cc",
     "../browser/service_worker/service_worker_clients_api_browsertest.cc",
     "../browser/service_worker/service_worker_file_upload_browsertest.cc",
+    "../browser/service_worker/service_worker_no_best_effort_tasks_browsertest.cc",
     "../browser/service_worker/service_worker_tls_browsertest.cc",
     "../browser/session_history_browsertest.cc",
     "../browser/shape_detection/shape_detection_browsertest.cc",
diff --git a/content/test/accessibility_browser_test_utils.cc b/content/test/accessibility_browser_test_utils.cc
index 73bae2a..c853e91 100644
--- a/content/test/accessibility_browser_test_utils.cc
+++ b/content/test/accessibility_browser_test_utils.cc
@@ -104,6 +104,14 @@
   loop_runner_ = std::make_unique<base::RunLoop>();
 }
 
+void AccessibilityNotificationWaiter::WaitForNotificationWithTimeout(
+    base::TimeDelta timeout) {
+  base::OneShotTimer quit_timer;
+  quit_timer.Start(FROM_HERE, timeout, loop_runner_->QuitWhenIdleClosure());
+
+  WaitForNotification();
+}
+
 const ui::AXTree& AccessibilityNotificationWaiter::GetAXTree() const {
   static base::NoDestructor<ui::AXTree> empty_tree;
   RenderFrameHostImpl* main_frame =
@@ -126,6 +134,8 @@
   if (IsAboutBlank())
     return;
 
+  LOG(INFO) << "OnAccessibilityEvent " << event_type;
+
   if (event_to_wait_for_ == ax::mojom::Event::kNone ||
       event_to_wait_for_ == event_type) {
     event_target_id_ = event_target_id;
diff --git a/content/test/accessibility_browser_test_utils.h b/content/test/accessibility_browser_test_utils.h
index 0d07291..27870b4 100644
--- a/content/test/accessibility_browser_test_utils.h
+++ b/content/test/accessibility_browser_test_utils.h
@@ -46,6 +46,9 @@
   // "about:blank".
   void WaitForNotification();
 
+  // Blocks until the notification is received, or the given timeout passes.
+  void WaitForNotificationWithTimeout(base::TimeDelta timeout);
+
   // After WaitForNotification has returned, this will retrieve
   // the tree of accessibility nodes received from the renderer process.
   const ui::AXTree& GetAXTree() const;
diff --git a/content/test/data/accessibility/aria/aria-hidden-iframe-body.html b/content/test/data/accessibility/aria/aria-hidden-iframe-body.html
index 583b0e4..c8537b87 100644
--- a/content/test/data/accessibility/aria/aria-hidden-iframe-body.html
+++ b/content/test/data/accessibility/aria/aria-hidden-iframe-body.html
@@ -5,7 +5,6 @@
 @BLINK-ALLOW:richlyEditable
 @WAIT-FOR:2
 -->
-<iframe srcdoc="<body contenteditable aria-hidden='true'>1</body>">
-</iframe>
-<iframe srcdoc="<body aria-hidden='true'>2</body>">
+<iframe src="frames/aria-hidden-1.html"></iframe>
+<iframe src="frames/aria-hidden-2.html"></iframe>
 </iframe>
diff --git a/content/test/data/accessibility/aria/frames/aria-hidden-1.html b/content/test/data/accessibility/aria/frames/aria-hidden-1.html
new file mode 100644
index 0000000..5fcad04
--- /dev/null
+++ b/content/test/data/accessibility/aria/frames/aria-hidden-1.html
@@ -0,0 +1 @@
+<body contenteditable aria-hidden='true'>1</body>
diff --git a/content/test/data/accessibility/aria/frames/aria-hidden-2.html b/content/test/data/accessibility/aria/frames/aria-hidden-2.html
new file mode 100644
index 0000000..8feb050
--- /dev/null
+++ b/content/test/data/accessibility/aria/frames/aria-hidden-2.html
@@ -0,0 +1 @@
+<body aria-hidden='true'>2</body>
diff --git a/content/test/data/accessibility/event/live-region-create-expected-uia-win7.txt b/content/test/data/accessibility/event/live-region-create-expected-uia-win7.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/content/test/data/accessibility/event/live-region-create-expected-uia-win7.txt
diff --git a/content/test/data/accessibility/event/remove-hidden-attribute-expected-win.txt b/content/test/data/accessibility/event/remove-hidden-attribute-expected-win.txt
index 7c485e7..73cb5b6a 100644
--- a/content/test/data/accessibility/event/remove-hidden-attribute-expected-win.txt
+++ b/content/test/data/accessibility/event/remove-hidden-attribute-expected-win.txt
@@ -1,3 +1,3 @@
 EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_LIST SetSize=3
 EVENT_OBJECT_SHOW on <div#item3> role=ROLE_SYSTEM_LISTITEM name="Item 3" PosInSet=3 SetSize=3
-IA2_EVENT_TEXT_INSERTED on <div> role=ROLE_SYSTEM_LIST SetSize=2 new_text={'<obj>' start=2 end=3}
+IA2_EVENT_TEXT_INSERTED on <div> role=ROLE_SYSTEM_LIST SetSize=3 new_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/event/remove-hidden-attribute-subtree-expected-win.txt b/content/test/data/accessibility/event/remove-hidden-attribute-subtree-expected-win.txt
index 1200268a..3dadf9f 100644
--- a/content/test/data/accessibility/event/remove-hidden-attribute-subtree-expected-win.txt
+++ b/content/test/data/accessibility/event/remove-hidden-attribute-subtree-expected-win.txt
@@ -1,3 +1,3 @@
 EVENT_OBJECT_REORDER on <ul> role=ROLE_SYSTEM_LIST SetSize=3
 EVENT_OBJECT_SHOW on <li#item3> role=ROLE_SYSTEM_LISTITEM PosInSet=3 SetSize=3
-IA2_EVENT_TEXT_INSERTED on <ul> role=ROLE_SYSTEM_LIST SetSize=2 new_text={'<obj>' start=2 end=3}
+IA2_EVENT_TEXT_INSERTED on <ul> role=ROLE_SYSTEM_LIST SetSize=3 new_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/html/frame/box2.html b/content/test/data/accessibility/html/frame/box2.html
new file mode 100644
index 0000000..9fa83bf
--- /dev/null
+++ b/content/test/data/accessibility/html/frame/box2.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body style="margin: 10px; padding: 0px; border: 0px;">
+<div role="img" style="width: 100px; height: 50px; background-color: #fef;"></div>
+</body>
+</html>
diff --git a/content/test/data/accessibility/html/iframe-transform.html b/content/test/data/accessibility/html/iframe-transform.html
index d29a9c59..d96a3c0 100644
--- a/content/test/data/accessibility/html/iframe-transform.html
+++ b/content/test/data/accessibility/html/iframe-transform.html
@@ -20,6 +20,6 @@
 <html>
 <body style="padding: 0; margin: 0;">
   <iframe width=220 height=220 src="frame/box.html" style="border: 0; position: absolute; top: 0px; left: 0px;"></iframe>
-  <iframe width=220 height=220 src="frame/box.html" style="border: 0; position: absolute; top: 250px; left: 0px; transform: scale(1.5); transform-origin: left top;"></iframe>
+  <iframe width=220 height=220 src="frame/box2.html" style="border: 0; position: absolute; top: 250px; left: 0px; transform: scale(1.5); transform-origin: left top;"></iframe>
 </body>
 </html>
diff --git a/content/test/mock_widget_input_handler.cc b/content/test/mock_widget_input_handler.cc
index 67e15c3..d93d862 100644
--- a/content/test/mock_widget_input_handler.cc
+++ b/content/test/mock_widget_input_handler.cc
@@ -52,6 +52,11 @@
       std::make_unique<DispatchedMessage>("CursorVisibilityChanged"));
 }
 
+void MockWidgetInputHandler::FallbackCursorModeToggled(bool is_on) {
+  dispatched_messages_.emplace_back(
+      std::make_unique<DispatchedMessage>("FallbackCursorModeToggled"));
+}
+
 void MockWidgetInputHandler::ImeSetComposition(
     const base::string16& text,
     const std::vector<ui::ImeTextSpan>& ime_text_spans,
diff --git a/content/test/mock_widget_input_handler.h b/content/test/mock_widget_input_handler.h
index 43ef32c..509484b 100644
--- a/content/test/mock_widget_input_handler.h
+++ b/content/test/mock_widget_input_handler.h
@@ -197,6 +197,7 @@
   void SetEditCommandsForNextKeyEvent(
       const std::vector<content::EditCommand>& commands) override;
   void CursorVisibilityChanged(bool visible) override;
+  void FallbackCursorModeToggled(bool is_on) override;
   void ImeSetComposition(const base::string16& text,
                          const std::vector<ui::ImeTextSpan>& ime_text_spans,
                          const gfx::Range& range,
diff --git a/device/BUILD.gn b/device/BUILD.gn
index bf15377..9d6e114 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -218,6 +218,11 @@
     ]
   }
 
+  if (is_chromeos) {
+    sources += [ "bluetooth/chromeos/bluetooth_utils_unittest.cc" ]
+    deps += [ "//chromeos/constants" ]
+  }
+
   if ((is_chromeos || is_linux) && use_dbus) {
     configs += [ "//build/config/linux/dbus" ]
 
diff --git a/device/bluetooth/chromeos/bluetooth_utils.cc b/device/bluetooth/chromeos/bluetooth_utils.cc
index fcc6450..4d0dbc0b 100644
--- a/device/bluetooth/chromeos/bluetooth_utils.cc
+++ b/device/bluetooth/chromeos/bluetooth_utils.cc
@@ -4,7 +4,15 @@
 
 #include "device/bluetooth/chromeos/bluetooth_utils.h"
 
+#include <string>
+
 #include "base/feature_list.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/optional.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "device/base/features.h"
 
 namespace device {
@@ -17,6 +25,8 @@
 // https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-sdos.
 const char kSecurityKeyServiceUUID[] = "FFFD";
 
+const size_t kLongTermKeyHexStringLength = 32;
+
 // Get limited number of devices from |devices| and
 // prioritize paired/connecting devices over other devices.
 BluetoothAdapter::DeviceList GetLimitedNumDevices(
@@ -93,4 +103,29 @@
   return GetLimitedNumDevices(max_devices, filtered_devices);
 }
 
+std::vector<std::vector<uint8_t>> GetBlockedLongTermKeys() {
+  std::string blocklist = base::GetFieldTrialParamValueByFeature(
+      chromeos::features::kBlueZLongTermKeyBlocklist,
+      chromeos::features::kBlueZLongTermKeyBlocklistParamName);
+  std::vector<std::vector<uint8_t>> long_term_keys;
+  if (blocklist.empty())
+    return long_term_keys;
+
+  std::vector<std::string> hex_keys = base::SplitString(
+      blocklist, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+  for (const auto& hex_key : hex_keys) {
+    // Must be |kLongTermKeyHexStringLength| nibbles in length.
+    if (hex_key.length() != kLongTermKeyHexStringLength) {
+      LOG(WARNING) << "Incorrect Long Term Key length";
+      continue;
+    }
+
+    std::vector<uint8_t> bytes_key;
+    if (base::HexStringToBytes(hex_key, &bytes_key))
+      long_term_keys.push_back(std::move(bytes_key));
+  }
+
+  return long_term_keys;
+}
+
 }  // namespace device
diff --git a/device/bluetooth/chromeos/bluetooth_utils.h b/device/bluetooth/chromeos/bluetooth_utils.h
index cd1bece..32ab5c02 100644
--- a/device/bluetooth/chromeos/bluetooth_utils.h
+++ b/device/bluetooth/chromeos/bluetooth_utils.h
@@ -5,10 +5,12 @@
 #ifndef DEVICE_BLUETOOTH_CHROMEOS_BLUETOOTH_UTILS_H_
 #define DEVICE_BLUETOOTH_CHROMEOS_BLUETOOTH_UTILS_H_
 
+#include <vector>
+
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_export.h"
 
-// This file contains common utilities for filtering the bluetooth devices
+// This file contains common utilities, including filtering bluetooth devices
 // based on the filter criteria.
 namespace device {
 
@@ -26,6 +28,9 @@
                           BluetoothFilterType filter_type,
                           int max_devices);
 
+std::vector<std::vector<uint8_t>> DEVICE_BLUETOOTH_EXPORT
+GetBlockedLongTermKeys();
+
 }  // namespace device
 
 #endif  // DEVICE_BLUETOOTH_CHROMEOS_BLUETOOTH_UTILS_H_
diff --git a/device/bluetooth/chromeos/bluetooth_utils_unittest.cc b/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
new file mode 100644
index 0000000..fa143b2
--- /dev/null
+++ b/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
@@ -0,0 +1,110 @@
+// 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 "device/bluetooth/chromeos/bluetooth_utils.h"
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/test/scoped_feature_list.h"
+#include "chromeos/constants/chromeos_features.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace device {
+
+class BluetoothUtilsTest : public testing::Test {
+ protected:
+  BluetoothUtilsTest() = default;
+
+  void SetLongTermKeys(const std::string& keys) {
+    feature_list_.InitAndEnableFeatureWithParameters(
+        chromeos::features::kBlueZLongTermKeyBlocklist,
+        {{chromeos::features::kBlueZLongTermKeyBlocklistParamName, keys}});
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothUtilsTest);
+};
+
+TEST_F(BluetoothUtilsTest, TestListIncludesBadLtks) {
+  // One nibble too long, one nibble too short, and one nibble just right.
+  std::string hex_key_1 = "000000000000000000000000000012345";
+  std::string hex_key_2 = "0000000000000000000000000000123";
+  std::string hex_key_3 = "00000000000000000000000000001234";
+  SetLongTermKeys(hex_key_1 + ',' + hex_key_2 + ',' + hex_key_3);
+
+  std::vector<std::vector<uint8_t>> expected_array;
+  std::vector<uint8_t> expected_key = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                       0x00, 0x00, 0x12, 0x34};
+  expected_array.push_back(expected_key);
+
+  EXPECT_EQ(expected_array, device::GetBlockedLongTermKeys());
+}
+
+TEST_F(BluetoothUtilsTest, TestListIncludesNonHexInput) {
+  std::string hex_key_1 = "bad00input00but00correct00length";
+  std::string hex_key_2 = "00000000000000000000000000001234";
+  SetLongTermKeys(hex_key_1 + ',' + hex_key_2);
+
+  std::vector<std::vector<uint8_t>> expected_array;
+  std::vector<uint8_t> expected_key = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                       0x00, 0x00, 0x12, 0x34};
+  expected_array.push_back(expected_key);
+
+  EXPECT_EQ(expected_array, device::GetBlockedLongTermKeys());
+}
+
+TEST_F(BluetoothUtilsTest, TestEmptyList) {
+  SetLongTermKeys("");
+
+  std::vector<std::vector<uint8_t>> expected_array;
+
+  EXPECT_EQ(expected_array, device::GetBlockedLongTermKeys());
+}
+
+TEST_F(BluetoothUtilsTest, TestOneElementList) {
+  std::string hex_key_1 = "012300004567000089ab0000cdef0000";
+  std::vector<uint8_t> expected_key_1 = {0x01, 0x23, 0x00, 0x00, 0x45, 0x67,
+                                         0x00, 0x00, 0x89, 0xab, 0x00, 0x00,
+                                         0xcd, 0xef, 0x00, 0x00};
+
+  SetLongTermKeys(hex_key_1);
+
+  std::vector<std::vector<uint8_t>> expected_array;
+  expected_array.push_back(expected_key_1);
+
+  EXPECT_EQ(expected_array, device::GetBlockedLongTermKeys());
+}
+
+TEST_F(BluetoothUtilsTest, TestMultipleElementList) {
+  std::string hex_key_1 = "012300004567000089ab0000cdef0000";
+  std::vector<uint8_t> expected_key_1 = {0x01, 0x23, 0x00, 0x00, 0x45, 0x67,
+                                         0x00, 0x00, 0x89, 0xab, 0x00, 0x00,
+                                         0xcd, 0xef, 0x00, 0x00};
+
+  std::string hex_key_2 = "00001111222233334444555566667777";
+  std::vector<uint8_t> expected_key_2 = {0x00, 0x00, 0x11, 0x11, 0x22, 0x22,
+                                         0x33, 0x33, 0x44, 0x44, 0x55, 0x55,
+                                         0x66, 0x66, 0x77, 0x77};
+
+  std::string hex_key_3 = "88889999aaaabbbbccccddddeeeeffff";
+  std::vector<uint8_t> expected_key_3 = {0x88, 0x88, 0x99, 0x99, 0xaa, 0xaa,
+                                         0xbb, 0xbb, 0xcc, 0xcc, 0xdd, 0xdd,
+                                         0xee, 0xee, 0xff, 0xff};
+
+  SetLongTermKeys(hex_key_1 + ',' + hex_key_2 + ',' + hex_key_3);
+
+  std::vector<std::vector<uint8_t>> expected_array;
+  expected_array.push_back(expected_key_1);
+  expected_array.push_back(expected_key_2);
+  expected_array.push_back(expected_key_3);
+
+  EXPECT_EQ(expected_array, device::GetBlockedLongTermKeys());
+}
+
+}  // namespace device
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn
index 622463d..e5dd860c 100644
--- a/device/fido/BUILD.gn
+++ b/device/fido/BUILD.gn
@@ -143,6 +143,7 @@
   deps = [
     "//components/apdu",
     "//components/cbor",
+    "//components/device_event_log",
     "//crypto",
     "//device/base",
     "//device/fido/strings",
diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc
index 4533515e..27f51da12 100644
--- a/device/fido/get_assertion_request_handler.cc
+++ b/device/fido/get_assertion_request_handler.cc
@@ -13,6 +13,7 @@
 #include "base/bind.h"
 #include "base/feature_list.h"
 #include "base/stl_util.h"
+#include "components/device_event_log/device_event_log.h"
 #include "device/fido/authenticator_get_assertion_response.h"
 #include "device/fido/cable/fido_cable_discovery.h"
 #include "device/fido/features.h"
@@ -193,6 +194,7 @@
     discoveries().push_back(std::move(discovery));
   }
 
+  FIDO_LOG(EVENT) << "Starting GetAssertion flow";
   Start();
 }
 
@@ -202,8 +204,17 @@
     FidoAuthenticator* authenticator) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
 
-  if (state_ != State::kWaitingForTouch ||
-      !CheckUserVerificationCompatible(authenticator, request_, observer())) {
+  if (state_ != State::kWaitingForTouch) {
+    FIDO_LOG(DEBUG) << "Not dispatching request to "
+                    << authenticator->GetDisplayName()
+                    << " because no longer waiting for touch";
+    return;
+  }
+
+  if (!CheckUserVerificationCompatible(authenticator, request_, observer())) {
+    FIDO_LOG(DEBUG) << "Not dispatching request to "
+                    << authenticator->GetDisplayName()
+                    << " because authenticator is not UV-compatible";
     return;
   }
 
@@ -211,6 +222,9 @@
       authenticator->WillNeedPINToGetAssertion(request_)) {
     // A PIN will be needed. Just request a touch to let the user select this
     // authenticator if they wish.
+    FIDO_LOG(DEBUG) << "Asking for touch from "
+                    << authenticator->GetDisplayName()
+                    << " because a PIN will be required";
     authenticator->GetTouch(
         base::BindOnce(&GetAssertionRequestHandler::HandleTouch,
                        weak_factory_.GetWeakPtr(), authenticator));
@@ -230,6 +244,8 @@
     }
   }
 
+  FIDO_LOG(DEBUG) << "Asking for assertion from "
+                  << authenticator->GetDisplayName();
   authenticator->GetAssertion(
       std::move(request),
       base::BindOnce(&GetAssertionRequestHandler::HandleResponse,
@@ -263,6 +279,9 @@
 
   if (state_ != State::kWaitingForTouch &&
       state_ != State::kWaitingForSecondTouch) {
+    FIDO_LOG(DEBUG) << "Ignoring response from "
+                    << authenticator->GetDisplayName()
+                    << " because no longer waiting for touch";
     return;
   }
 
@@ -273,6 +292,9 @@
 
   state_ = State::kFinished;
   if (response_code != CtapDeviceResponseCode::kSuccess) {
+    FIDO_LOG(ERROR) << "Failing assertion request due to status "
+                    << static_cast<int>(response_code) << " from "
+                    << authenticator->GetDisplayName();
     OnAuthenticatorResponse(authenticator, response_code, base::nullopt);
     return;
   }
@@ -281,6 +303,8 @@
       !CheckResponseCredentialIdMatchesRequestAllowList(*authenticator,
                                                         request_, *response) ||
       !CheckRequirementsOnResponseUserEntity(request_, *response)) {
+    FIDO_LOG(ERROR) << "Failing assertion request due to bad response from "
+                    << authenticator->GetDisplayName();
     OnAuthenticatorResponse(
         authenticator, CtapDeviceResponseCode::kCtap2ErrOther, base::nullopt);
     return;
diff --git a/device/usb/public/cpp/BUILD.gn b/device/usb/public/cpp/BUILD.gn
index ea55d7cf8..ffe8852 100644
--- a/device/usb/public/cpp/BUILD.gn
+++ b/device/usb/public/cpp/BUILD.gn
@@ -24,6 +24,8 @@
     "fake_usb_device_info.h",
     "fake_usb_device_manager.cc",
     "fake_usb_device_manager.h",
+    "mock_usb_mojo_device.cc",
+    "mock_usb_mojo_device.h",
   ]
 
   deps = [
@@ -33,6 +35,7 @@
   public_deps = [
     "//base",
     "//device/usb/public/mojom",
+    "//testing/gmock",
     "//url:url",
   ]
 }
diff --git a/device/usb/public/cpp/fake_usb_device.cc b/device/usb/public/cpp/fake_usb_device.cc
index d14280fb..ba0c1b6 100644
--- a/device/usb/public/cpp/fake_usb_device.cc
+++ b/device/usb/public/cpp/fake_usb_device.cc
@@ -10,9 +10,11 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
+#include "device/usb/public/cpp/mock_usb_mojo_device.h"
 #include "device/usb/public/cpp/usb_utils.h"
 
 namespace device {
@@ -28,6 +30,7 @@
 
 FakeUsbDevice::~FakeUsbDevice() {
   CloseHandle();
+  observer_.RemoveAll();
 }
 
 FakeUsbDevice::FakeUsbDevice(scoped_refptr<FakeUsbDeviceInfo> device,
@@ -43,7 +46,17 @@
 }
 
 void FakeUsbDevice::CloseHandle() {
-  if (is_opened_ && client_)
+  if (!is_opened_) {
+    return;
+  }
+
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->Close(base::DoNothing::Once());
+    return;
+  }
+
+  if (client_)
     client_->OnDeviceClosed();
 
   is_opened_ = false;
@@ -51,6 +64,14 @@
 
 // Device implementation:
 void FakeUsbDevice::Open(OpenCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->Open(std::move(callback));
+    is_opened_ = true;
+    return;
+  }
+
   if (is_opened_) {
     std::move(callback).Run(mojom::UsbOpenDeviceError::ALREADY_OPEN);
     return;
@@ -64,17 +85,38 @@
 }
 
 void FakeUsbDevice::Close(CloseCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->Close(std::move(callback));
+    return;
+  }
+
   CloseHandle();
   std::move(callback).Run();
 }
 
 void FakeUsbDevice::SetConfiguration(uint8_t value,
                                      SetConfigurationCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->SetConfiguration(value, std::move(callback));
+    return;
+  }
+
   std::move(callback).Run(true);
 }
 
 void FakeUsbDevice::ClaimInterface(uint8_t interface_number,
                                    ClaimInterfaceCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->ClaimInterface(interface_number, std::move(callback));
+    return;
+  }
+
   bool success = claimed_interfaces_.insert(interface_number).second;
 
   std::move(callback).Run(success);
@@ -82,6 +124,13 @@
 
 void FakeUsbDevice::ReleaseInterface(uint8_t interface_number,
                                      ReleaseInterfaceCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->ReleaseInterface(interface_number, std::move(callback));
+    return;
+  }
+
   bool success = claimed_interfaces_.erase(interface_number) > 0;
 
   std::move(callback).Run(success);
@@ -91,14 +140,33 @@
     uint8_t interface_number,
     uint8_t alternate_setting,
     SetInterfaceAlternateSettingCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->SetInterfaceAlternateSetting(
+        interface_number, alternate_setting, std::move(callback));
+    return;
+  }
   std::move(callback).Run(true);
 }
 
 void FakeUsbDevice::Reset(ResetCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->Reset(std::move(callback));
+    return;
+  }
   std::move(callback).Run(true);
 }
 
 void FakeUsbDevice::ClearHalt(uint8_t endpoint, ClearHaltCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->ClearHalt(endpoint, std::move(callback));
+    return;
+  }
   std::move(callback).Run(true);
 }
 
@@ -106,6 +174,13 @@
                                       uint32_t length,
                                       uint32_t timeout,
                                       ControlTransferInCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->ControlTransferIn(std::move(params), length, timeout,
+                                   std::move(callback));
+    return;
+  }
   std::move(callback).Run(mojom::UsbTransferStatus::COMPLETED, {});
 }
 
@@ -114,6 +189,13 @@
     const std::vector<uint8_t>& data,
     uint32_t timeout,
     ControlTransferOutCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->ControlTransferOut(std::move(params), data, timeout,
+                                    std::move(callback));
+    return;
+  }
   std::move(callback).Run(mojom::UsbTransferStatus::COMPLETED);
 }
 
@@ -121,6 +203,13 @@
                                       uint32_t length,
                                       uint32_t timeout,
                                       GenericTransferInCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->GenericTransferIn(endpoint_number, length, timeout,
+                                   std::move(callback));
+    return;
+  }
   std::move(callback).Run(mojom::UsbTransferStatus::COMPLETED, {});
 }
 
@@ -128,6 +217,13 @@
                                        const std::vector<uint8_t>& data,
                                        uint32_t timeout,
                                        GenericTransferOutCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->GenericTransferOut(endpoint_number, data, timeout,
+                                    std::move(callback));
+    return;
+  }
   std::move(callback).Run(mojom::UsbTransferStatus::COMPLETED);
 }
 
@@ -136,6 +232,14 @@
     const std::vector<uint32_t>& packet_lengths,
     uint32_t timeout,
     IsochronousTransferInCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->IsochronousTransferIn(endpoint_number, packet_lengths, timeout,
+                                       std::move(callback));
+    return;
+  }
+
   std::move(callback).Run(
       {}, BuildIsochronousPacketArray(packet_lengths,
                                       mojom::UsbTransferStatus::COMPLETED));
@@ -147,6 +251,14 @@
     const std::vector<uint32_t>& packet_lengths,
     uint32_t timeout,
     IsochronousTransferOutCallback callback) {
+  // Go on with mock device for testing.
+  MockUsbMojoDevice* mock_device = device_->mock_device();
+  if (mock_device) {
+    mock_device->IsochronousTransferOut(endpoint_number, data, packet_lengths,
+                                        timeout, std::move(callback));
+    return;
+  }
+
   std::move(callback).Run(BuildIsochronousPacketArray(
       packet_lengths, mojom::UsbTransferStatus::COMPLETED));
 }
diff --git a/device/usb/public/cpp/fake_usb_device_info.h b/device/usb/public/cpp/fake_usb_device_info.h
index 34fceb7..c78af25 100644
--- a/device/usb/public/cpp/fake_usb_device_info.h
+++ b/device/usb/public/cpp/fake_usb_device_info.h
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "device/usb/public/cpp/mock_usb_mojo_device.h"
 #include "device/usb/public/mojom/device.mojom.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "url/gurl.h"
@@ -70,6 +71,8 @@
   const mojom::UsbDeviceInfo& GetDeviceInfo() { return device_info_; }
   void AddConfig(mojom::UsbConfigurationInfoPtr config);
   bool SetActiveConfig(uint8_t value);
+  void SetMockDevice(MockUsbMojoDevice* device) { mock_device_ = device; }
+  MockUsbMojoDevice* mock_device() const { return mock_device_; }
 
  protected:
   friend class RefCounted<FakeUsbDeviceInfo>;
@@ -79,6 +82,7 @@
   void SetDefault();
   mojom::UsbDeviceInfo device_info_;
   base::ObserverList<Observer> observer_list_;
+  MockUsbMojoDevice* mock_device_ = nullptr;
   DISALLOW_COPY_AND_ASSIGN(FakeUsbDeviceInfo);
 };
 
diff --git a/device/usb/public/cpp/fake_usb_device_manager.cc b/device/usb/public/cpp/fake_usb_device_manager.cc
index b88b504..3e147752 100644
--- a/device/usb/public/cpp/fake_usb_device_manager.cc
+++ b/device/usb/public/cpp/fake_usb_device_manager.cc
@@ -11,6 +11,7 @@
 #include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "device/usb/public/cpp/fake_usb_device.h"
+#include "device/usb/public/cpp/mock_usb_mojo_device.h"
 #include "device/usb/public/cpp/usb_utils.h"
 #include "device/usb/public/mojom/device_enumeration_options.mojom.h"
 #include "device/usb/public/mojom/device_manager_client.mojom.h"
@@ -103,6 +104,7 @@
     scoped_refptr<FakeUsbDeviceInfo> device) {
   DCHECK(device);
   DCHECK(base::ContainsKey(devices_, device->guid()));
+
   auto device_info = device->GetDeviceInfo().Clone();
   devices_.erase(device->guid());
 
@@ -117,7 +119,27 @@
 
 void FakeUsbDeviceManager::RemoveDevice(const std::string& guid) {
   DCHECK(ContainsKey(devices_, guid));
+
   RemoveDevice(devices_[guid]);
 }
 
+void FakeUsbDeviceManager::RemoveAllDevices() {
+  std::vector<scoped_refptr<FakeUsbDeviceInfo>> device_list;
+  for (const auto& pair : devices_) {
+    device_list.push_back(pair.second);
+  }
+  for (const auto& device : device_list) {
+    RemoveDevice(device);
+  }
+}
+
+bool FakeUsbDeviceManager::SetMockForDevice(const std::string& guid,
+                                            MockUsbMojoDevice* mock_device) {
+  if (!base::ContainsKey(devices_, guid))
+    return false;
+
+  devices_[guid]->SetMockDevice(mock_device);
+  return true;
+}
+
 }  // namespace device
diff --git a/device/usb/public/cpp/fake_usb_device_manager.h b/device/usb/public/cpp/fake_usb_device_manager.h
index b543678d..f88e8450 100644
--- a/device/usb/public/cpp/fake_usb_device_manager.h
+++ b/device/usb/public/cpp/fake_usb_device_manager.h
@@ -19,6 +19,8 @@
 
 namespace device {
 
+class MockUsbMojoDevice;
+
 // This class implements a fake USB device manager which will only be used in
 // tests for device::mojom::UsbDeviceManager's users.
 class FakeUsbDeviceManager : public mojom::UsbDeviceManager {
@@ -45,10 +47,15 @@
 
   void RemoveDevice(scoped_refptr<FakeUsbDeviceInfo> device);
 
+  bool SetMockForDevice(const std::string& guid,
+                        MockUsbMojoDevice* mock_device);
+
   bool IsBound() { return !bindings_.empty(); }
 
   void CloseAllBindings() { bindings_.CloseAllBindings(); }
 
+  void RemoveAllDevices();
+
  protected:
   DeviceMap& devices() { return devices_; }
 
diff --git a/device/usb/public/cpp/mock_usb_mojo_device.cc b/device/usb/public/cpp/mock_usb_mojo_device.cc
new file mode 100644
index 0000000..3a9ac13
--- /dev/null
+++ b/device/usb/public/cpp/mock_usb_mojo_device.cc
@@ -0,0 +1,50 @@
+// 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 "device/usb/public/cpp/mock_usb_mojo_device.h"
+
+#include <utility>
+
+namespace device {
+
+MockUsbMojoDevice::~MockUsbMojoDevice() {}
+
+MockUsbMojoDevice::MockUsbMojoDevice() {}
+
+void MockUsbMojoDevice::IsochronousTransferIn(
+    uint8_t endpoint_number,
+    const std::vector<uint32_t>& packet_lengths,
+    uint32_t timeout,
+    IsochronousTransferInCallback callback) {
+  std::vector<mojom::UsbIsochronousPacket> packets =
+      IsochronousTransferInInternal(endpoint_number, packet_lengths, timeout);
+  std::vector<mojom::UsbIsochronousPacketPtr> packet_ptrs;
+  size_t total_length = 0;
+  packet_ptrs.reserve(packets.size());
+  for (const auto& packet : packets) {
+    total_length += packet.length;
+    packet_ptrs.push_back(packet.Clone());
+  }
+  std::move(callback).Run(std::vector<uint8_t>(total_length),
+                          std::move(packet_ptrs));
+}
+
+void MockUsbMojoDevice::IsochronousTransferOut(
+    uint8_t endpoint_number,
+    const std::vector<uint8_t>& data,
+    const std::vector<uint32_t>& packet_lengths,
+    uint32_t timeout,
+    IsochronousTransferOutCallback callback) {
+  std::vector<mojom::UsbIsochronousPacket> packets =
+      IsochronousTransferOutInternal(endpoint_number, data, packet_lengths,
+                                     timeout);
+  std::vector<mojom::UsbIsochronousPacketPtr> packet_ptrs;
+  packet_ptrs.reserve(packets.size());
+  for (const auto& packet : packets) {
+    packet_ptrs.push_back(packet.Clone());
+  }
+  std::move(callback).Run(std::move(packet_ptrs));
+}
+
+}  // namespace device
diff --git a/device/usb/public/cpp/mock_usb_mojo_device.h b/device/usb/public/cpp/mock_usb_mojo_device.h
new file mode 100644
index 0000000..ff37436
--- /dev/null
+++ b/device/usb/public/cpp/mock_usb_mojo_device.h
@@ -0,0 +1,146 @@
+// 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 DEVICE_USB_PUBLIC_CPP_MOCK_USB_MOJO_DEVICE_H_
+#define DEVICE_USB_PUBLIC_CPP_MOCK_USB_MOJO_DEVICE_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "device/usb/public/mojom/device.mojom.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace device {
+
+// This class provides mock implementation for device::mojom::UsbDevice.
+// It should be used together with FakeUsbDeviceManager and
+// FakeUsbDeviceInfo just for testing.
+class MockUsbMojoDevice : public mojom::UsbDevice {
+ public:
+  MockUsbMojoDevice();
+  ~MockUsbMojoDevice() override;
+
+  // As current version of gmock in Chromium doesn't support move-only types,
+  // so it needs mock methods with OnceCallback pointer as parameter here.
+  void Open(OpenCallback callback) override { OpenInternal(&callback); }
+  MOCK_METHOD1(OpenInternal, void(OpenCallback*));
+
+  void Close(CloseCallback callback) override { CloseInternal(&callback); }
+  MOCK_METHOD1(CloseInternal, void(CloseCallback*));
+
+  void SetConfiguration(uint8_t value,
+                        SetConfigurationCallback callback) override {
+    SetConfigurationInternal(value, &callback);
+  }
+  MOCK_METHOD2(SetConfigurationInternal,
+               void(uint8_t, SetConfigurationCallback*));
+
+  void ClaimInterface(uint8_t interface_number,
+                      ClaimInterfaceCallback callback) override {
+    ClaimInterfaceInternal(interface_number, &callback);
+  }
+  MOCK_METHOD2(ClaimInterfaceInternal, void(uint8_t, ClaimInterfaceCallback*));
+
+  void ReleaseInterface(uint8_t interface_number,
+                        ReleaseInterfaceCallback callback) override {
+    ReleaseInterfaceInternal(interface_number, &callback);
+  }
+  MOCK_METHOD2(ReleaseInterfaceInternal,
+               void(uint8_t, ReleaseInterfaceCallback*));
+
+  void SetInterfaceAlternateSetting(
+      uint8_t interface_number,
+      uint8_t alternate_setting,
+      SetInterfaceAlternateSettingCallback callback) override {
+    SetInterfaceAlternateSettingInternal(interface_number, alternate_setting,
+                                         &callback);
+  }
+  MOCK_METHOD3(SetInterfaceAlternateSettingInternal,
+               void(uint8_t, uint8_t, SetInterfaceAlternateSettingCallback*));
+
+  void Reset(ResetCallback callback) override { ResetInternal(&callback); }
+  MOCK_METHOD1(ResetInternal, void(ResetCallback*));
+
+  void ClearHalt(uint8_t endpoint, ClearHaltCallback callback) override {
+    ClearHaltInternal(endpoint, &callback);
+  }
+  MOCK_METHOD2(ClearHaltInternal, void(uint8_t, ClearHaltCallback*));
+
+  void ControlTransferIn(mojom::UsbControlTransferParamsPtr params,
+                         uint32_t length,
+                         uint32_t timeout,
+                         ControlTransferInCallback callback) override {
+    ControlTransferInInternal(*params, length, timeout, &callback);
+  }
+  MOCK_METHOD4(ControlTransferInInternal,
+               void(const mojom::UsbControlTransferParams&,
+                    uint32_t,
+                    uint32_t,
+                    ControlTransferInCallback*));
+
+  void ControlTransferOut(mojom::UsbControlTransferParamsPtr params,
+                          const std::vector<uint8_t>& data,
+                          uint32_t timeout,
+                          ControlTransferOutCallback callback) override {
+    ControlTransferOutInternal(*params, data, timeout, &callback);
+  }
+  MOCK_METHOD4(ControlTransferOutInternal,
+               void(const mojom::UsbControlTransferParams&,
+                    const std::vector<uint8_t>&,
+                    uint32_t,
+                    ControlTransferOutCallback*));
+
+  void GenericTransferIn(uint8_t endpoint_number,
+                         uint32_t length,
+                         uint32_t timeout,
+                         GenericTransferInCallback callback) override {
+    GenericTransferInInternal(endpoint_number, length, timeout, &callback);
+  }
+  MOCK_METHOD4(GenericTransferInInternal,
+               void(uint8_t, uint32_t, uint32_t, GenericTransferInCallback*));
+
+  void GenericTransferOut(uint8_t endpoint_number,
+                          const std::vector<uint8_t>& data,
+                          uint32_t timeout,
+                          GenericTransferOutCallback callback) override {
+    GenericTransferOutInternal(endpoint_number, data, timeout, &callback);
+  }
+  MOCK_METHOD4(GenericTransferOutInternal,
+               void(uint8_t,
+                    const std::vector<uint8_t>&,
+                    uint32_t,
+                    GenericTransferOutCallback*));
+
+  void IsochronousTransferIn(uint8_t endpoint_number,
+                             const std::vector<uint32_t>& packet_lengths,
+                             uint32_t timeout,
+                             IsochronousTransferInCallback callback) override;
+  MOCK_METHOD3(
+      IsochronousTransferInInternal,
+      std::vector<mojom::UsbIsochronousPacket>(uint8_t,
+                                               const std::vector<uint32_t>&,
+                                               uint32_t));
+
+  void IsochronousTransferOut(uint8_t endpoint_number,
+                              const std::vector<uint8_t>& data,
+                              const std::vector<uint32_t>& packet_lengths,
+                              uint32_t timeout,
+                              IsochronousTransferOutCallback callback) override;
+  MOCK_METHOD4(
+      IsochronousTransferOutInternal,
+      std::vector<mojom::UsbIsochronousPacket>(uint8_t,
+                                               const std::vector<uint8_t>&,
+                                               const std::vector<uint32_t>&,
+                                               uint32_t));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockUsbMojoDevice);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_USB_PUBLIC_CPP_MOCK_USB_MOJO_DEVICE_H_
diff --git a/docs/win_cross.md b/docs/win_cross.md
index ef55dc3..ee8514e 100644
--- a/docs/win_cross.md
+++ b/docs/win_cross.md
@@ -80,7 +80,7 @@
 For now, one needs to use the rbe backend, not the (default) borg backend:
 
     goma_auth.py login
-    GOMA_STUBBY_PROXY_IP_ADDRESS=rbe-staging1.endpoints.cxx-compiler-service.cloud.goog GOMA_USE_CASE=rbe-staging goma_ctl.py ensure_start
+    GOMA_SERVER_HOST=rbe-staging1.endpoints.cxx-compiler-service.cloud.goog goma_ctl.py ensure_start
 
 ## Copying and running chrome
 
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc
index 5b02bd3d..357136e 100644
--- a/headless/lib/browser/headless_web_contents_impl.cc
+++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -77,13 +77,15 @@
       content::WebContents* web_contents,
       content::SecurityStyleExplanations* security_style_explanations)
       override {
-    security_state::SecurityInfo security_info;
-    security_state::GetSecurityInfo(
-        security_state::GetVisibleSecurityState(web_contents),
-        false /* used_policy_installed_certificate */,
-        base::Bind(&content::IsOriginSecure), &security_info);
-    return security_state::GetSecurityStyle(security_info,
-                                            security_style_explanations);
+    std::unique_ptr<security_state::VisibleSecurityState>
+        visible_security_state =
+            security_state::GetVisibleSecurityState(web_contents);
+    return security_state::GetSecurityStyle(
+        security_state::GetSecurityLevel(
+            *visible_security_state.get(),
+            false /* used_policy_installed_certificate */,
+            base::BindRepeating(&content::IsOriginSecure)),
+        *visible_security_state.get(), security_style_explanations);
   }
 #endif  // !defined(CHROME_MULTIPLE_DLL_CHILD)
 
diff --git a/ios/chrome/browser/ssl/ios_security_state_tab_helper.h b/ios/chrome/browser/ssl/ios_security_state_tab_helper.h
index 120e2901..ca82c54 100644
--- a/ios/chrome/browser/ssl/ios_security_state_tab_helper.h
+++ b/ios/chrome/browser/ssl/ios_security_state_tab_helper.h
@@ -23,7 +23,6 @@
  public:
   ~IOSSecurityStateTabHelper() override;
 
-  void GetSecurityInfo(security_state::SecurityInfo* result) const;
   security_state::SecurityLevel GetSecurityLevel() const;
   std::unique_ptr<security_state::VisibleSecurityState>
   GetVisibleSecurityState() const;
diff --git a/ios/chrome/browser/ssl/ios_security_state_tab_helper.mm b/ios/chrome/browser/ssl/ios_security_state_tab_helper.mm
index 6685d723..61d499a 100644
--- a/ios/chrome/browser/ssl/ios_security_state_tab_helper.mm
+++ b/ios/chrome/browser/ssl/ios_security_state_tab_helper.mm
@@ -28,20 +28,11 @@
 
 IOSSecurityStateTabHelper::~IOSSecurityStateTabHelper() {}
 
-void IOSSecurityStateTabHelper::GetSecurityInfo(
-    security_state::SecurityInfo* result) const {
-  security_state::GetSecurityInfo(GetVisibleSecurityState(),
-                                  false /* used policy installed certificate */,
-                                  base::Bind(&web::IsOriginSecure), result);
-}
-
 security_state::SecurityLevel IOSSecurityStateTabHelper::GetSecurityLevel()
     const {
-  security_state::SecurityInfo result;
-  security_state::GetSecurityInfo(
-      GetVisibleSecurityState(), false /* used policy installed certificate */,
-      base::BindRepeating(&web::IsOriginSecure), &result);
-  return result.security_level;
+  return security_state::GetSecurityLevel(
+      *GetVisibleSecurityState(), false /* used policy installed certificate */,
+      base::BindRepeating(&web::IsOriginSecure));
 }
 
 std::unique_ptr<security_state::VisibleSecurityState>
diff --git a/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm b/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm
index 2aa26351c..b7dcecd 100644
--- a/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm
+++ b/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm
@@ -80,9 +80,9 @@
   GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageSearch);
 
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_one_match_ptr->last_javascript_call());
+            frame_with_one_match_ptr->GetLastJavaScriptCall());
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_two_matches_ptr->last_javascript_call());
+            frame_with_two_matches_ptr->GetLastJavaScriptCall());
   ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
     base::RunLoop().RunUntilIdle();
     return fake_delegate_.state();
@@ -106,9 +106,9 @@
   GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageSearch);
 
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_null_result_ptr->last_javascript_call());
+            frame_with_null_result_ptr->GetLastJavaScriptCall());
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_one_match_ptr->last_javascript_call());
+            frame_with_one_match_ptr->GetLastJavaScriptCall());
   ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
     base::RunLoop().RunUntilIdle();
     return fake_delegate_.state();
@@ -131,9 +131,9 @@
   GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageSearch);
 
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_one_match_ptr->last_javascript_call());
+            frame_with_one_match_ptr->GetLastJavaScriptCall());
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_two_matches_ptr->last_javascript_call());
+            frame_with_two_matches_ptr->GetLastJavaScriptCall());
   test_web_state_->RemoveWebFrame(kOneMatchFrameId);
   GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageSearch);
   ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
@@ -154,7 +154,7 @@
   GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageSearch);
 
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_one_match_ptr->last_javascript_call());
+            frame_with_one_match_ptr->GetLastJavaScriptCall());
   test_web_state_ = nullptr;
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(fake_delegate_.state());
@@ -175,9 +175,9 @@
   GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageSearch);
 
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_one_match_ptr->last_javascript_call());
+            frame_with_one_match_ptr->GetLastJavaScriptCall());
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_two_matches_ptr->last_javascript_call());
+            frame_with_two_matches_ptr->GetLastJavaScriptCall());
   test_web_state_->RemoveWebFrame(kTwoMatchesFrameId);
   ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
     base::RunLoop().RunUntilIdle();
@@ -204,15 +204,15 @@
   GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageSearch);
 
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_one_match_ptr->last_javascript_call());
+            frame_with_one_match_ptr->GetLastJavaScriptCall());
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_two_matches_ptr->last_javascript_call());
+            frame_with_two_matches_ptr->GetLastJavaScriptCall());
   ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
     base::RunLoop().RunUntilIdle();
     return fake_delegate_.state();
   }));
   EXPECT_EQ("__gCrWeb.findInPage.pumpSearch(100.0);",
-            frame_with_two_matches_ptr->last_javascript_call());
+            frame_with_two_matches_ptr->GetLastJavaScriptCall());
   EXPECT_EQ(3, fake_delegate_.state()->match_count);
 }
 
@@ -227,7 +227,7 @@
   GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageSearch);
 
   EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);",
-            frame_with_one_match_ptr->last_javascript_call());
+            frame_with_one_match_ptr->GetLastJavaScriptCall());
   base::RunLoop().RunUntilIdle();
 }
 
diff --git a/ios/web/public/test/fakes/fake_web_frame.cc b/ios/web/public/test/fakes/fake_web_frame.cc
index eed124d..2aa9553 100644
--- a/ios/web/public/test/fakes/fake_web_frame.cc
+++ b/ios/web/public/test/fakes/fake_web_frame.cc
@@ -44,18 +44,19 @@
   if (!can_call_function_) {
     return false;
   }
-  last_javascript_call_ = std::string("__gCrWeb." + name + "(");
+  std::string javascript_call = std::string("__gCrWeb." + name + "(");
   bool first = true;
   for (auto& param : parameters) {
     if (!first) {
-      last_javascript_call_ += ", ";
+      javascript_call += ", ";
     }
     first = false;
     std::string paramString;
     base::JSONWriter::Write(param, &paramString);
-    last_javascript_call_ += paramString;
+    javascript_call += paramString;
   }
-  last_javascript_call_ += ");";
+  javascript_call += ");";
+  java_script_calls_.push_back(javascript_call);
   return can_call_function_;
 }
 
diff --git a/ios/web/public/test/fakes/fake_web_frame.h b/ios/web/public/test/fakes/fake_web_frame.h
index 9505fc1..43bfd74 100644
--- a/ios/web/public/test/fakes/fake_web_frame.h
+++ b/ios/web/public/test/fakes/fake_web_frame.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <memory>
+#include <vector>
 
 #include "ios/web/public/web_state/web_frame.h"
 
@@ -35,7 +36,16 @@
       const std::vector<base::Value>& parameters,
       base::OnceCallback<void(const base::Value*)> callback,
       base::TimeDelta timeout) override;
-  std::string last_javascript_call() { return last_javascript_call_; }
+
+  // Returns the most recent JavaScript handler call made to this frame.
+  std::string GetLastJavaScriptCall() const {
+    return java_script_calls_.size() == 0 ? "" : java_script_calls_.back();
+  }
+
+  // Returns |javascript_calls|. Use LastJavaScriptCall() if possible.
+  const std::vector<std::string>& GetJavaScriptCallHistory() {
+    return java_script_calls_;
+  }
 
   // Sets |js_result| that will be passed into callback for |name| function
   // call. The same result will be pass regardless of call arguments.
@@ -60,8 +70,9 @@
   bool is_main_frame_ = false;
   // The security origin associated with this frame.
   GURL security_origin_;
-  // The last Javascript script that was called, converted as a string.
-  std::string last_javascript_call_;
+  // Vector holding history of all javascript handler calls made in this frame.
+  // The calls are sorted with the most recent appended at the end.
+  std::vector<std::string> java_script_calls_;
   // The return value of CanCallJavaScriptFunction().
   bool can_call_function_ = true;
 };
diff --git a/media/blink/multibuffer_data_source_unittest.cc b/media/blink/multibuffer_data_source_unittest.cc
index 429bf96..02be5cee 100644
--- a/media/blink/multibuffer_data_source_unittest.cc
+++ b/media/blink/multibuffer_data_source_unittest.cc
@@ -520,7 +520,7 @@
   Initialize(kHttpUrl, true);
   EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length()));
   WebURLResponse response = response_generator_->Generate200();
-  response.SetHTTPHeaderField(WebString::FromUTF8("Accept-Ranges"),
+  response.SetHttpHeaderField(WebString::FromUTF8("Accept-Ranges"),
                               WebString::FromUTF8("bytes"));
   Respond(response);
 
@@ -1476,7 +1476,7 @@
   GURL gurl(kHttpUrl);
   blink::WebURLResponse response(gurl);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(
+  response.SetHttpHeaderField(
       WebString::FromUTF8("Content-Length"),
       WebString::FromUTF8(base::NumberToString(kDataSize / 2)));
   response.SetExpectedContentLength(kDataSize / 2);
@@ -1599,7 +1599,7 @@
   EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length()));
   WebURLResponse response = response_generator_->Generate206(0);
   const std::string etag("\"arglebargle glop-glyf?\"");
-  response.SetHTTPHeaderField(WebString::FromUTF8("Etag"),
+  response.SetHttpHeaderField(WebString::FromUTF8("Etag"),
                               WebString::FromUTF8(etag));
   Respond(response);
   EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize));
diff --git a/media/blink/resource_multibuffer_data_provider.cc b/media/blink/resource_multibuffer_data_provider.cc
index c455cdc..bad8f7cf 100644
--- a/media/blink/resource_multibuffer_data_provider.cc
+++ b/media/blink/resource_multibuffer_data_provider.cc
@@ -84,7 +84,7 @@
   request.SetRequestContext(is_client_audio_element_
                                 ? blink::mojom::RequestContextType::AUDIO
                                 : blink::mojom::RequestContextType::VIDEO);
-  request.SetHTTPHeaderField(
+  request.SetHttpHeaderField(
       WebString::FromUTF8(net::HttpRequestHeaders::kRange),
       WebString::FromUTF8(
           net::HttpByteRange::RightUnbounded(byte_pos()).GetHeaderValue()));
@@ -94,7 +94,7 @@
     // This lets the data reduction proxy know that we don't have anything
     // previously cached data for this resource. We can only send it if this is
     // the first request for this resource.
-    request.SetHTTPHeaderField(WebString::FromUTF8("chrome-proxy"),
+    request.SetHttpHeaderField(WebString::FromUTF8("chrome-proxy"),
                                WebString::FromUTF8("frfr"));
   }
 
@@ -105,7 +105,7 @@
   // along the way. See crbug/504194 and crbug/689989 for more information.
 
   // Disable compression, compression for audio/video doesn't make sense...
-  request.SetHTTPHeaderField(
+  request.SetHttpHeaderField(
       WebString::FromUTF8(net::HttpRequestHeaders::kAcceptEncoding),
       WebString::FromUTF8("identity;q=1, *;q=0"));
 
diff --git a/media/blink/resource_multibuffer_data_provider_unittest.cc b/media/blink/resource_multibuffer_data_provider_unittest.cc
index 917174b..6498038 100644
--- a/media/blink/resource_multibuffer_data_provider_unittest.cc
+++ b/media/blink/resource_multibuffer_data_provider_unittest.cc
@@ -107,7 +107,7 @@
 
   void FullResponse(int64_t instance_size, bool ok = true) {
     WebURLResponse response(gurl_);
-    response.SetHTTPHeaderField(
+    response.SetHttpHeaderField(
         WebString::FromUTF8("Content-Length"),
         WebString::FromUTF8(base::StringPrintf("%" PRId64, instance_size)));
     response.SetExpectedContentLength(instance_size);
@@ -133,7 +133,7 @@
                        bool chunked,
                        bool accept_ranges) {
     WebURLResponse response(gurl_);
-    response.SetHTTPHeaderField(
+    response.SetHttpHeaderField(
         WebString::FromUTF8("Content-Range"),
         WebString::FromUTF8(
             base::StringPrintf("bytes "
@@ -143,7 +143,7 @@
     // HTTP 1.1 doesn't permit Content-Length with Transfer-Encoding: chunked.
     int64_t content_length = -1;
     if (chunked) {
-      response.SetHTTPHeaderField(WebString::FromUTF8("Transfer-Encoding"),
+      response.SetHttpHeaderField(WebString::FromUTF8("Transfer-Encoding"),
                                   WebString::FromUTF8("chunked"));
     } else {
       content_length = last_position - first_position + 1;
@@ -152,7 +152,7 @@
 
     // A server isn't required to return Accept-Ranges even though it might.
     if (accept_ranges) {
-      response.SetHTTPHeaderField(WebString::FromUTF8("Accept-Ranges"),
+      response.SetHttpHeaderField(WebString::FromUTF8("Accept-Ranges"),
                                   WebString::FromUTF8("bytes"));
     }
 
@@ -302,7 +302,7 @@
   EXPECT_CALL(*this, RedirectCallback(scoped_refptr<UrlData>(nullptr)));
 
   WebURLResponse response(gurl_);
-  response.SetHTTPHeaderField(
+  response.SetHttpHeaderField(
       WebString::FromUTF8("Content-Range"),
       WebString::FromUTF8(base::StringPrintf("bytes "
                                              "%d-%d/%d",
diff --git a/media/blink/test_response_generator.cc b/media/blink/test_response_generator.cc
index 998bffe8..ec63901 100644
--- a/media/blink/test_response_generator.cc
+++ b/media/blink/test_response_generator.cc
@@ -29,7 +29,7 @@
   WebURLResponse response(gurl_);
   response.SetHttpStatusCode(200);
 
-  response.SetHTTPHeaderField(
+  response.SetHttpHeaderField(
       WebString::FromUTF8("Content-Length"),
       WebString::FromUTF8(base::NumberToString(content_length_)));
   response.SetExpectedContentLength(content_length_);
@@ -61,7 +61,7 @@
   response.SetHttpStatusCode(206);
 
   if ((flags & kNoAcceptRanges) == 0) {
-    response.SetHTTPHeaderField(WebString::FromUTF8("Accept-Ranges"),
+    response.SetHttpHeaderField(WebString::FromUTF8("Accept-Ranges"),
                                 WebString::FromUTF8("bytes"));
   }
 
@@ -73,12 +73,12 @@
       content_range += "*";
     else
       content_range += base::StringPrintf("%" PRId64, content_length_);
-    response.SetHTTPHeaderField(WebString::FromUTF8("Content-Range"),
+    response.SetHttpHeaderField(WebString::FromUTF8("Content-Range"),
                                 WebString::FromUTF8(content_range));
   }
 
   if ((flags & kNoContentLength) == 0) {
-    response.SetHTTPHeaderField(
+    response.SetHttpHeaderField(
         WebString::FromUTF8("Content-Length"),
         WebString::FromUTF8(base::NumberToString(range_content_length)));
     response.SetExpectedContentLength(range_content_length);
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc
index d5daff5..58a2afc 100644
--- a/media/blink/webmediaplayer_impl_unittest.cc
+++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -591,7 +591,7 @@
     // "Serve" the file to the DataSource. Note: We respond with 200 okay, which
     // will prevent range requests or partial responses from being used.
     blink::WebURLResponse response(kTestURL);
-    response.SetHTTPHeaderField(
+    response.SetHttpHeaderField(
         blink::WebString::FromUTF8("Content-Length"),
         blink::WebString::FromUTF8(base::NumberToString(data->data_size())));
     response.SetExpectedContentLength(data->data_size());
diff --git a/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc b/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
index dba8c9a..c849685 100644
--- a/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
+++ b/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
@@ -367,12 +367,10 @@
 void CameraHalDispatcherImpl::OnCameraHalClientConnectionError(
     CameraClientObserver* client_observer) {
   DCHECK(proxy_task_runner_->BelongsToCurrentThread());
-  for (auto& it : client_observers_) {
-    if (it.get() == client_observer) {
-      client_observers_.erase(it);
-      VLOG(1) << "Camera HAL client connection lost";
-      break;
-    }
+  auto it = client_observers_.find(client_observer);
+  if (it != client_observers_.end()) {
+    client_observers_.erase(it);
+    VLOG(1) << "Camera HAL client connection lost";
   }
 }
 
diff --git a/media/capture/video/chromeos/camera_hal_dispatcher_impl.h b/media/capture/video/chromeos/camera_hal_dispatcher_impl.h
index 02cd8fa..6e71a89 100644
--- a/media/capture/video/chromeos/camera_hal_dispatcher_impl.h
+++ b/media/capture/video/chromeos/camera_hal_dispatcher_impl.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <set>
 
+#include "base/containers/unique_ptr_adapters.h"
 #include "base/files/scoped_file.h"
 #include "base/memory/singleton.h"
 #include "base/threading/thread.h"
@@ -115,7 +116,8 @@
 
   cros::mojom::CameraHalServerPtr camera_hal_server_;
 
-  std::set<std::unique_ptr<CameraClientObserver>> client_observers_;
+  std::set<std::unique_ptr<CameraClientObserver>, base::UniquePtrComparator>
+      client_observers_;
 
   MojoJpegDecodeAcceleratorFactoryCB jda_factory_;
 
diff --git a/media/gpu/image_processor.cc b/media/gpu/image_processor.cc
index 85418c5..f6da2f15 100644
--- a/media/gpu/image_processor.cc
+++ b/media/gpu/image_processor.cc
@@ -31,18 +31,18 @@
 
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
 bool ImageProcessor::Process(scoped_refptr<VideoFrame> frame,
-                             int output_buffer_index,
-                             std::vector<base::ScopedFD> output_dmabuf_fds,
                              LegacyFrameReadyCB cb) {
-  return ProcessInternal(std::move(frame), output_buffer_index,
-                         std::move(output_dmabuf_fds),
-                         BindToCurrentLoop(std::move(cb)));
+  DCHECK_EQ(output_mode(), OutputMode::ALLOCATE);
+
+  return ProcessInternal(std::move(frame), BindToCurrentLoop(std::move(cb)));
 }
 #endif
 
 bool ImageProcessor::Process(scoped_refptr<VideoFrame> input_frame,
                              scoped_refptr<VideoFrame> output_frame,
                              FrameReadyCB cb) {
+  DCHECK_EQ(output_mode(), OutputMode::IMPORT);
+
   return ProcessInternal(std::move(input_frame), std::move(output_frame),
                          BindToCurrentLoop(std::move(cb)));
 }
diff --git a/media/gpu/image_processor.h b/media/gpu/image_processor.h
index 4727bb94..d7b35eba 100644
--- a/media/gpu/image_processor.h
+++ b/media/gpu/image_processor.h
@@ -105,12 +105,9 @@
 
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
   // Called by client to process |frame|. The resulting processed frame will be
-  // stored in |output_buffer_index| output buffer and notified via |cb|. The
+  // stored in a ImageProcessor-owned output buffer and notified via |cb|. The
   // processor will drop all its references to |frame| after it finishes
-  // accessing it. If the input buffers are DMA-backed, the caller
-  // should pass non-empty |output_dmabuf_fds| and the processed frame will be
-  // stored in those buffers. If the number of |output_dmabuf_fds| is not
-  // expected, this function will return false.
+  // accessing it.
   // Process() must be called on "client thread". This should not be blocking
   // function.
   //
@@ -120,8 +117,6 @@
   // TODO(crbug.com/907767): Remove this once ImageProcessor always works as
   // IMPORT mode for output.
   bool Process(scoped_refptr<VideoFrame> frame,
-               int output_buffer_index,
-               std::vector<base::ScopedFD> output_dmabuf_fds,
                LegacyFrameReadyCB cb);
 #endif
 
@@ -165,8 +160,6 @@
   // "client thread".
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
   virtual bool ProcessInternal(scoped_refptr<VideoFrame> frame,
-                               int output_buffer_index,
-                               std::vector<base::ScopedFD> output_dmabuf_fds,
                                LegacyFrameReadyCB cb) = 0;
 #endif
   virtual bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
diff --git a/media/gpu/libyuv_image_processor.cc b/media/gpu/libyuv_image_processor.cc
index 6d663ff0..2f826f10 100644
--- a/media/gpu/libyuv_image_processor.cc
+++ b/media/gpu/libyuv_image_processor.cc
@@ -20,13 +20,12 @@
     const VideoFrameLayout& output_layout,
     const gfx::Size& output_visible_size,
     VideoFrame::StorageType output_storage_type,
-    OutputMode output_mode,
     ErrorCB error_cb)
     : ImageProcessor(input_layout,
                      input_storage_type,
                      output_layout,
                      output_storage_type,
-                     output_mode),
+                     OutputMode::IMPORT),
       input_visible_rect_(input_visible_size),
       output_visible_rect_(output_visible_size),
       error_cb_(error_cb),
@@ -88,7 +87,7 @@
   auto processor = base::WrapUnique(new LibYUVImageProcessor(
       input_config.layout, input_config.visible_size, input_storage_type,
       output_config.layout, output_config.visible_size, output_storage_type,
-      output_mode, media::BindToCurrentLoop(std::move(error_cb))));
+      media::BindToCurrentLoop(std::move(error_cb))));
   if (!processor->process_thread_.Start()) {
     VLOGF(1) << "Failed to start processing thread";
     return nullptr;
@@ -102,8 +101,6 @@
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
 bool LibYUVImageProcessor::ProcessInternal(
     scoped_refptr<VideoFrame> frame,
-    int output_buffer_index,
-    std::vector<base::ScopedFD> output_dmabuf_fds,
     LegacyFrameReadyCB cb) {
   DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
   NOTIMPLEMENTED();
diff --git a/media/gpu/libyuv_image_processor.h b/media/gpu/libyuv_image_processor.h
index 1780fc62..eec9a8b9 100644
--- a/media/gpu/libyuv_image_processor.h
+++ b/media/gpu/libyuv_image_processor.h
@@ -53,14 +53,11 @@
                        const VideoFrameLayout& output_layout,
                        const gfx::Size& output_visible_size,
                        VideoFrame::StorageType output_storage_type,
-                       OutputMode output_mode,
                        ErrorCB error_cb);
 
   // ImageProcessor override
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
   bool ProcessInternal(scoped_refptr<VideoFrame> frame,
-                       int output_buffer_index,
-                       std::vector<base::ScopedFD> output_dmabuf_fds,
                        LegacyFrameReadyCB cb) override;
 #endif
   bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc
index 9cd3e2b8..f8bd3bf5 100644
--- a/media/gpu/v4l2/v4l2_image_processor.cc
+++ b/media/gpu/v4l2/v4l2_image_processor.cc
@@ -369,8 +369,6 @@
 
 bool V4L2ImageProcessor::ProcessInternal(
     scoped_refptr<VideoFrame> frame,
-    int output_buffer_index,
-    std::vector<base::ScopedFD> output_dmabuf_fds,
     LegacyFrameReadyCB cb) {
   DVLOGF(4) << "ts=" << frame->timestamp().InMilliseconds();
 
@@ -378,24 +376,8 @@
   job_record->input_frame = frame;
   job_record->legacy_ready_cb = std::move(cb);
 
-  switch (output_memory_type_) {
-    case V4L2_MEMORY_MMAP:
-      if (!output_dmabuf_fds.empty()) {
-        VLOGF(1) << "output_dmabuf_fds must be empty for MMAP output mode";
-        return false;
-      }
-      break;
-
-    case V4L2_MEMORY_DMABUF:
-      job_record->output_frame = VideoFrame::WrapExternalDmabufs(
-          output_layout_, gfx::Rect(output_visible_size_), output_visible_size_,
-          std::move(output_dmabuf_fds), job_record->input_frame->timestamp());
-      job_record->output_buffer_index = output_buffer_index;
-      break;
-
-    default:
-      NOTREACHED();
-      return false;
+  if (output_memory_type_ != V4L2_MEMORY_MMAP) {
+    NOTREACHED();
   }
 
   // Since device_thread_ is owned by this class. base::Unretained(this) and the
@@ -410,8 +392,18 @@
 bool V4L2ImageProcessor::ProcessInternal(scoped_refptr<VideoFrame> input_frame,
                                          scoped_refptr<VideoFrame> output_frame,
                                          FrameReadyCB cb) {
-  NOTIMPLEMENTED();
-  return false;
+  DVLOGF(4) << "ts=" << input_frame->timestamp().InMilliseconds();
+
+  auto job_record = std::make_unique<JobRecord>();
+  job_record->input_frame = std::move(input_frame);
+  job_record->output_frame = std::move(output_frame);
+  job_record->ready_cb = std::move(cb);
+
+  process_task_tracker_.PostTask(
+      device_thread_.task_runner().get(), FROM_HERE,
+      base::BindOnce(&V4L2ImageProcessor::ProcessTask, base::Unretained(this),
+                     std::move(job_record)));
+  return true;
 }
 
 void V4L2ImageProcessor::ProcessTask(std::unique_ptr<JobRecord> job_record) {
@@ -735,8 +727,6 @@
     std::unique_ptr<JobRecord> job_record = std::move(running_jobs_.front());
     running_jobs_.pop();
 
-    int output_index;
-
     scoped_refptr<VideoFrame> output_frame;
     switch (output_memory_type_) {
       case V4L2_MEMORY_MMAP:
@@ -746,7 +736,6 @@
         output_frame = VideoFrame::WrapVideoFrame(
             output_frame, output_frame->format(), output_frame->visible_rect(),
             output_frame->natural_size());
-        output_index = buffer->BufferId();
         output_frame->AddDestructionObserver(BindToCurrentLoop(
             base::BindOnce(&V4L2ImageProcessor::V4L2VFDestructionObserver,
                            weak_this_factory_.GetWeakPtr(), buffer)));
@@ -754,7 +743,6 @@
 
       case V4L2_MEMORY_DMABUF:
         output_frame = std::move(job_record->output_frame);
-        output_index = job_record->output_buffer_index;
         break;
 
       default:
@@ -766,7 +754,7 @@
 
     if (!job_record->legacy_ready_cb.is_null()) {
       std::move(job_record->legacy_ready_cb)
-          .Run(output_index, std::move(output_frame));
+          .Run(buffer->BufferId(), std::move(output_frame));
     } else {
       std::move(job_record->ready_cb).Run(std::move(output_frame));
     }
diff --git a/media/gpu/v4l2/v4l2_image_processor.h b/media/gpu/v4l2/v4l2_image_processor.h
index c2f0753..193e7fe 100644
--- a/media/gpu/v4l2/v4l2_image_processor.h
+++ b/media/gpu/v4l2/v4l2_image_processor.h
@@ -84,7 +84,6 @@
     JobRecord();
     ~JobRecord();
     scoped_refptr<VideoFrame> input_frame;
-    int output_buffer_index = -1;
     FrameReadyCB ready_cb;
     LegacyFrameReadyCB legacy_ready_cb;
     scoped_refptr<VideoFrame> output_frame;
@@ -118,8 +117,6 @@
 
   // ImageProcessor implementation.
   bool ProcessInternal(scoped_refptr<VideoFrame> frame,
-                       int output_buffer_index,
-                       std::vector<base::ScopedFD> output_dmabuf_fds,
                        LegacyFrameReadyCB cb) override;
   bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
                        scoped_refptr<VideoFrame> output_frame,
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
index 98cd9cb3..a6cf685 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -691,8 +691,19 @@
 
   if (output_mode_ == Config::OutputMode::IMPORT) {
     DCHECK_EQ(egl_image_planes_count_, dmabuf_fds.size());
-    DCHECK(iter->output_fds.empty());
-    iter->output_fds = DuplicateFDs(dmabuf_fds);
+    DCHECK(!iter->output_frame);
+
+    auto layout = VideoFrameLayout::Create(
+        V4L2Device::V4L2PixFmtToVideoPixelFormat(output_format_fourcc_),
+        coded_size_);
+    if (!layout) {
+      VLOGF(1) << "Cannot create layout!";
+      NOTIFY_ERROR(INVALID_ARGUMENT);
+      return;
+    }
+    iter->output_frame = VideoFrame::WrapExternalDmabufs(
+        *layout, gfx::Rect(visible_size_), visible_size_,
+        DuplicateFDs(dmabuf_fds), base::TimeDelta());
   }
 
   if (iter->texture_id != 0) {
@@ -1588,10 +1599,12 @@
     case V4L2_MEMORY_MMAP:
       ret = std::move(buffer).QueueMMap();
       break;
-    case V4L2_MEMORY_DMABUF:
-      DCHECK_EQ(output_planes_count_, output_record.output_fds.size());
-      ret = std::move(buffer).QueueDMABuf(output_record.output_fds);
+    case V4L2_MEMORY_DMABUF: {
+      const auto& fds = output_record.output_frame->DmabufFds();
+      DCHECK_EQ(output_planes_count_, fds.size());
+      ret = std::move(buffer).QueueDMABuf(fds);
       break;
+    }
     default:
       NOTREACHED();
   }
@@ -2493,23 +2506,24 @@
     return false;
   }
 
-  std::vector<base::ScopedFD> output_fds;
-  if (output_mode_ == Config::OutputMode::IMPORT) {
-    output_fds = DuplicateFDs(output_record.output_fds);
-    if (output_fds.empty())
-      return false;
-  }
-
   // Keep reference to the IP input until the frame is processed
   buffers_at_ip_.push(std::make_pair(bitstream_buffer_id, buf));
 
   // Unretained(this) is safe for FrameReadyCB because |decoder_thread_| is
   // owned by this V4L2VideoDecodeAccelerator and |this| must be valid when
   // FrameReadyCB is executed.
-  image_processor_->Process(
-      input_frame, buf->BufferId(), std::move(output_fds),
-      base::BindOnce(&V4L2VideoDecodeAccelerator::FrameProcessed,
-                     base::Unretained(this), bitstream_buffer_id));
+  if (image_processor_->output_mode() == ImageProcessor::OutputMode::IMPORT) {
+    image_processor_->Process(
+        input_frame, output_record.output_frame,
+        base::BindOnce(&V4L2VideoDecodeAccelerator::FrameProcessed,
+                       base::Unretained(this), bitstream_buffer_id,
+                       buf->BufferId()));
+  } else {
+    image_processor_->Process(
+        input_frame,
+        base::BindOnce(&V4L2VideoDecodeAccelerator::FrameProcessed,
+                       base::Unretained(this), bitstream_buffer_id));
+  }
   return true;
 }
 
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
index a7ad43e3..53b923f 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.h
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
@@ -193,8 +193,8 @@
     GLuint texture_id;
     bool cleared;           // Whether the texture is cleared and safe to render
                             // from. See TextureManager for details.
-    // Output fds. Used only when OutputMode is IMPORT.
-    std::vector<base::ScopedFD> output_fds;
+    // Output frame. Used only when OutputMode is IMPORT.
+    scoped_refptr<VideoFrame> output_frame;
   };
 
   //
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
index 722254a9..5b888d7 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -397,10 +397,9 @@
         // We have to bind |weak_this| for FrameProcessed, because child
         // thread is outlive this V4L2VideoEncodeAccelerator.
         if (!image_processor_->Process(
-                frame, output_buffer_index, std::vector<base::ScopedFD>(),
-                base::BindOnce(&V4L2VideoEncodeAccelerator::FrameProcessed,
-                               weak_this_, force_keyframe,
-                               frame->timestamp()))) {
+                frame, base::BindOnce(
+                           &V4L2VideoEncodeAccelerator::FrameProcessed,
+                           weak_this_, force_keyframe, frame->timestamp()))) {
           NOTIFY_ERROR(kPlatformFailureError);
         }
       }
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index f93240d..50b61aa 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -239,12 +239,12 @@
                       std::set<std::string> filter_domains,
                       std::set<url::Origin> filter_origins,
                       const GURL& url) {
-  std::string url_registerable_domain =
+  std::string url_registrable_domain =
       net::registry_controlled_domains::GetDomainAndRegistry(
           url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
   bool found_domain =
-      (filter_domains.find(url_registerable_domain != ""
-                               ? url_registerable_domain
+      (filter_domains.find(url_registrable_domain != ""
+                               ? url_registrable_domain
                                : url.host()) != filter_domains.end());
 
   bool found_origin =
diff --git a/services/network/public/cpp/cors/origin_access_entry.cc b/services/network/public/cpp/cors/origin_access_entry.cc
index b9eb5fac..6eb6ed2 100644
--- a/services/network/public/cpp/cors/origin_access_entry.cc
+++ b/services/network/public/cpp/cors/origin_access_entry.cc
@@ -58,16 +58,16 @@
   if (host_.length() <= public_suffix_length + 1) {
     host_is_public_suffix_ = true;
   } else if (mode_ ==
-                 mojom::CorsOriginAccessMatchMode::kAllowRegisterableDomains &&
+                 mojom::CorsOriginAccessMatchMode::kAllowRegistrableDomains &&
              public_suffix_length) {
     // The "2" in the next line is 1 for the '.', plus a 1-char minimum label
     // length.
     const size_t dot =
         host_.rfind('.', host_.length() - public_suffix_length - 2);
     if (dot == std::string::npos)
-      registerable_domain_ = host_;
+      registrable_domain_ = host_;
     else
-      registerable_domain_ = host_.substr(dot + 1);
+      registrable_domain_ = host_.substr(dot + 1);
   }
 }
 
@@ -107,14 +107,14 @@
         return kDoesNotMatchOrigin;
       break;
 
-    case mojom::CorsOriginAccessMatchMode::kAllowRegisterableDomains:
-      // Fall back to a simple subdomain check if no registerable domain could
+    case mojom::CorsOriginAccessMatchMode::kAllowRegistrableDomains:
+      // Fall back to a simple subdomain check if no registrable domain could
       // be found:
-      if (registerable_domain_.empty()) {
+      if (registrable_domain_.empty()) {
         if (!IsSubdomainOfHost(origin.host(), host_))
           return kDoesNotMatchOrigin;
-      } else if (registerable_domain_ != origin.host() &&
-                 !IsSubdomainOfHost(origin.host(), registerable_domain_)) {
+      } else if (registrable_domain_ != origin.host() &&
+                 !IsSubdomainOfHost(origin.host(), registrable_domain_)) {
         return kDoesNotMatchOrigin;
       }
       break;
diff --git a/services/network/public/cpp/cors/origin_access_entry.h b/services/network/public/cpp/cors/origin_access_entry.h
index f49838d6..8e69c826 100644
--- a/services/network/public/cpp/cors/origin_access_entry.h
+++ b/services/network/public/cpp/cors/origin_access_entry.h
@@ -55,9 +55,7 @@
 
   bool host_is_ip_address() const { return host_is_ip_address_; }
   mojom::CorsOriginAccessMatchPriority priority() const { return priority_; }
-  const std::string& registerable_domain() const {
-    return registerable_domain_;
-  }
+  const std::string& registrable_domain() const { return registrable_domain_; }
 
   // Creates mojom::CorsOriginPattern instance that represents |this|
   // OriginAccessEntry instance.
@@ -71,7 +69,7 @@
   const mojom::CorsOriginAccessMatchPriority priority_;
   const bool host_is_ip_address_;
 
-  std::string registerable_domain_;
+  std::string registrable_domain_;
   bool host_is_public_suffix_;
 
   DISALLOW_COPY_AND_ASSIGN(OriginAccessEntry);
diff --git a/services/network/public/cpp/cors/origin_access_entry_unittest.cc b/services/network/public/cpp/cors/origin_access_entry_unittest.cc
index 1f086e0..f9073af 100644
--- a/services/network/public/cpp/cors/origin_access_entry_unittest.cc
+++ b/services/network/public/cpp/cors/origin_access_entry_unittest.cc
@@ -100,7 +100,7 @@
   }
 }
 
-TEST(OriginAccessEntryTest, AllowRegisterableDomainsTest) {
+TEST(OriginAccessEntryTest, AllowRegistrableDomainsTest) {
   struct TestCase {
     const std::string protocol;
     const std::string host;
@@ -143,17 +143,17 @@
     url::Origin origin_to_test = url::Origin::Create(GURL(test.origin));
     OriginAccessEntry entry1(
         test.protocol, test.host,
-        mojom::CorsOriginAccessMatchMode::kAllowRegisterableDomains,
+        mojom::CorsOriginAccessMatchMode::kAllowRegistrableDomains,
         mojom::CorsOriginAccessMatchPriority::kDefaultPriority);
 
     SCOPED_TRACE(testing::Message()
                  << "Host: " << test.host << ", Origin: " << test.origin
-                 << ", Domain: " << entry1.registerable_domain());
+                 << ", Domain: " << entry1.registrable_domain());
     EXPECT_EQ(test.expected, entry1.MatchesOrigin(origin_to_test));
   }
 }
 
-TEST(OriginAccessEntryTest, AllowRegisterableDomainsTestWithDottedSuffix) {
+TEST(OriginAccessEntryTest, AllowRegistrableDomainsTestWithDottedSuffix) {
   struct TestCase {
     const std::string protocol;
     const std::string host;
@@ -197,12 +197,12 @@
     url::Origin origin_to_test = url::Origin::Create(GURL(test.origin));
     OriginAccessEntry entry1(
         test.protocol, test.host,
-        mojom::CorsOriginAccessMatchMode::kAllowRegisterableDomains,
+        mojom::CorsOriginAccessMatchMode::kAllowRegistrableDomains,
         mojom::CorsOriginAccessMatchPriority::kDefaultPriority);
 
     SCOPED_TRACE(testing::Message()
                  << "Host: " << test.host << ", Origin: " << test.origin
-                 << ", Domain: " << entry1.registerable_domain());
+                 << ", Domain: " << entry1.registrable_domain());
     EXPECT_EQ(test.expected, entry1.MatchesOrigin(origin_to_test));
   }
 }
diff --git a/services/network/public/mojom/cors_origin_pattern.mojom b/services/network/public/mojom/cors_origin_pattern.mojom
index 787a589..f49aa0a 100644
--- a/services/network/public/mojom/cors_origin_pattern.mojom
+++ b/services/network/public/mojom/cors_origin_pattern.mojom
@@ -5,13 +5,13 @@
 module network.mojom;
 
 // An enum to represent a mode if matching functions can accept a partial match
-// for sub-domains, or for registerable domains.
+// for sub-domains, or for registrable domains.
 enum CorsOriginAccessMatchMode {
   // 'www.example.com' matches an OriginAccessEntry for 'example.com'
   kAllowSubdomains,
 
   // 'www.example.com' matches an OriginAccessEntry for 'not-www.example.com'
-  kAllowRegisterableDomains,
+  kAllowRegistrableDomains,
 
   // 'www.example.com' does not match an OriginAccessEntry for 'example.com'
   kDisallowSubdomains,
diff --git a/sql/OWNERS b/sql/OWNERS
index b542429..279a3cf4 100644
--- a/sql/OWNERS
+++ b/sql/OWNERS
@@ -2,7 +2,7 @@
 pwnall@chromium.org
 
 # Secondary:
-cmumford@chromium.org
+cmumford@google.com
 
 # TEAM: storage-dev@chromium.org
 # COMPONENT: Internals>Storage
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index 5364917..0ae5231 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -657,7 +657,6 @@
       [ "//third_party/blink/renderer/platform:blink_platform_public_deps" ]
   sources = [
     "platform/modules/bluetooth/web_bluetooth.mojom",
-    "platform/modules/notifications/notification_service.mojom",
   ]
   public_deps = [
     ":android_mojo_bindings",
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn
index 7862a04..31d2bda5 100644
--- a/third_party/blink/public/mojom/BUILD.gn
+++ b/third_party/blink/public/mojom/BUILD.gn
@@ -72,6 +72,7 @@
     "mime/mime_registry.mojom",
     "net/ip_address_space.mojom",
     "notifications/notification.mojom",
+    "notifications/notification_service.mojom",
     "oom_intervention/oom_intervention.mojom",
     "page/display_cutout.mojom",
     "payments/payment_app.mojom",
diff --git a/third_party/blink/public/platform/modules/notifications/notification_service.mojom b/third_party/blink/public/mojom/notifications/notification_service.mojom
similarity index 100%
rename from third_party/blink/public/platform/modules/notifications/notification_service.mojom
rename to third_party/blink/public/mojom/notifications/notification_service.mojom
diff --git a/third_party/blink/public/platform/modules/notifications/OWNERS b/third_party/blink/public/platform/modules/notifications/OWNERS
index a6e3ece..2fd0e4b 100644
--- a/third_party/blink/public/platform/modules/notifications/OWNERS
+++ b/third_party/blink/public/platform/modules/notifications/OWNERS
@@ -1,10 +1,4 @@
 peter@chromium.org
 
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
-
-per-file *.typemap=set noparent
-per-file *.typemap=file://ipc/SECURITY_OWNERS
-
 # TEAM: platform-capabilities@chromium.org
 # COMPONENT: UI>Notifications
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h
index 8addc01..9c4cf14 100644
--- a/third_party/blink/public/platform/web_url_request.h
+++ b/third_party/blink/public/platform/web_url_request.h
@@ -153,7 +153,7 @@
   BLINK_PLATFORM_EXPORT WebString HttpHeaderField(const WebString& name) const;
   // It's not possible to set the referrer header using this method. Use
   // SetHTTPReferrer instead.
-  BLINK_PLATFORM_EXPORT void SetHTTPHeaderField(const WebString& name,
+  BLINK_PLATFORM_EXPORT void SetHttpHeaderField(const WebString& name,
                                                 const WebString& value);
   BLINK_PLATFORM_EXPORT void SetHTTPReferrer(const WebString& referrer,
                                              network::mojom::ReferrerPolicy);
diff --git a/third_party/blink/public/platform/web_url_response.h b/third_party/blink/public/platform/web_url_response.h
index 9128a2b..bb77f0b 100644
--- a/third_party/blink/public/platform/web_url_response.h
+++ b/third_party/blink/public/platform/web_url_response.h
@@ -195,7 +195,7 @@
   BLINK_PLATFORM_EXPORT void SetHttpStatusText(const WebString&);
 
   BLINK_PLATFORM_EXPORT WebString HttpHeaderField(const WebString& name) const;
-  BLINK_PLATFORM_EXPORT void SetHTTPHeaderField(const WebString& name,
+  BLINK_PLATFORM_EXPORT void SetHttpHeaderField(const WebString& name,
                                                 const WebString& value);
   BLINK_PLATFORM_EXPORT void AddHTTPHeaderField(const WebString& name,
                                                 const WebString& value);
diff --git a/third_party/blink/public/web/web_ax_object.h b/third_party/blink/public/web/web_ax_object.h
index 6aafedc..a8b14c915 100644
--- a/third_party/blink/public/web/web_ax_object.h
+++ b/third_party/blink/public/web/web_ax_object.h
@@ -99,10 +99,10 @@
   // tree.
   BLINK_EXPORT int GenerateAXID() const;
 
-  // Update layout on the underlying tree, and return true if this object is
-  // still valid (not detached). Note that calling this method
-  // can cause other WebAXObjects to become invalid, too,
-  // so always call isDetached if any other WebCore code has run.
+  // Update layout if necessary on the underlying tree, and return true if this
+  // object is still valid (not detached). Note that calling this method can
+  // cause other WebAXObjects to become invalid, too, so always call isDetached
+  // if any other blink/renderer/core code has run.
   BLINK_EXPORT bool UpdateLayoutAndCheckValidity();
 
   BLINK_EXPORT unsigned ChildCount() const;
diff --git a/third_party/blink/public/web/web_widget.h b/third_party/blink/public/web/web_widget.h
index a7da4679..b0f66af 100644
--- a/third_party/blink/public/web/web_widget.h
+++ b/third_party/blink/public/web/web_widget.h
@@ -194,6 +194,9 @@
   // Called to inform the WebWidget of the mouse cursor's visibility.
   virtual void SetCursorVisibilityState(bool is_visible) {}
 
+  // Inform WebWidget fallback cursor mode toggled.
+  virtual void OnFallbackCursorModeToggled(bool is_on) {}
+
   // Applies viewport related properties during a commit from the compositor
   // thread.
   virtual void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) {}
diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc b/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc
index 6d9ada6..44f59c3 100644
--- a/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc
+++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc
@@ -40,12 +40,6 @@
 
 namespace blink {
 
-V8CustomXPathNSResolver* V8CustomXPathNSResolver::Create(
-    ScriptState* script_state,
-    v8::Local<v8::Object> resolver) {
-  return MakeGarbageCollected<V8CustomXPathNSResolver>(script_state, resolver);
-}
-
 V8CustomXPathNSResolver::V8CustomXPathNSResolver(ScriptState* script_state,
                                                  v8::Local<v8::Object> resolver)
     : script_state_(script_state), resolver_(resolver) {}
diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h b/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h
index 5de4d58..76999822 100644
--- a/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h
+++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h
@@ -44,9 +44,6 @@
 // must not exceed the lifetime of the passed handle.
 class V8CustomXPathNSResolver final : public XPathNSResolver {
  public:
-  static V8CustomXPathNSResolver* Create(ScriptState*,
-                                         v8::Local<v8::Object> resolver);
-
   V8CustomXPathNSResolver(ScriptState*, v8::Local<v8::Object> resolver);
 
   AtomicString lookupNamespaceURI(const String& prefix) override;
diff --git a/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h b/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h
index 66aba9ac..68d9b0eb 100644
--- a/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h
+++ b/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h
@@ -15,25 +15,14 @@
 // compiled.
 class JSEventHandlerForContentAttribute final : public JSEventHandler {
  public:
-  static JSEventHandlerForContentAttribute* Create(
-      const AtomicString& function_name,
-      const String& code,
-      const String& source_url,
-      const TextPosition& position,
+  JSEventHandlerForContentAttribute(
       v8::Isolate* isolate,
       DOMWrapperWorld& world,
-      HandlerType type = HandlerType::kEventHandler) {
-    return MakeGarbageCollected<JSEventHandlerForContentAttribute>(
-        isolate, world, function_name, code, source_url, position, type);
-  }
-
-  JSEventHandlerForContentAttribute(v8::Isolate* isolate,
-                                    DOMWrapperWorld& world,
-                                    const AtomicString& function_name,
-                                    const String& script_body,
-                                    const String& source_url,
-                                    const TextPosition& position,
-                                    HandlerType type)
+      const AtomicString& function_name,
+      const String& script_body,
+      const String& source_url,
+      const TextPosition& position,
+      HandlerType type = HandlerType::kEventHandler)
       : JSEventHandler(type),
         did_compile_(false),
         function_name_(function_name),
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h
index 06e2f394..bdc1634 100644
--- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h
+++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h
@@ -48,13 +48,6 @@
 // Subclass of WindowProxy that only handles LocalFrame.
 class LocalWindowProxy final : public WindowProxy {
  public:
-  static LocalWindowProxy* Create(v8::Isolate* isolate,
-                                  LocalFrame& frame,
-                                  scoped_refptr<DOMWrapperWorld> world) {
-    return MakeGarbageCollected<LocalWindowProxy>(isolate, frame,
-                                                  std::move(world));
-  }
-
   LocalWindowProxy(v8::Isolate*, LocalFrame&, scoped_refptr<DOMWrapperWorld>);
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h b/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h
index c96623a..0841c42 100644
--- a/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h
+++ b/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h
@@ -45,13 +45,6 @@
 // using v8::Context::NewRemoteContext().
 class RemoteWindowProxy final : public WindowProxy {
  public:
-  static RemoteWindowProxy* Create(v8::Isolate* isolate,
-                                   RemoteFrame& frame,
-                                   scoped_refptr<DOMWrapperWorld> world) {
-    return MakeGarbageCollected<RemoteWindowProxy>(isolate, frame,
-                                                   std::move(world));
-  }
-
   RemoteWindowProxy(v8::Isolate*, RemoteFrame&, scoped_refptr<DOMWrapperWorld>);
 
  private:
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.h b/third_party/blink/renderer/bindings/core/v8/script_controller.h
index bf6af28..871feb0 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.h
@@ -68,12 +68,6 @@
     kDoNotExecuteScriptWhenScriptsDisabled
   };
 
-  static ScriptController* Create(
-      LocalFrame& frame,
-      LocalWindowProxyManager& window_proxy_manager) {
-    return MakeGarbageCollected<ScriptController>(frame, window_proxy_manager);
-  }
-
   ScriptController(LocalFrame& frame,
                    LocalWindowProxyManager& window_proxy_manager)
       : frame_(&frame), window_proxy_manager_(&window_proxy_manager) {}
diff --git a/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc b/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc
index d735ce4..6dc7a12 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc
@@ -72,8 +72,8 @@
   // of the isolated world for the content script by design.
   DOMWrapperWorld& world = DOMWrapperWorld::MainWorld();
 
-  return JSEventHandlerForContentAttribute::Create(
-      name.LocalName(), value, source_url, position, isolate, world, type);
+  return MakeGarbageCollected<JSEventHandlerForContentAttribute>(
+      isolate, world, name.LocalName(), value, source_url, position, type);
 }
 
 EventListener* CreateAttributeEventListener(LocalFrame* frame,
@@ -101,8 +101,8 @@
   // of the isolated world for the content script by design.
   DOMWrapperWorld& world = DOMWrapperWorld::MainWorld();
 
-  return JSEventHandlerForContentAttribute::Create(
-      name.LocalName(), value, source_url, position, isolate, world, type);
+  return MakeGarbageCollected<JSEventHandlerForContentAttribute>(
+      isolate, world, name.LocalName(), value, source_url, position, type);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc
index 2565a5b0..fc5dee6 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc
@@ -68,7 +68,7 @@
 TEST_F(ScriptPromiseResolverTest, construct) {
   ASSERT_FALSE(GetExecutionContext()->IsContextDestroyed());
   ScriptState::Scope scope(GetScriptState());
-  ScriptPromiseResolver::Create(GetScriptState());
+  MakeGarbageCollected<ScriptPromiseResolver>(GetScriptState());
 }
 
 TEST_F(ScriptPromiseResolverTest, resolve) {
@@ -76,7 +76,7 @@
   ScriptPromise promise;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolver::Create(GetScriptState());
+    resolver = MakeGarbageCollected<ScriptPromiseResolver>(GetScriptState());
     promise = resolver->Promise();
   }
 
@@ -125,7 +125,7 @@
   ScriptPromise promise;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolver::Create(GetScriptState());
+    resolver = MakeGarbageCollected<ScriptPromiseResolver>(GetScriptState());
     promise = resolver->Promise();
   }
 
@@ -174,7 +174,7 @@
   ScriptPromise promise;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolver::Create(GetScriptState());
+    resolver = MakeGarbageCollected<ScriptPromiseResolver>(GetScriptState());
     promise = resolver->Promise();
   }
 
@@ -202,10 +202,6 @@
 
 class ScriptPromiseResolverKeepAlive : public ScriptPromiseResolver {
  public:
-  static ScriptPromiseResolverKeepAlive* Create(ScriptState* script_state) {
-    return MakeGarbageCollected<ScriptPromiseResolverKeepAlive>(script_state);
-  }
-
   explicit ScriptPromiseResolverKeepAlive(ScriptState* script_state)
       : ScriptPromiseResolver(script_state) {}
   ~ScriptPromiseResolverKeepAlive() override { destructor_calls_++; }
@@ -223,7 +219,8 @@
   ScriptPromiseResolver* resolver = nullptr;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolverKeepAlive::Create(GetScriptState());
+    resolver =
+        MakeGarbageCollected<ScriptPromiseResolverKeepAlive>(GetScriptState());
   }
   resolver->KeepAliveWhilePending();
   ThreadState::Current()->CollectGarbage(
@@ -243,7 +240,8 @@
   ScriptPromiseResolver* resolver = nullptr;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolverKeepAlive::Create(GetScriptState());
+    resolver =
+        MakeGarbageCollected<ScriptPromiseResolverKeepAlive>(GetScriptState());
   }
   resolver->KeepAliveWhilePending();
   ThreadState::Current()->CollectGarbage(
@@ -263,7 +261,8 @@
   ScriptPromiseResolver* resolver = nullptr;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolverKeepAlive::Create(GetScriptState());
+    resolver =
+        MakeGarbageCollected<ScriptPromiseResolverKeepAlive>(GetScriptState());
   }
 
   {
@@ -289,7 +288,8 @@
   ScriptPromiseResolver* resolver = nullptr;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolverKeepAlive::Create(GetScriptState());
+    resolver =
+        MakeGarbageCollected<ScriptPromiseResolverKeepAlive>(GetScriptState());
   }
   resolver->KeepAliveWhilePending();
   ThreadState::Current()->CollectGarbage(
@@ -309,7 +309,8 @@
   ScriptPromiseResolver* resolver = nullptr;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolverKeepAlive::Create(GetScriptState());
+    resolver =
+        MakeGarbageCollected<ScriptPromiseResolverKeepAlive>(GetScriptState());
   }
   resolver->KeepAliveWhilePending();
   ThreadState::Current()->CollectGarbage(
@@ -336,7 +337,7 @@
   ScriptPromise promise;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolver::Create(GetScriptState());
+    resolver = MakeGarbageCollected<ScriptPromiseResolver>(GetScriptState());
     promise = resolver->Promise();
   }
 
@@ -361,7 +362,7 @@
   ScriptPromise promise;
   {
     ScriptState::Scope scope(GetScriptState());
-    resolver = ScriptPromiseResolver::Create(GetScriptState());
+    resolver = MakeGarbageCollected<ScriptPromiseResolver>(GetScriptState());
     promise = resolver->Promise();
   }
 
diff --git a/third_party/blink/renderer/bindings/core/v8/script_wrappable_marking_visitor_test.cc b/third_party/blink/renderer/bindings/core/v8/script_wrappable_marking_visitor_test.cc
index b6f06500..40d0791 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_wrappable_marking_visitor_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_wrappable_marking_visitor_test.cc
@@ -230,10 +230,6 @@
 class HandleContainer
     : public blink::GarbageCollectedFinalized<HandleContainer> {
  public:
-  static HandleContainer* Create() {
-    return MakeGarbageCollected<HandleContainer>();
-  }
-
   HandleContainer() = default;
   virtual ~HandleContainer() = default;
 
@@ -264,7 +260,7 @@
       v8::String::NewFromUtf8(scope.GetIsolate(), "teststring",
                               v8::NewStringType::kNormal, sizeof("teststring"))
           .ToLocalChecked();
-  HandleContainer* container = HandleContainer::Create();
+  auto* container = MakeGarbageCollected<HandleContainer>();
   CHECK_EQ(0u, raw_visitor->NumberOfMarkedWrappers());
   container->SetValue(scope.GetIsolate(), str);
   // The write barrier is conservative and does not check the mark bits of the
@@ -287,7 +283,7 @@
       v8::String::NewFromUtf8(scope.GetIsolate(), "teststring",
                               v8::NewStringType::kNormal, sizeof("teststring"))
           .ToLocalChecked();
-  HandleContainer* container = HandleContainer::Create();
+  auto* container = MakeGarbageCollected<HandleContainer>();
   HeapObjectHeader::FromPayload(container)->MarkWrapperHeader();
   CHECK_EQ(0u, raw_visitor->NumberOfMarkedWrappers());
   container->SetValue(scope.GetIsolate(), str);
@@ -415,11 +411,6 @@
   USING_GARBAGE_COLLECTED_MIXIN(Base);
 
  public:
-  static Base* Create(DeathAwareScriptWrappable* wrapper_in_base,
-                      DeathAwareScriptWrappable* wrapper_in_mixin) {
-    return MakeGarbageCollected<Base>(wrapper_in_base, wrapper_in_mixin);
-  }
-
   Base(DeathAwareScriptWrappable* wrapper_in_base,
        DeathAwareScriptWrappable* wrapper_in_mixin)
       : Mixin(wrapper_in_mixin), wrapper_in_base_(wrapper_in_base) {
@@ -451,7 +442,7 @@
   DeathAwareScriptWrappable* base_wrapper = DeathAwareScriptWrappable::Create();
   DeathAwareScriptWrappable* mixin_wrapper =
       DeathAwareScriptWrappable::Create();
-  Base* base = Base::Create(base_wrapper, mixin_wrapper);
+  auto* base = MakeGarbageCollected<Base>(base_wrapper, mixin_wrapper);
   Mixin* mixin = static_cast<Mixin*>(base);
   HeapObjectHeader* base_header = HeapObjectHeader::FromPayload(base);
   EXPECT_FALSE(base_header->IsWrapperHeaderMarked());
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
index 47d07a3..49ca746 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
@@ -620,8 +620,8 @@
   if (V8XPathNSResolver::HasInstance(value, script_state->GetIsolate())) {
     resolver = V8XPathNSResolver::ToImpl(v8::Local<v8::Object>::Cast(value));
   } else if (value->IsObject()) {
-    resolver =
-        V8CustomXPathNSResolver::Create(script_state, value.As<v8::Object>());
+    resolver = MakeGarbageCollected<V8CustomXPathNSResolver>(
+        script_state, value.As<v8::Object>());
   }
   return resolver;
 }
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index 0fdf8ba..aac30943 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -558,7 +558,7 @@
     v8::Local<v8::ScriptOrModule> v8_referrer,
     v8::Local<v8::String> v8_specifier) {
   ScriptState* script_state = ScriptState::From(context);
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   Modulator* modulator = Modulator::From(script_state);
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
index 122f33e..b805488 100644
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
@@ -78,10 +78,10 @@
       // LocalFrame and at that time virtual member functions are not yet
       // available (we cannot use LocalFrame::isLocalFrame).  Ditto for
       // RemoteFrame.
-      return LocalWindowProxy::Create(
+      return MakeGarbageCollected<LocalWindowProxy>(
           isolate_, *static_cast<LocalFrame*>(frame_.Get()), &world);
     case FrameType::kRemote:
-      return RemoteWindowProxy::Create(
+      return MakeGarbageCollected<RemoteWindowProxy>(
           isolate_, *static_cast<RemoteFrame*>(frame_.Get()), &world);
   }
   NOTREACHED();
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
index c988154..51190ee 100644
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
@@ -91,10 +91,6 @@
 class LocalWindowProxyManager
     : public WindowProxyManagerImplHelper<LocalFrame, LocalWindowProxy> {
  public:
-  static LocalWindowProxyManager* Create(LocalFrame& frame) {
-    return MakeGarbageCollected<LocalWindowProxyManager>(frame);
-  }
-
   explicit LocalWindowProxyManager(LocalFrame& frame)
       : WindowProxyManagerImplHelper<LocalFrame, LocalWindowProxy>(
             frame,
@@ -113,10 +109,6 @@
 class RemoteWindowProxyManager
     : public WindowProxyManagerImplHelper<RemoteFrame, RemoteWindowProxy> {
  public:
-  static RemoteWindowProxyManager* Create(RemoteFrame& frame) {
-    return MakeGarbageCollected<RemoteWindowProxyManager>(frame);
-  }
-
   explicit RemoteWindowProxyManager(RemoteFrame& frame)
       : WindowProxyManagerImplHelper<RemoteFrame, RemoteWindowProxy>(
             frame,
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
index 36e2924..611ea66 100644
--- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -92,13 +92,6 @@
   ExecutionState* outer_state_;
 };
 
-WorkerOrWorkletScriptController* WorkerOrWorkletScriptController::Create(
-    WorkerOrWorkletGlobalScope* global_scope,
-    v8::Isolate* isolate) {
-  return MakeGarbageCollected<WorkerOrWorkletScriptController>(global_scope,
-                                                               isolate);
-}
-
 WorkerOrWorkletScriptController::WorkerOrWorkletScriptController(
     WorkerOrWorkletGlobalScope* global_scope,
     v8::Isolate* isolate)
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
index 8b0d4b5c..cdf69f97 100644
--- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
+++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
@@ -52,9 +52,6 @@
 class CORE_EXPORT WorkerOrWorkletScriptController final
     : public GarbageCollectedFinalized<WorkerOrWorkletScriptController> {
  public:
-  static WorkerOrWorkletScriptController* Create(WorkerOrWorkletGlobalScope*,
-                                                 v8::Isolate*);
-
   WorkerOrWorkletScriptController(WorkerOrWorkletGlobalScope*, v8::Isolate*);
   virtual ~WorkerOrWorkletScriptController();
   void Dispose();
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
index 02f4f86..721bb00 100644
--- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h
+++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -58,6 +58,10 @@
 
   virtual void Dispose() = 0;
 
+  // Register/remove popups
+  virtual void InitializePopup(Document* document) = 0;
+  virtual void DisposePopup(Document* document) = 0;
+
   virtual void SelectionChanged(Node*) = 0;
   virtual void ChildrenChanged(Node*) = 0;
   virtual void ChildrenChanged(LayoutObject*) = 0;
@@ -86,7 +90,8 @@
   virtual void UpdateCacheAfterNodeIsAttached(Node*) = 0;
   virtual void DidInsertChildrenOfNode(Node*) = 0;
 
-  virtual void HandleAttributeChanged(const QualifiedName& attr_name,
+  // Returns true if the AXObjectCache cares about this attribute
+  virtual bool HandleAttributeChanged(const QualifiedName& attr_name,
                                       Element*) = 0;
   virtual void HandleFocusedUIElementChanged(Node* old_focused_node,
                                              Node* new_focused_node) = 0;
diff --git a/third_party/blink/renderer/core/animation/compositor_animations.cc b/third_party/blink/renderer/core/animation/compositor_animations.cc
index c4a6ebf6..fecefc8 100644
--- a/third_party/blink/renderer/core/animation/compositor_animations.cc
+++ b/third_party/blink/renderer/core/animation/compositor_animations.cc
@@ -706,8 +706,8 @@
     }
     DCHECK(curve.get());
 
-    std::unique_ptr<CompositorKeyframeModel> keyframe_model =
-        CompositorKeyframeModel::Create(*curve, target_property, group, 0);
+    auto keyframe_model = std::make_unique<CompositorKeyframeModel>(
+        *curve, target_property, 0, group);
 
     if (start_time)
       keyframe_model->SetStartTime(start_time.value());
diff --git a/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc
index 691c4360d..1bbe4ee8 100644
--- a/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc
@@ -27,7 +27,7 @@
       BasicShape* offset_path = style.OffsetPath();
       if (!offset_path || offset_path->GetType() != BasicShape::kStylePathType)
         return nullptr;
-      return ToStylePath(style.OffsetPath());
+      return To<StylePath>(style.OffsetPath());
     }
     default:
       NOTREACHED();
diff --git a/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc
index f8491f9..76f6140 100644
--- a/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc
@@ -67,7 +67,7 @@
   BasicShape* offset_path = style.OffsetPath();
   if (!offset_path || offset_path->GetType() != BasicShape::kStyleRayType)
     return nullptr;
-  return ToStyleRay(style.OffsetPath());
+  return To<StyleRay>(style.OffsetPath());
 }
 
 class UnderlyingRayModeChecker
@@ -205,7 +205,8 @@
     return nullptr;
 
   scoped_refptr<BasicShape> shape = BasicShapeForValue(*state, value);
-  return CreateValue(ToStyleRay(*shape).Angle(), RayMode(ToStyleRay(*shape)));
+  return CreateValue(To<StyleRay>(*shape).Angle(),
+                     RayMode(To<StyleRay>(*shape)));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/aom/accessible_node.cc b/third_party/blink/renderer/core/aom/accessible_node.cc
index d940a04..b3c5b361 100644
--- a/third_party/blink/renderer/core/aom/accessible_node.cc
+++ b/third_party/blink/renderer/core/aom/accessible_node.cc
@@ -8,7 +8,9 @@
 #include "third_party/blink/renderer/core/aom/accessible_node_list.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/qualified_name.h"
+#include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/platform//weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 
@@ -1170,12 +1172,30 @@
     const blink::QualifiedName& attribute) {
   // TODO(dmazzoni): Make a cleaner API for this rather than pretending
   // the DOM attribute changed.
-  if (AXObjectCache* cache = GetAXObjectCache()) {
-    if (element_)
-      cache->HandleAttributeChanged(attribute, element_);
-    else
-      cache->HandleAttributeChanged(attribute, this);
+  AXObjectCache* cache = GetAXObjectCache();
+  if (!cache)
+    return;
+
+  if (!element_) {
+    cache->HandleAttributeChanged(attribute, this);
+    return;
   }
+
+  // By definition, any attribute on an AccessibleNode is interesting to
+  // AXObjectCache, so no need to check return value.
+  cache->HandleAttributeChanged(attribute, element_);
+
+  auto* page = GetDocument()->GetPage();
+  auto* view = GetDocument()->View();
+  if (!page || !view)
+    return;
+
+  // TODO(aboxhall): add a lifecycle phase for accessibility updates.
+  if (!view->CanThrottleRendering())
+    page->Animator().ScheduleVisualUpdate(GetDocument()->GetFrame());
+
+  GetDocument()->Lifecycle().EnsureStateAtMost(
+      DocumentLifecycle::kVisualUpdatePending);
 }
 
 AXObjectCache* AccessibleNode::GetAXObjectCache() {
diff --git a/third_party/blink/renderer/core/aom/computed_accessible_node.cc b/third_party/blink/renderer/core/aom/computed_accessible_node.cc
index d4d97f8..7da3d0e3 100644
--- a/third_party/blink/renderer/core/aom/computed_accessible_node.cc
+++ b/third_party/blink/renderer/core/aom/computed_accessible_node.cc
@@ -55,7 +55,7 @@
     ScriptState* script_state,
     Element& element)
     : element_(element),
-      resolver_(ScriptPromiseResolver::Create(script_state)),
+      resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
       resolve_with_node_(false),
       ax_context_(std::make_unique<AXContext>(element_->GetDocument())) {}
 
diff --git a/third_party/blink/renderer/core/css/basic_shape_functions.cc b/third_party/blink/renderer/core/css/basic_shape_functions.cc
index 224ed11..2932deca 100644
--- a/third_party/blink/renderer/core/css/basic_shape_functions.cc
+++ b/third_party/blink/renderer/core/css/basic_shape_functions.cc
@@ -119,7 +119,7 @@
                              const BasicShape* basic_shape) {
   switch (basic_shape->GetType()) {
     case BasicShape::kStyleRayType: {
-      const StyleRay& ray = ToStyleRay(*basic_shape);
+      const StyleRay& ray = To<StyleRay>(*basic_shape);
       return cssvalue::CSSRayValue::Create(
           *CSSPrimitiveValue::Create(ray.Angle(),
                                      CSSPrimitiveValue::UnitType::kDegrees),
@@ -129,7 +129,7 @@
     }
 
     case BasicShape::kStylePathType:
-      return ToStylePath(basic_shape)->ComputedCSSValue();
+      return To<StylePath>(basic_shape)->ComputedCSSValue();
 
     case BasicShape::kBasicShapeCircleType: {
       const BasicShapeCircle* circle = ToBasicShapeCircle(basic_shape);
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.cc b/third_party/blink/renderer/core/css/css_style_sheet.cc
index d0d5e60..363913dd 100644
--- a/third_party/blink/renderer/core/css/css_style_sheet.cc
+++ b/third_party/blink/renderer/core/css/css_style_sheet.cc
@@ -475,7 +475,7 @@
   SetText(text, true /* allow_import_rules */, exception_state);
   if (!IsLoading())
     return ScriptPromise::Cast(script_state, ToV8(this, script_state));
-  resolver_ = ScriptPromiseResolver::Create(script_state);
+  resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   return resolver_->Promise();
 }
 
diff --git a/third_party/blink/renderer/core/css/font_face_set.cc b/third_party/blink/renderer/core/css/font_face_set.cc
index 886ba8d..bd386c2 100644
--- a/third_party/blink/renderer/core/css/font_face_set.cc
+++ b/third_party/blink/renderer/core/css/font_face_set.cc
@@ -163,8 +163,7 @@
 
   Font font;
   if (!ResolveFontStyle(font_string, font)) {
-    ScriptPromiseResolver* resolver =
-        ScriptPromiseResolver::Create(script_state);
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
     ScriptPromise promise = resolver->Promise();
     resolver->Reject(DOMException::Create(
         DOMExceptionCode::kSyntaxError,
diff --git a/third_party/blink/renderer/core/css/font_face_set.h b/third_party/blink/renderer/core/css/font_face_set.h
index 53c0f1c44..6235034 100644
--- a/third_party/blink/renderer/core/css/font_face_set.h
+++ b/third_party/blink/renderer/core/css/font_face_set.h
@@ -139,7 +139,7 @@
     LoadFontPromiseResolver(FontFaceArray faces, ScriptState* script_state)
         : num_loading_(faces.size()),
           error_occured_(false),
-          resolver_(ScriptPromiseResolver::Create(script_state)) {
+          resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)) {
       font_faces_.swap(faces);
     }
 
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
index f2781e7..3c3c051 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -60,7 +60,7 @@
 // Helper function that returns an immediately rejected promise.
 ScriptPromise GetRejectedPromise(ScriptState* script_state,
                                  const char* rejection_reason) {
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   auto promise = resolver->Promise();
   resolver->Reject(DOMException::Create(DOMExceptionCode::kNotAllowedError,
                                         rejection_reason));
@@ -69,7 +69,7 @@
 
 // Helper function that returns an immediately resolved promise.
 ScriptPromise GetResolvedPromise(ScriptState* script_state) {
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   auto promise = resolver->Promise();
   resolver->Resolve();
   return promise;
@@ -174,7 +174,8 @@
   // If we're already connected then we need to ensure that 1. layout is clean
   // and 2. we have removed the current painted output.
   if (ConnectedToView()) {
-    acquire_resolver_ = ScriptPromiseResolver::Create(script_state);
+    acquire_resolver_ =
+        MakeGarbageCollected<ScriptPromiseResolver>(script_state);
     state_ = kPendingAcquire;
     MarkPaintLayerNeedsRepaint();
     ScheduleAnimation();
@@ -202,7 +203,7 @@
     return update_resolver_->Promise();
   }
 
-  update_resolver_ = ScriptPromiseResolver::Create(script_state);
+  update_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   StartUpdateIfNeeded();
   return update_resolver_->Promise();
 }
@@ -228,8 +229,10 @@
   DCHECK_NE(state_, kCommitting);
   // We might already have a resolver if we called updateAndCommit() before
   // this.
-  if (!commit_resolver_)
-    commit_resolver_ = ScriptPromiseResolver::Create(script_state);
+  if (!commit_resolver_) {
+    commit_resolver_ =
+        MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+  }
   auto promise = commit_resolver_->Promise();
   StartCommit();
   return promise;
@@ -259,7 +262,7 @@
   }
 
   CancelTimeoutTask();
-  commit_resolver_ = ScriptPromiseResolver::Create(script_state);
+  commit_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   StartUpdateIfNeeded();
   return commit_resolver_->Promise();
 }
@@ -631,12 +634,12 @@
   }
 }
 
-void DisplayLockContext::WillStartLifecycleUpdate() {
+void DisplayLockContext::WillStartLifecycleUpdate(const LocalFrameView& view) {
   if (state_ == kUpdating)
     update_budget_->WillStartLifecycleUpdate();
 }
 
-void DisplayLockContext::DidFinishLifecycleUpdate() {
+void DisplayLockContext::DidFinishLifecycleUpdate(const LocalFrameView& view) {
   if (state_ == kPendingAcquire) {
     if (!ElementSupportsDisplayLocking()) {
       FinishAcquireResolver(kReject, rejection_names::kContainmentNotSatisfied);
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.h b/third_party/blink/renderer/core/display_lock/display_lock_context.h
index 0e5895d..8f4d7ec 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context.h
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -163,8 +163,8 @@
   void AddToWhitespaceReattachSet(Element& element);
 
   // LifecycleNotificationObserver overrides.
-  void WillStartLifecycleUpdate() override;
-  void DidFinishLifecycleUpdate() override;
+  void WillStartLifecycleUpdate(const LocalFrameView&) override;
+  void DidFinishLifecycleUpdate(const LocalFrameView&) override;
 
   // Notify this element will be disconnected.
   void NotifyWillDisconnect();
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index faecf20..3c00b7f 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2474,9 +2474,6 @@
   if (Lifecycle().GetState() < DocumentLifecycle::kLayoutClean)
     Lifecycle().AdvanceTo(DocumentLifecycle::kLayoutClean);
 
-  if (AXObjectCache* cache = ExistingAXObjectCache())
-    cache->ProcessUpdatesAfterLayout(*this);
-
   if (LocalFrameView* frame_view_anchored = View())
     frame_view_anchored->PerformScrollAnchoringAdjustments();
 
@@ -5076,7 +5073,7 @@
   if (!access_entry_from_url_) {
     access_entry_from_url_ = std::make_unique<OriginAccessEntry>(
         Url().Protocol(), Url().Host(),
-        network::mojom::CorsOriginAccessMatchMode::kAllowRegisterableDomains);
+        network::mojom::CorsOriginAccessMatchMode::kAllowRegistrableDomains);
   }
   return *access_entry_from_url_;
 }
@@ -5451,7 +5448,7 @@
   if (!top_local_frame) {
     remote_entry.emplace(
         top_document_url.Protocol(), top_document_url.Host(),
-        network::mojom::CorsOriginAccessMatchMode::kAllowRegisterableDomains);
+        network::mojom::CorsOriginAccessMatchMode::kAllowRegistrableDomains);
   }
   const OriginAccessEntry& access_entry =
       remote_entry ? *remote_entry
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index ae861d3..a416238 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1690,8 +1690,22 @@
 
   if (isConnected()) {
     if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) {
-      if (params.old_value != params.new_value)
-        cache->HandleAttributeChanged(name, this);
+      if (params.old_value != params.new_value) {
+        auto* page = GetDocument().GetPage();
+        auto* view = GetDocument().View();
+        // If this attribute is interesting for accessibility (e.g. `role` or
+        // `alt`), but doesn't trigger a lifecycle update on its own
+        // (e.g. because it doesn't make layout dirty), make sure we run
+        // lifecycle phases to update the computed accessibility tree.
+        if (cache->HandleAttributeChanged(name, this) && page && view) {
+          if (!view->CanThrottleRendering())
+            page->Animator().ScheduleVisualUpdate(GetDocument().GetFrame());
+
+          // TODO(aboxhall): add a lifecycle phase for accessibility updates.
+          GetDocument().Lifecycle().EnsureStateAtMost(
+              DocumentLifecycle::kVisualUpdatePending);
+        }
+      }
     }
   }
 
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index c4a7b95b..b3c5123 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -2820,12 +2820,12 @@
 }
 
 HTMLSlotElement* Node::AssignedSlot() const {
-  // assignedSlot doesn't need to recalc assignment.
   DCHECK(!IsPseudoElement());
   ShadowRoot* root = V1ShadowRootOfParent();
   if (!root)
     return nullptr;
   if (!RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled()) {
+    // Don't recalc assignment in this case.
     return root->AssignedSlotFor(*this);
   }
 
@@ -2845,11 +2845,14 @@
   //
   // If we can remove such code path, we don't need to check
   // IsInSlotAssignmentRecalc() here.
-  if (root->NeedsSlotAssignmentRecalc() ||
-      GetDocument().IsInSlotAssignmentRecalc()) {
+  if (GetDocument().IsInSlotAssignmentRecalc()) {
     // FlatTreeNodeData is not realiable here. Entering slow path.
     return root->AssignedSlotFor(*this);
   }
+
+  // Recalc assignment, if necessary, to make sure the FlatTreeNodeData is not
+  // dirty. RecalcAssignment() is almost no-op if we don't need to recalc.
+  root->GetSlotAssignment().RecalcAssignment();
   if (FlatTreeNodeData* data = GetFlatTreeNodeData()) {
     DCHECK_EQ(root->AssignedSlotFor(*this), data->AssignedSlot());
     return data->AssignedSlot();
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue.cc b/third_party/blink/renderer/core/dom/scripted_task_queue.cc
index 98a5c13..54a3473 100644
--- a/third_party/blink/renderer/core/dom/scripted_task_queue.cc
+++ b/third_party/blink/renderer/core/dom/scripted_task_queue.cc
@@ -64,7 +64,7 @@
                                           AbortSignal* signal) {
   CallbackId id = next_callback_id_++;
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
   if (signal) {
     if (signal->aborted()) {
diff --git a/third_party/blink/renderer/core/editing/plain_text_range.h b/third_party/blink/renderer/core/editing/plain_text_range.h
index 78b52bfb..62af2e98 100644
--- a/third_party/blink/renderer/core/editing/plain_text_range.h
+++ b/third_party/blink/renderer/core/editing/plain_text_range.h
@@ -30,7 +30,7 @@
 #include "third_party/blink/renderer/core/editing/forward.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
index 09b0986..44f784c 100644
--- a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
+++ b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
@@ -187,7 +187,7 @@
       request.SetHTTPReferrer(WebString::FromUTF8(header_value),
                               network::mojom::ReferrerPolicy::kDefault);
     } else {
-      request.SetHTTPHeaderField(WebString::FromUTF8(header_field),
+      request.SetHttpHeaderField(WebString::FromUTF8(header_field),
                                  WebString::FromUTF8(header_value));
     }
 
@@ -430,7 +430,7 @@
   expected_redirect_response_ = WebURLResponse();
   expected_redirect_response_.SetMimeType("text/html");
   expected_redirect_response_.SetHttpStatusCode(301);
-  expected_redirect_response_.SetHTTPHeaderField("Location", redirect);
+  expected_redirect_response_.SetHttpHeaderField("Location", redirect);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       url, expected_redirect_response_, frame_file_path_);
 
@@ -466,7 +466,7 @@
   expected_redirect_response_ = WebURLResponse();
   expected_redirect_response_.SetMimeType("text/html");
   expected_redirect_response_.SetHttpStatusCode(301);
-  expected_redirect_response_.SetHTTPHeaderField("Location", redirect);
+  expected_redirect_response_.SetHttpHeaderField("Location", redirect);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       url, expected_redirect_response_, frame_file_path_);
 
@@ -506,7 +506,7 @@
   expected_redirect_response_ = WebURLResponse();
   expected_redirect_response_.SetMimeType("text/html");
   expected_redirect_response_.SetHttpStatusCode(301);
-  expected_redirect_response_.SetHTTPHeaderField("Location", redirect);
+  expected_redirect_response_.SetHttpHeaderField("Location", redirect);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       url, expected_redirect_response_, frame_file_path_);
 
@@ -546,14 +546,14 @@
   request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors);
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
   // Add a CORS simple header.
-  request.SetHTTPHeaderField("accept", "application/json");
+  request.SetHttpHeaderField("accept", "application/json");
 
   // Create a redirect response that allows the redirect to pass the access
   // control checks.
   expected_redirect_response_ = WebURLResponse();
   expected_redirect_response_.SetMimeType("text/html");
   expected_redirect_response_.SetHttpStatusCode(301);
-  expected_redirect_response_.SetHTTPHeaderField("Location", redirect);
+  expected_redirect_response_.SetHttpHeaderField("Location", redirect);
   expected_redirect_response_.AddHTTPHeaderField("access-control-allow-origin",
                                                  "*");
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc
index 39457c0..6e3b09fbb 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -7285,7 +7285,7 @@
   WebURLResponse redirect_response;
   redirect_response.SetMimeType("text/html");
   redirect_response.SetHttpStatusCode(302);
-  redirect_response.SetHTTPHeaderField("Location", redirect);
+  redirect_response.SetHttpHeaderField("Location", redirect);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       test_url, redirect_response, file_path);
 
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index 750b55f..b716b5bb 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -298,14 +298,15 @@
   frame->Init();
   frame->View()->SetParentVisible(true);
   frame->View()->SetSelfVisible(true);
-  if (AXObjectCache* cache =
-          popup_client_->OwnerElement().GetDocument().ExistingAXObjectCache())
-    cache->ChildrenChanged(&popup_client_->OwnerElement());
 
   DCHECK(frame->DomWindow());
   PagePopupSupplement::Install(*frame, *this, popup_client_);
   DCHECK_EQ(popup_client_->OwnerElement().GetDocument().ExistingAXObjectCache(),
             frame->GetDocument()->ExistingAXObjectCache());
+  if (AXObjectCache* cache = frame->GetDocument()->ExistingAXObjectCache()) {
+    cache->InitializePopup(frame->GetDocument());
+    cache->ChildrenChanged(&popup_client_->OwnerElement());
+  }
 
   page_->LayerTreeViewInitialized(*layer_tree_view_, *animation_host_, nullptr);
 
@@ -558,6 +559,9 @@
 
   closing_ = true;
 
+  if (AXObjectCache* cache = MainFrame().GetDocument()->ExistingAXObjectCache())
+    cache->DisposePopup(MainFrame().GetDocument());
+
   {
     // This function can be called in EventDispatchForbiddenScope for the main
     // document, and the following operations dispatch some events.  It's safe
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 12fd00b..aee88dfc 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1828,6 +1828,12 @@
     AsView().page->SetIsCursorVisible(is_visible);
 }
 
+void WebViewImpl::OnFallbackCursorModeToggled(bool is_on) {
+  DCHECK(MainFrameImpl());
+  MainFrameImpl()->GetFrame()->GetEventHandler().SetIsFallbackCursorModeOn(
+      is_on);
+}
+
 void WebViewImpl::MouseCaptureLost() {
   TRACE_EVENT_ASYNC_END0("input", "capturing mouse", this);
   mouse_capture_element_ = nullptr;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
index d9b8a6c..2c5dbf7 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -453,6 +453,7 @@
   WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override;
   WebInputEventResult DispatchBufferedTouchEvents() override;
   void SetCursorVisibilityState(bool is_visible) override;
+  void OnFallbackCursorModeToggled(bool is_on) override;
   void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override;
   void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel,
                                          bool has_scrolled_by_touch) override;
diff --git a/third_party/blink/renderer/core/exported/worker_shadow_page.cc b/third_party/blink/renderer/core/exported/worker_shadow_page.cc
index 397bbc7..9903ffc8 100644
--- a/third_party/blink/renderer/core/exported/worker_shadow_page.cc
+++ b/third_party/blink/renderer/core/exported/worker_shadow_page.cc
@@ -102,7 +102,7 @@
 
 void WorkerShadowPage::WillSendRequest(WebURLRequest& request) {
   if (preferences_.enable_do_not_track) {
-    request.SetHTTPHeaderField(WebString::FromUTF8(kDoNotTrackHeader), "1");
+    request.SetHttpHeaderField(WebString::FromUTF8(kDoNotTrackHeader), "1");
   }
   if (!preferences_.enable_referrers) {
     request.SetHTTPReferrer(WebString(),
diff --git a/third_party/blink/renderer/core/fetch/body.cc b/third_party/blink/renderer/core/fetch/body.cc
index b40289f..9dae3aa 100644
--- a/third_party/blink/renderer/core/fetch/body.cc
+++ b/third_party/blink/renderer/core/fetch/body.cc
@@ -166,7 +166,7 @@
   if (!ExecutionContext::From(script_state))
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (BodyBuffer()) {
     BodyBuffer()->StartLoading(
@@ -194,7 +194,7 @@
   if (!ExecutionContext::From(script_state))
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (BodyBuffer()) {
     BodyBuffer()->StartLoading(
@@ -224,7 +224,7 @@
   if (!ExecutionContext::From(script_state))
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   const ParsedContentType parsedTypeWithParameters(ContentType());
   const String parsedType = parsedTypeWithParameters.MimeType().LowerASCII();
   ScriptPromise promise = resolver->Promise();
@@ -289,7 +289,7 @@
   if (!ExecutionContext::From(script_state))
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (BodyBuffer()) {
     BodyBuffer()->StartLoading(FetchDataLoader::CreateLoaderAsString(),
@@ -317,7 +317,7 @@
   if (!ExecutionContext::From(script_state))
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (BodyBuffer()) {
     BodyBuffer()->StartLoading(FetchDataLoader::CreateLoaderAsString(),
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc
index 66a464d..7bd15b89 100644
--- a/third_party/blink/renderer/core/fetch/fetch_manager.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -846,7 +846,7 @@
                                   FetchRequestData* request,
                                   AbortSignal* signal,
                                   ExceptionState& exception_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   DCHECK(signal);
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
index f2290fc..0ea68fd 100644
--- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
+++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -65,11 +65,11 @@
 #include "third_party/blink/renderer/platform/weborigin/known_ports.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
 #include "third_party/blink/renderer/platform/wtf/string_hasher.h"
 #include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
 #include "v8/include/v8.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
index 00685e1..4633e30a 100644
--- a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
+++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
@@ -944,23 +944,23 @@
                   response, secure_origin.get()),
               test.inherits);
 
-    response.SetHTTPHeaderField(http_names::kAllowCSPFrom, AtomicString("*"));
+    response.SetHttpHeaderField(http_names::kAllowCSPFrom, AtomicString("*"));
     EXPECT_TRUE(ContentSecurityPolicy::ShouldEnforceEmbeddersPolicy(
         response, secure_origin.get()));
 
-    response.SetHTTPHeaderField(http_names::kAllowCSPFrom,
+    response.SetHttpHeaderField(http_names::kAllowCSPFrom,
                                 AtomicString("* not a valid header"));
     EXPECT_EQ(ContentSecurityPolicy::ShouldEnforceEmbeddersPolicy(
                   response, secure_origin.get()),
               test.inherits);
 
-    response.SetHTTPHeaderField(http_names::kAllowCSPFrom,
+    response.SetHttpHeaderField(http_names::kAllowCSPFrom,
                                 AtomicString("http://example.test"));
     EXPECT_EQ(ContentSecurityPolicy::ShouldEnforceEmbeddersPolicy(
                   response, secure_origin.get()),
               test.inherits);
 
-    response.SetHTTPHeaderField(http_names::kAllowCSPFrom,
+    response.SetHttpHeaderField(http_names::kAllowCSPFrom,
                                 AtomicString("https://example.test"));
     EXPECT_TRUE(ContentSecurityPolicy::ShouldEnforceEmbeddersPolicy(
         response, secure_origin.get()));
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 136a804a..4014254 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -926,7 +926,10 @@
                               Page& page,
                               FrameOwner* owner,
                               InterfaceRegistry* interface_registry)
-    : Frame(client, page, owner, LocalWindowProxyManager::Create(*this)),
+    : Frame(client,
+            page,
+            owner,
+            MakeGarbageCollected<LocalWindowProxyManager>(*this)),
       frame_scheduler_(page.GetPageScheduler()->CreateFrameScheduler(
           this,
           client->GetFrameBlameContext(),
@@ -934,7 +937,7 @@
                         : FrameScheduler::FrameType::kSubframe)),
       loader_(this),
       navigation_scheduler_(NavigationScheduler::Create(this)),
-      script_controller_(ScriptController::Create(
+      script_controller_(MakeGarbageCollected<ScriptController>(
           *this,
           *static_cast<LocalWindowProxyManager*>(GetWindowProxyManager()))),
       editor_(Editor::Create(*this)),
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 4b35f36..264d2b4 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2215,7 +2215,7 @@
 
   ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
     for (auto& observer : frame_view.lifecycle_observers_)
-      observer->WillStartLifecycleUpdate();
+      observer->WillStartLifecycleUpdate(frame_view);
   });
 
   // If we're in PrintBrowser mode, setup a print context.
@@ -2231,7 +2231,7 @@
 
   ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
     for (auto& observer : frame_view.lifecycle_observers_)
-      observer->DidFinishLifecycleUpdate();
+      observer->DidFinishLifecycleUpdate(frame_view);
   });
 
   return Lifecycle().GetState() == target_state;
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h
index 867a0a7..49fa8c1 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.h
+++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -117,8 +117,8 @@
       : public GarbageCollectedMixin {
    public:
     // These are called when the lifecycle updates start/finish.
-    virtual void WillStartLifecycleUpdate() = 0;
-    virtual void DidFinishLifecycleUpdate() = 0;
+    virtual void WillStartLifecycleUpdate(const LocalFrameView&) = 0;
+    virtual void DidFinishLifecycleUpdate(const LocalFrameView&) = 0;
   };
 
   static LocalFrameView* Create(LocalFrame&);
diff --git a/third_party/blink/renderer/core/frame/navigator_user_agent.cc b/third_party/blink/renderer/core/frame/navigator_user_agent.cc
index 12e44f4..e9dd0068 100644
--- a/third_party/blink/renderer/core/frame/navigator_user_agent.cc
+++ b/third_party/blink/renderer/core/frame/navigator_user_agent.cc
@@ -11,7 +11,7 @@
 namespace blink {
 
 ScriptPromise NavigatorUserAgent::getUserAgent(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   blink::UserAgentMetadata metadata = GetUserAgentMetadata();
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc
index 6c01824..60d03a8 100644
--- a/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -30,7 +30,10 @@
 inline RemoteFrame::RemoteFrame(RemoteFrameClient* client,
                                 Page& page,
                                 FrameOwner* owner)
-    : Frame(client, page, owner, RemoteWindowProxyManager::Create(*this)),
+    : Frame(client,
+            page,
+            owner,
+            MakeGarbageCollected<RemoteWindowProxyManager>(*this)),
       security_context_(RemoteSecurityContext::Create()) {
   dom_window_ = RemoteDOMWindow::Create(*this);
   UpdateInertIfPossible();
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index 2cb2430..e342bd4 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -500,6 +500,11 @@
   GetPage()->SetIsCursorVisible(is_visible);
 }
 
+void WebFrameWidgetImpl::OnFallbackCursorModeToggled(bool is_on) {
+  // TODO(crbug.com/944575) Should support oopif.
+  NOTREACHED();
+}
+
 WebInputMethodController*
 WebFrameWidgetImpl::GetActiveWebInputMethodController() const {
   WebLocalFrameImpl* local_frame =
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
index d4992a6..a45f138d 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -99,6 +99,7 @@
   WebInputEventResult DispatchBufferedTouchEvents() override;
   WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override;
   void SetCursorVisibilityState(bool is_visible) override;
+  void OnFallbackCursorModeToggled(bool is_on) override;
 
   void ApplyViewportChanges(const ApplyViewportChangesArgs&) override;
   void MouseCaptureLost() override;
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
index e7be575b..75aef1e6 100644
--- a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
+++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
@@ -110,6 +110,10 @@
   web_view_->SetCursorVisibilityState(is_visible);
 }
 
+void WebViewFrameWidget::OnFallbackCursorModeToggled(bool is_on) {
+  web_view_->OnFallbackCursorModeToggled(is_on);
+}
+
 void WebViewFrameWidget::ApplyViewportChanges(
     const ApplyViewportChangesArgs& args) {
   web_view_->ApplyViewportChanges(args);
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.h b/third_party/blink/renderer/core/frame/web_view_frame_widget.h
index dad1e28..868b599 100644
--- a/third_party/blink/renderer/core/frame/web_view_frame_widget.h
+++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.h
@@ -64,6 +64,7 @@
   WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override;
   WebInputEventResult DispatchBufferedTouchEvents() override;
   void SetCursorVisibilityState(bool is_visible) override;
+  void OnFallbackCursorModeToggled(bool is_on) override;
   void ApplyViewportChanges(const ApplyViewportChangesArgs&) override;
   void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel,
                                          bool has_scrolled_by_touch) override;
diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen.cc b/third_party/blink/renderer/core/fullscreen/fullscreen.cc
index 567bd87e..2529cfb 100644
--- a/third_party/blink/renderer/core/fullscreen/fullscreen.cc
+++ b/third_party/blink/renderer/core/fullscreen/fullscreen.cc
@@ -578,7 +578,7 @@
   if (script_state) {
     // We should only be creating promises for unprefixed variants.
     DCHECK_EQ(Fullscreen::RequestType::kUnprefixed, request_type);
-    resolver = ScriptPromiseResolver::Create(script_state);
+    resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   }
 
   bool for_cross_process_descendant =
@@ -789,7 +789,7 @@
   }
 
   if (script_state)
-    resolver = ScriptPromiseResolver::Create(script_state);
+    resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
   // 3. Let |resize| be false.
   bool resize = false;
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
index 4a2ea288..5836aa3 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
@@ -210,8 +210,7 @@
   scoped_refptr<StaticBitmapImage> image_bitmap =
       RenderingContext()->GetImage(kPreferNoAcceleration);
   if (image_bitmap) {
-    ScriptPromiseResolver* resolver =
-        ScriptPromiseResolver::Create(script_state);
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
     CanvasAsyncBlobCreator::ToBlobFunctionType function_type =
         CanvasAsyncBlobCreator::kHTMLCanvasConvertToBlobPromise;
     if (this->IsOffscreenCanvas()) {
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_registry.cc b/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
index 97cef38..13d7a65 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
@@ -323,8 +323,8 @@
   ScriptPromiseResolver* resolver = when_defined_promise_map_.at(name);
   if (resolver)
     return resolver->Promise();
-  ScriptPromiseResolver* new_resolver =
-      ScriptPromiseResolver::Create(script_state);
+  auto* new_resolver =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   when_defined_promise_map_.insert(name, new_resolver);
   return new_resolver->Promise();
 }
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index 2b6b90e5..76d81ef 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -1142,6 +1142,23 @@
 
   if (value_changed)
     NotifyFormStateChanged();
+
+  if (isConnected()) {
+    if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) {
+      auto* page = GetDocument().GetPage();
+      auto* view = GetDocument().View();
+      // Run the document lifecycle to ensure AX notifications fire,
+      // even if the value didn't change.
+      if (page && view) {
+        // TODO(aboxhall): add a lifecycle phase for accessibility updates.
+        if (!view->CanThrottleRendering())
+          page->Animator().ScheduleVisualUpdate(GetDocument().GetFrame());
+
+        GetDocument().Lifecycle().EnsureStateAtMost(
+            DocumentLifecycle::kVisualUpdatePending);
+      }
+    }
+  }
 }
 
 void HTMLInputElement::SetNonAttributeValue(const String& sanitized_value) {
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc
index 002177e..1530715 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -2384,7 +2384,7 @@
   // is called, |play_promise_resolvers_| needs to be populated. What this code
   // does is to populate |play_promise_resolvers_| before calling ::play() and
   // remove the Promise if ::play() failed.
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   play_promise_resolvers_.push_back(resolver);
 
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
index a82ef91..d34689bf 100644
--- a/third_party/blink/renderer/core/html/portal/html_portal_element.cc
+++ b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
@@ -112,7 +112,7 @@
 
 ScriptPromise HTMLPortalElement::activate(ScriptState* script_state,
                                           PortalActivateOptions* options) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   ExceptionState exception_state(script_state->GetIsolate(),
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
index 1117032..3ba5012 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -969,7 +969,7 @@
                                        Document* document,
                                        ScriptState* script_state,
                                        const ImageBitmapOptions* options) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   scoped_refptr<Image> input = image->CachedImage()->GetImage();
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
index 53bcbfd..8e22dee6 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
@@ -257,7 +257,7 @@
           this,
           GetExecutionContext()->GetTaskRunner(TaskType::kFileReading))),
       factory_(&factory),
-      resolver_(ScriptPromiseResolver::Create(script_state)),
+      resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
       crop_rect_(crop_rect),
       options_(options) {}
 
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.cc
index 20f0e69..a2854e7b 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.cc
@@ -12,7 +12,7 @@
 
 ScriptPromise ImageBitmapSource::FulfillImageBitmap(ScriptState* script_state,
                                                     ImageBitmap* image_bitmap) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (image_bitmap && image_bitmap->BitmapImage()) {
     resolver->Resolve(image_bitmap);
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc
index 5016dc3..1a7354ec 100644
--- a/third_party/blink/renderer/core/input/event_handler.cc
+++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -180,7 +180,7 @@
                              this,
                              &EventHandler::ActiveIntervalTimerFired) {
   if (RuntimeEnabledFeatures::FallbackCursorModeEnabled() &&
-      frame.IsLocalRoot()) {
+      frame.IsMainFrame()) {
     fallback_cursor_event_manager_ =
         MakeGarbageCollected<FallbackCursorEventManager>(frame);
   }
@@ -662,6 +662,8 @@
       mev.InnerNode());
 
   if (RuntimeEnabledFeatures::FallbackCursorModeEnabled()) {
+    // TODO(crbug.com/944575) Should support oopif.
+    DCHECK(frame_->LocalFrameRoot().IsMainFrame());
     frame_->LocalFrameRoot()
         .GetEventHandler()
         .fallback_cursor_event_manager_->HandleMousePressEvent(mouse_event);
@@ -820,6 +822,8 @@
                                                   hovered_node_result);
 
   if (RuntimeEnabledFeatures::FallbackCursorModeEnabled()) {
+    // TODO(crbug.com/944575) Should support oopif.
+    DCHECK(frame_->LocalFrameRoot().IsMainFrame());
     frame_->LocalFrameRoot()
         .GetEventHandler()
         .fallback_cursor_event_manager_->HandleMouseMoveEvent(event);
@@ -2322,4 +2326,11 @@
   capturing_subframe_element_ = nullptr;
 }
 
+void EventHandler::SetIsFallbackCursorModeOn(bool is_on) {
+  DCHECK(RuntimeEnabledFeatures::FallbackCursorModeEnabled());
+  // TODO(crbug.com/944575) Should support oopif.
+  DCHECK(frame_->IsMainFrame());
+  fallback_cursor_event_manager_->SetIsFallbackCursorModeOn(is_on);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/input/event_handler.h b/third_party/blink/renderer/core/input/event_handler.h
index b923b44..2fc2c22 100644
--- a/third_party/blink/renderer/core/input/event_handler.h
+++ b/third_party/blink/renderer/core/input/event_handler.h
@@ -288,6 +288,8 @@
 
   void MarkHoverStateDirty();
 
+  void SetIsFallbackCursorModeOn(bool is_on);
+
  private:
   enum NoCursorChangeType { kNoCursorChange };
 
diff --git a/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc b/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc
index e136641f..1a9d4c50 100644
--- a/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc
+++ b/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc
@@ -265,6 +265,7 @@
 
 void FallbackCursorEventManager::HandleMouseMoveEvent(const WebMouseEvent& e) {
   DCHECK(RuntimeEnabledFeatures::FallbackCursorModeEnabled());
+  DCHECK(is_fallback_cursor_mode_on_);
 
   InvalidateCurrentScrollableIfNeeded();
   ScrollableArea* scrollable = CurrentScrollingScrollableArea();
@@ -289,6 +290,7 @@
 
 void FallbackCursorEventManager::HandleMousePressEvent(const WebMouseEvent& e) {
   DCHECK(RuntimeEnabledFeatures::FallbackCursorModeEnabled());
+  DCHECK(is_fallback_cursor_mode_on_);
 
   ResetCurrentScrollable();
 
diff --git a/third_party/blink/renderer/core/input/fallback_cursor_event_manager.h b/third_party/blink/renderer/core/input/fallback_cursor_event_manager.h
index b5a56fc..4c58bdd2 100644
--- a/third_party/blink/renderer/core/input/fallback_cursor_event_manager.h
+++ b/third_party/blink/renderer/core/input/fallback_cursor_event_manager.h
@@ -27,6 +27,10 @@
   FallbackCursorEventManager(LocalFrame&);
   void Trace(blink::Visitor*);
 
+  void SetIsFallbackCursorModeOn(bool is_on) {
+    is_fallback_cursor_mode_on_ = is_on;
+  }
+
   void HandleMouseMoveEvent(const WebMouseEvent&);
   void HandleMousePressEvent(const WebMouseEvent&);
 
@@ -59,6 +63,7 @@
 
   const Member<LocalFrame> root_frame_;
   Member<Node> current_node_;
+  bool is_fallback_cursor_mode_on_;
 
   DISALLOW_COPY_AND_ASSIGN(FallbackCursorEventManager);
 };
diff --git a/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc b/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc
index 90a0ec63..49b439d5 100644
--- a/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc
+++ b/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc
@@ -57,6 +57,10 @@
     return *chrome_client_;
   }
 
+  void TurnOnFallbackCursorMode() {
+    GetDocument().GetFrame()->GetEventHandler().SetIsFallbackCursorModeOn(true);
+  }
+
   void MouseMove(int x, int y) {
     WebMouseEvent event(WebInputEvent::kMouseMove, WebFloatPoint(x, y),
                         WebFloatPoint(x, y),
@@ -91,6 +95,7 @@
 
 TEST_F(FallbackCursorEventManagerTest, RootFrameNotScrollable) {
   SetBodyInnerHTML("A");
+  TurnOnFallbackCursorMode();
 
   // Mouse move to edge.
   MouseMove(0, 0);
@@ -119,6 +124,7 @@
     </style>
     <div class='big'></div>
   )HTML");
+  TurnOnFallbackCursorMode();
 
   // Move below the scroll down line.
   MouseMove(100, 500);
@@ -153,6 +159,7 @@
       <div class='big'></div>
     </div>
   )HTML");
+  TurnOnFallbackCursorMode();
 
   // Move below the scroll down line but before mouse down.
   MouseMove(50, 80);
@@ -208,6 +215,7 @@
     </style>
     <div class='big'></div>
   )HTML");
+  TurnOnFallbackCursorMode();
 
   // Move below the scroll down line but before mouse down.
   MouseMove(50, 80);
@@ -251,6 +259,7 @@
     <div class='big' contenteditable='true'>
     </div>
   )HTML");
+  TurnOnFallbackCursorMode();
 
   MouseMove(50, 80);
   MouseDown(50, 80);
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.cc b/third_party/blink/renderer/core/inspector/inspect_tools.cc
index 6700c591..4cf4fe04 100644
--- a/third_party/blink/renderer/core/inspector/inspect_tools.cc
+++ b/third_party/blink/renderer/core/inspector/inspect_tools.cc
@@ -133,6 +133,21 @@
   overlay_->EvaluateInOverlay("drawHighlight", highlight.AsProtocolValue());
 }
 
+bool SearchingForNodeTool::HandleInputEvent(LocalFrameView* frame_view,
+                                            const WebInputEvent& input_event,
+                                            bool* swallow_next_mouse_up,
+                                            bool* swallow_next_escape_up) {
+  if (input_event.GetType() == WebInputEvent::kGestureScrollBegin ||
+      input_event.GetType() == WebInputEvent::kGestureScrollUpdate) {
+    hovered_node_.Clear();
+    event_target_node_.Clear();
+    overlay_->ScheduleUpdate();
+    return false;
+  }
+  return InspectTool::HandleInputEvent(
+      frame_view, input_event, swallow_next_mouse_up, swallow_next_escape_up);
+}
+
 bool SearchingForNodeTool::HandleMouseMove(const WebMouseEvent& event) {
   LocalFrame* frame = overlay_->GetFrame();
   if (!frame || !frame->View() || !frame->ContentLayoutObject())
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.h b/third_party/blink/renderer/core/inspector/inspect_tools.h
index 6d03d52..0d45876 100644
--- a/third_party/blink/renderer/core/inspector/inspect_tools.h
+++ b/third_party/blink/renderer/core/inspector/inspect_tools.h
@@ -22,6 +22,10 @@
                        const String& highlight_config);
 
  private:
+  bool HandleInputEvent(LocalFrameView* frame_view,
+                        const WebInputEvent& input_event,
+                        bool* swallow_next_mouse_up,
+                        bool* swallow_next_escape_up) override;
   bool HandleMouseDown(const WebMouseEvent& event,
                        bool* swallow_next_mouse_up) override;
   bool HandleMouseMove(const WebMouseEvent& event) override;
diff --git a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
index e4f40c43..02b4971 100644
--- a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
@@ -357,7 +357,7 @@
     ResourceType resource_type) {
   if (!accept_language_override_.Get().IsEmpty() &&
       request.HttpHeaderField("Accept-Language").IsEmpty()) {
-    request.SetHTTPHeaderField(
+    request.SetHttpHeaderField(
         "Accept-Language",
         AtomicString(network_utils::GenerateAcceptLanguageHeader(
             accept_language_override_.Get())));
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
index a73712b..4a041e0 100644
--- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -862,7 +862,7 @@
         request.SetHTTPReferrer(
             Referrer(value, network::mojom::ReferrerPolicy::kAlways));
       } else {
-        request.SetHTTPHeaderField(header_name, AtomicString(value));
+        request.SetHttpHeaderField(header_name, AtomicString(value));
       }
     }
   }
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
index 0d0684be..b0bd7f0 100644
--- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -116,6 +116,52 @@
   return "inspect_tool_highlight.html";
 }
 
+bool InspectTool::HandleInputEvent(LocalFrameView* frame_view,
+                                   const WebInputEvent& input_event,
+                                   bool* swallow_next_mouse_up,
+                                   bool* swallow_next_escape_up) {
+  if (input_event.GetType() == WebInputEvent::kGestureTap) {
+    // We only have a use for gesture tap.
+    WebGestureEvent transformed_event = TransformWebGestureEvent(
+        frame_view, static_cast<const WebGestureEvent&>(input_event));
+    return HandleGestureTapEvent(transformed_event);
+  }
+
+  if (WebInputEvent::IsMouseEventType(input_event.GetType())) {
+    WebMouseEvent transformed_event = TransformWebMouseEvent(
+        frame_view, static_cast<const WebMouseEvent&>(input_event));
+    return HandleMouseEvent(transformed_event, swallow_next_mouse_up);
+  }
+
+  if (WebInputEvent::IsPointerEventType(input_event.GetType())) {
+    WebPointerEvent transformed_event = TransformWebPointerEvent(
+        frame_view, static_cast<const WebPointerEvent&>(input_event));
+    return HandlePointerEvent(transformed_event);
+  }
+
+  if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) {
+    return HandleKeyboardEvent(
+        static_cast<const WebKeyboardEvent&>(input_event),
+        swallow_next_escape_up);
+  }
+
+  return false;
+}
+
+bool InspectTool::HandleMouseEvent(const WebMouseEvent& mouse_event,
+                                   bool* swallow_next_mouse_up) {
+  if (mouse_event.GetType() == WebInputEvent::kMouseMove)
+    return HandleMouseMove(mouse_event);
+
+  if (mouse_event.GetType() == WebInputEvent::kMouseDown)
+    return HandleMouseDown(mouse_event, swallow_next_mouse_up);
+
+  if (mouse_event.GetType() == WebInputEvent::kMouseUp)
+    return HandleMouseUp(mouse_event);
+
+  return false;
+}
+
 bool InspectTool::HandleMouseDown(const WebMouseEvent&,
                                   bool* swallow_next_mouse_up) {
   return false;
@@ -634,136 +680,86 @@
   if (!inspect_tool_)
     return WebInputEventResult::kNotHandled;
 
-  if (input_event.GetType() == WebInputEvent::kGestureTap) {
-    // We only have a use for gesture tap.
-    WebGestureEvent transformed_event = TransformWebGestureEvent(
-        frame_impl_->GetFrameView(),
-        static_cast<const WebGestureEvent&>(input_event));
-    return HandleGestureTapEvent(transformed_event);
-  }
+  bool handled = inspect_tool_->HandleInputEvent(
+      frame_impl_->GetFrameView(), input_event, &swallow_next_mouse_up_,
+      &swallow_next_escape_up_);
 
-  if (WebInputEvent::IsMouseEventType(input_event.GetType())) {
-    WebMouseEvent transformed_event =
-        TransformWebMouseEvent(frame_impl_->GetFrameView(),
-                               static_cast<const WebMouseEvent&>(input_event));
-    return HandleMouseEvent(transformed_event);
-  }
-
-  if (WebInputEvent::IsPointerEventType(input_event.GetType())) {
-    WebPointerEvent transformed_event = TransformWebPointerEvent(
-        frame_impl_->GetFrameView(),
-        static_cast<const WebPointerEvent&>(input_event));
-    return HandlePointerEvent(transformed_event);
-  }
-
-  if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) {
-    return HandleKeyboardEvent(
-        static_cast<const WebKeyboardEvent&>(input_event));
-  }
-
-  if (input_event.GetType() == WebInputEvent::kMouseWheel) {
-    WebMouseWheelEvent transformed_event = TransformWebMouseWheelEvent(
-        frame_impl_->GetFrameView(),
-        static_cast<const WebMouseWheelEvent&>(input_event));
-    return HandleMouseWheelEvent(transformed_event);
-  }
-
-  return WebInputEventResult::kNotHandled;
-}
-
-WebInputEventResult InspectorOverlayAgent::HandleGestureTapEvent(
-    const WebGestureEvent& gesture_event) {
-  if (inspect_tool_->HandleGestureTapEvent(gesture_event)) {
-    ScheduleUpdate();
-    return WebInputEventResult::kHandledSuppressed;
-  }
-  if (!inspect_tool_->ForwardEventsToOverlay())
-    return WebInputEventResult::kNotHandled;
-
-  return OverlayMainFrame()->GetEventHandler().HandleGestureEvent(
-      gesture_event);
-}
-
-WebInputEventResult InspectorOverlayAgent::HandleMouseEvent(
-    const WebMouseEvent& mouse_event) {
-  bool handled = false;
-  if (mouse_event.GetType() == WebInputEvent::kMouseMove) {
-    handled = inspect_tool_->HandleMouseMove(mouse_event);
-  } else if (mouse_event.GetType() == WebInputEvent::kMouseDown) {
-    handled =
-        inspect_tool_->HandleMouseDown(mouse_event, &swallow_next_mouse_up_);
-  } else if (mouse_event.GetType() == WebInputEvent::kMouseUp) {
-    handled = inspect_tool_->HandleMouseUp(mouse_event);
-  }
-
-  if (handled) {
-    ScheduleUpdate();
-    return WebInputEventResult::kHandledSuppressed;
-  }
-
-  if (!inspect_tool_->ForwardEventsToOverlay())
-    return WebInputEventResult::kNotHandled;
-
-  if (mouse_event.GetType() == WebInputEvent::kMouseMove) {
-    return OverlayMainFrame()->GetEventHandler().HandleMouseMoveEvent(
-        mouse_event,
-        TransformWebMouseEventVector(frame_impl_->GetFrameView(),
-                                     std::vector<const WebInputEvent*>()),
-        TransformWebMouseEventVector(frame_impl_->GetFrameView(),
-                                     std::vector<const WebInputEvent*>()));
-  }
-  if (mouse_event.GetType() == WebInputEvent::kMouseDown) {
-    return OverlayMainFrame()->GetEventHandler().HandleMousePressEvent(
-        mouse_event);
-  }
-  if (mouse_event.GetType() == WebInputEvent::kMouseUp) {
-    return OverlayMainFrame()->GetEventHandler().HandleMouseReleaseEvent(
-        mouse_event);
-  }
-  return WebInputEventResult::kNotHandled;
-}
-
-WebInputEventResult InspectorOverlayAgent::HandlePointerEvent(
-    const WebPointerEvent& pointer_event) {
-  bool handled = inspect_tool_->HandlePointerEvent(pointer_event);
-  if (handled) {
-    ScheduleUpdate();
-    return WebInputEventResult::kHandledSuppressed;
-  }
-
-  if (!inspect_tool_->ForwardEventsToOverlay())
-    return WebInputEventResult::kNotHandled;
-
-  return OverlayMainFrame()->GetEventHandler().HandlePointerEvent(
-      pointer_event, Vector<WebPointerEvent>(), Vector<WebPointerEvent>());
-}
-
-WebInputEventResult InspectorOverlayAgent::HandleKeyboardEvent(
-    const WebKeyboardEvent& keyboard_event) {
-  bool handled = inspect_tool_->HandleKeyboardEvent(keyboard_event,
-                                                    &swallow_next_escape_up_);
   if (handled) {
     ScheduleUpdate();
     return WebInputEventResult::kHandledSuppressed;
   }
 
   // Exit tool upon unhandled Esc.
-  if (keyboard_event.GetType() == WebInputEvent::kRawKeyDown) {
+  if (input_event.GetType() == WebInputEvent::kRawKeyDown) {
+    const WebKeyboardEvent& keyboard_event =
+        static_cast<const WebKeyboardEvent&>(input_event);
     if (keyboard_event.windows_key_code == VKEY_ESCAPE) {
       GetFrontend()->inspectModeCanceled();
       swallow_next_escape_up_ = true;
       return WebInputEventResult::kHandledSuppressed;
     }
   }
+
   if (!inspect_tool_->ForwardEventsToOverlay())
     return WebInputEventResult::kNotHandled;
-
-  return OverlayMainFrame()->GetEventHandler().KeyEvent(keyboard_event);
+  return HandleInputEventInOverlay(input_event);
 }
 
-WebInputEventResult InspectorOverlayAgent::HandleMouseWheelEvent(
-    const WebMouseWheelEvent& wheel_event) {
-  return OverlayMainFrame()->GetEventHandler().HandleWheelEvent(wheel_event);
+WebInputEventResult InspectorOverlayAgent::HandleInputEventInOverlay(
+    const WebInputEvent& input_event) {
+  if (input_event.GetType() == WebInputEvent::kGestureTap) {
+    // We only have a use for gesture tap.
+    WebGestureEvent transformed_event = TransformWebGestureEvent(
+        frame_impl_->GetFrameView(),
+        static_cast<const WebGestureEvent&>(input_event));
+    return OverlayMainFrame()->GetEventHandler().HandleGestureEvent(
+        transformed_event);
+  }
+
+  if (WebInputEvent::IsMouseEventType(input_event.GetType())) {
+    WebMouseEvent mouse_event =
+        TransformWebMouseEvent(frame_impl_->GetFrameView(),
+                               static_cast<const WebMouseEvent&>(input_event));
+    if (mouse_event.GetType() == WebInputEvent::kMouseMove) {
+      return OverlayMainFrame()->GetEventHandler().HandleMouseMoveEvent(
+          mouse_event,
+          TransformWebMouseEventVector(frame_impl_->GetFrameView(),
+                                       std::vector<const WebInputEvent*>()),
+          TransformWebMouseEventVector(frame_impl_->GetFrameView(),
+                                       std::vector<const WebInputEvent*>()));
+    }
+    if (mouse_event.GetType() == WebInputEvent::kMouseDown) {
+      return OverlayMainFrame()->GetEventHandler().HandleMousePressEvent(
+          mouse_event);
+    }
+    if (mouse_event.GetType() == WebInputEvent::kMouseUp) {
+      return OverlayMainFrame()->GetEventHandler().HandleMouseReleaseEvent(
+          mouse_event);
+    }
+    return WebInputEventResult::kNotHandled;
+  }
+
+  if (WebInputEvent::IsPointerEventType(input_event.GetType())) {
+    WebPointerEvent pointer_event = TransformWebPointerEvent(
+        frame_impl_->GetFrameView(),
+        static_cast<const WebPointerEvent&>(input_event));
+    return OverlayMainFrame()->GetEventHandler().HandlePointerEvent(
+        pointer_event, Vector<WebPointerEvent>(), Vector<WebPointerEvent>());
+  }
+
+  if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) {
+    return OverlayMainFrame()->GetEventHandler().KeyEvent(
+        static_cast<const WebKeyboardEvent&>(input_event));
+  }
+
+  if (input_event.GetType() == WebInputEvent::kMouseWheel) {
+    WebMouseWheelEvent wheel_event = TransformWebMouseWheelEvent(
+        frame_impl_->GetFrameView(),
+        static_cast<const WebMouseWheelEvent&>(input_event));
+    return OverlayMainFrame()->GetEventHandler().HandleWheelEvent(wheel_event);
+  }
+
+  return WebInputEventResult::kNotHandled;
 }
 
 void InspectorOverlayAgent::ScheduleUpdate() {
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
index f77de45..097e62e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
@@ -54,17 +54,17 @@
 
 namespace blink {
 
+class FrameOverlay;
 class GraphicsContext;
 class InspectedFrames;
 class InspectorDOMAgent;
 class LocalFrame;
+class LocalFrameView;
 class Node;
 class Page;
-class FrameOverlay;
 class WebGestureEvent;
 class WebKeyboardEvent;
 class WebMouseEvent;
-class WebMouseWheelEvent;
 class WebLocalFrameImpl;
 class WebPointerEvent;
 
@@ -77,6 +77,12 @@
   virtual ~InspectTool() = default;
   void Init(InspectorOverlayAgent* overlay, OverlayFrontend* frontend);
   virtual CString GetDataResourceName();
+  virtual bool HandleInputEvent(LocalFrameView* frame_view,
+                                const WebInputEvent& input_event,
+                                bool* swallow_next_mouse_up,
+                                bool* swallow_next_escape_up);
+  virtual bool HandleMouseEvent(const WebMouseEvent&,
+                                bool* swallow_next_mouse_up);
   virtual bool HandleMouseDown(const WebMouseEvent&,
                                bool* swallow_next_mouse_up);
   virtual bool HandleMouseUp(const WebMouseEvent&);
@@ -159,6 +165,7 @@
   void Inspect(Node*);
   void DispatchBufferedTouchEvents();
   WebInputEventResult HandleInputEvent(const WebInputEvent&);
+  WebInputEventResult HandleInputEventInOverlay(const WebInputEvent&);
   void PageLayoutInvalidated(bool resized);
   void EvaluateInOverlay(const String& method, const String& argument);
   void EvaluateInOverlay(const String& method,
@@ -173,6 +180,7 @@
 
   LocalFrame* GetFrame() const;
   float WindowToViewportScale() const;
+  void ScheduleUpdate();
 
  private:
   class InspectorOverlayChromeClient;
@@ -190,7 +198,6 @@
   void OnTimer(TimerBase*);
   void UpdateOverlayPage();
   void RebuildOverlayPage();
-  void ScheduleUpdate();
 
   protocol::Response CompositingEnabled();
 
@@ -204,14 +211,6 @@
       protocol::Maybe<protocol::Overlay::HighlightConfig>
           highlight_inspector_object,
       std::unique_ptr<InspectorHighlightConfig>*);
-  WebInputEventResult HandleGestureTapEvent(
-      const WebGestureEvent& gesture_event);
-  WebInputEventResult HandleMouseEvent(const WebMouseEvent& mouse_event);
-  WebInputEventResult HandlePointerEvent(const WebPointerEvent& pointer_event);
-  WebInputEventResult HandleKeyboardEvent(
-      const WebKeyboardEvent& keyboard_event);
-  WebInputEventResult HandleMouseWheelEvent(
-      const WebMouseWheelEvent& wheel_event);
 
   Member<WebLocalFrameImpl> frame_impl_;
   Member<InspectedFrames> inspected_frames_;
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.cc b/third_party/blink/renderer/core/loader/base_fetch_context.cc
index ef54735..c00108c 100644
--- a/third_party/blink/renderer/core/loader/base_fetch_context.cc
+++ b/third_party/blink/renderer/core/loader/base_fetch_context.cc
@@ -165,7 +165,7 @@
         OriginAccessEntry access_entry(
             request.Url().Protocol(), request.Url().Host(),
             network::mojom::CorsOriginAccessMatchMode::
-                kAllowRegisterableDomains);
+                kAllowRegistrableDomains);
         if (access_entry.MatchesOrigin(
                 *fetch_client_settings_object.GetSecurityOrigin()) ==
             network::cors::OriginAccessEntry::kMatchesOrigin) {
diff --git a/third_party/blink/renderer/core/loader/document_loader_test.cc b/third_party/blink/renderer/core/loader/document_loader_test.cc
index 7b85aef..d9ae91d7 100644
--- a/third_party/blink/renderer/core/loader/document_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/document_loader_test.cc
@@ -199,7 +199,7 @@
       url_test_helpers::ToKURL("https://examplenoupgrade.com/foo.html");
   WebURLResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField("mixed-content", "noupgrade");
+  response.SetHttpHeaderField("mixed-content", "noupgrade");
   url_test_helpers::RegisterMockedURLLoadWithCustomResponse(
       url, test::CoreTestDataPath("foo.html"), response);
   WebViewImpl* web_view_impl = web_view_helper_.InitializeAndLoad(
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 f2a0f31a..fed793c 100644
--- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc
+++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -318,7 +318,7 @@
     request.ClearHttpHeaderField(http_names::kSaveData);
 
   if (save_data_enabled_)
-    request.SetHTTPHeaderField(http_names::kSaveData, "on");
+    request.SetHttpHeaderField(http_names::kSaveData, "on");
 
   if (GetLocalFrameClient()->GetPreviewsStateForFrame() &
       WebURLRequest::kNoScriptOn) {
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 b8fceadd..2dc6d824 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
@@ -967,7 +967,7 @@
   // Conditional request
   document->Loader()->SetLoadType(WebFrameLoadType::kStandard);
   ResourceRequest conditional("http://www.example.com/mock");
-  conditional.SetHTTPHeaderField(http_names::kIfModifiedSince, "foo");
+  conditional.SetHttpHeaderField(http_names::kIfModifiedSince, "foo");
   EXPECT_EQ(mojom::FetchCacheMode::kValidateCache,
             GetFetchContext()->ResourceRequestCachePolicy(
                 conditional, ResourceType::kMock, FetchParameters::kNoDefer));
@@ -1441,7 +1441,7 @@
 
   // Verify appended to an existing "Intervention" header value.
   ResourceRequest resource_request2("http://www.example.com/getad.js");
-  resource_request2.SetHTTPHeaderField("Intervention",
+  resource_request2.SetHttpHeaderField("Intervention",
                                        "<https://otherintervention.org>");
   GetFetchContext()->AddAdditionalRequestHeaders(resource_request2);
   EXPECT_EQ(
@@ -1472,7 +1472,7 @@
 
   // Verify appended to an existing "Intervention" header value.
   ResourceRequest resource_request2("http://www.example.com/getad.js");
-  resource_request2.SetHTTPHeaderField("Intervention",
+  resource_request2.SetHttpHeaderField("Intervention",
                                        "<https://otherintervention.org>");
   GetFetchContext()->AddAdditionalRequestHeaders(resource_request2);
   EXPECT_EQ(
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 34ba3ab..58260bb 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -1658,7 +1658,7 @@
   if (!RequiredCSP().IsEmpty()) {
     DCHECK(
         ContentSecurityPolicy::IsValidCSPAttr(RequiredCSP().GetString(), ""));
-    resource_request.SetHTTPHeaderField(http_names::kSecRequiredCSP,
+    resource_request.SetHttpHeaderField(http_names::kSecRequiredCSP,
                                         RequiredCSP());
   }
 
@@ -1672,7 +1672,7 @@
       return;
     }
 
-    resource_request.SetHTTPHeaderField(http_names::kUpgradeInsecureRequests,
+    resource_request.SetHttpHeaderField(http_names::kUpgradeInsecureRequests,
                                         "1");
   }
 
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc
index f9774028..d8dcc9f 100644
--- a/third_party/blink/renderer/core/loader/image_loader.cc
+++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -517,7 +517,7 @@
     bool page_is_being_dismissed =
         document.PageDismissalEventBeingDispatched() != Document::kNoDismissal;
     if (page_is_being_dismissed) {
-      resource_request.SetHTTPHeaderField(http_names::kCacheControl,
+      resource_request.SetHttpHeaderField(http_names::kCacheControl,
                                           "max-age=0");
       resource_request.SetKeepalive(true);
       resource_request.SetRequestContext(mojom::RequestContextType::PING);
@@ -932,7 +932,7 @@
   UseCounter::Count(GetElement()->GetDocument(), WebFeature::kImageDecodeAPI);
 
   auto* request = MakeGarbageCollected<DecodeRequest>(
-      this, ScriptPromiseResolver::Create(script_state));
+      this, MakeGarbageCollected<ScriptPromiseResolver>(script_state));
   Microtask::EnqueueMicrotask(
       WTF::Bind(&DecodeRequest::ProcessForTask, WrapWeakPersistent(request)));
   decode_requests_.push_back(request);
diff --git a/third_party/blink/renderer/core/loader/ping_loader.cc b/third_party/blink/renderer/core/loader/ping_loader.cc
index c3fa424b0..77ce4b0 100644
--- a/third_party/blink/renderer/core/loader/ping_loader.cc
+++ b/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -214,14 +214,14 @@
   request.SetHTTPMethod(http_names::kPOST);
   request.SetHTTPContentType("text/ping");
   request.SetHTTPBody(EncodedFormData::Create("PING"));
-  request.SetHTTPHeaderField(http_names::kCacheControl, "max-age=0");
-  request.SetHTTPHeaderField(http_names::kPingTo,
+  request.SetHttpHeaderField(http_names::kCacheControl, "max-age=0");
+  request.SetHttpHeaderField(http_names::kPingTo,
                              AtomicString(destination_url.GetString()));
   scoped_refptr<const SecurityOrigin> ping_origin =
       SecurityOrigin::Create(ping_url);
   if (ProtocolIs(frame->GetDocument()->Url().GetString(), "http") ||
       frame->GetDocument()->GetSecurityOrigin()->CanAccess(ping_origin.get())) {
-    request.SetHTTPHeaderField(
+    request.SetHttpHeaderField(
         http_names::kPingFrom,
         AtomicString(frame->GetDocument()->Url().GetString()));
   }
diff --git a/third_party/blink/renderer/core/loader/resource/font_resource_test.cc b/third_party/blink/renderer/core/loader/resource/font_resource_test.cc
index 6137615a..20cc22b1 100644
--- a/third_party/blink/renderer/core/loader/resource/font_resource_test.cc
+++ b/third_party/blink/renderer/core/loader/resource/font_resource_test.cc
@@ -44,7 +44,7 @@
   KURL url("http://127.0.0.1:8000/font.woff");
   ResourceResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(http_names::kETag, "1234567890");
+  response.SetHttpHeaderField(http_names::kETag, "1234567890");
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       url, WrappedResourceResponse(response), "");
 
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 3b004bf..a5df7c6 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
@@ -279,7 +279,7 @@
   resource_response.SetExpectedContentLength(
       kJpegImageSubrangeWithDimensionsLength);
   resource_response.SetHttpStatusCode(206);
-  resource_response.SetHTTPHeaderField(
+  resource_response.SetHttpHeaderField(
       "content-range", BuildContentRange(kJpegImageSubrangeWithDimensionsLength,
                                          sizeof(kJpegImage)));
   image_resource->Loader()->DidReceiveResponse(
@@ -383,7 +383,7 @@
   // flagged as multipart.
   ResourceResponse multipart_response(NullURL());
   multipart_response.SetMimeType("multipart/x-mixed-replace");
-  multipart_response.SetHTTPHeaderField(
+  multipart_response.SetHttpHeaderField(
       http_names::kContentType, "multipart/x-mixed-replace; boundary=boundary");
   image_resource->Loader()->DidReceiveResponse(
       WrappedResourceResponse(multipart_response), nullptr);
@@ -464,7 +464,7 @@
 
   ResourceResponse multipart_response(NullURL());
   multipart_response.SetMimeType("multipart/x-mixed-replace");
-  multipart_response.SetHTTPHeaderField(
+  multipart_response.SetHttpHeaderField(
       http_names::kContentType, "multipart/x-mixed-replace; boundary=boundary");
   image_resource->Loader()->DidReceiveResponse(
       WrappedResourceResponse(multipart_response), nullptr);
@@ -1346,7 +1346,7 @@
   ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
 
   ResourceRequest resource_request(test_url);
-  resource_request.SetHTTPHeaderField("range", "bytes=0-2");
+  resource_request.SetHttpHeaderField("range", "bytes=0-2");
   FetchParameters params(resource_request);
   ResourceFetcher* fetcher = CreateFetcher();
   ImageResource* image_resource = ImageResource::Fetch(params, fetcher);
@@ -1358,7 +1358,7 @@
   partial_response.SetExpectedContentLength(
       kJpegImageSubrangeWithoutDimensionsLength);
   partial_response.SetHttpStatusCode(206);
-  partial_response.SetHTTPHeaderField(
+  partial_response.SetHttpHeaderField(
       "content-range",
       BuildContentRange(kJpegImageSubrangeWithoutDimensionsLength,
                         sizeof(kJpegImage)));
@@ -1434,7 +1434,7 @@
   KURL test_url(kTestURL);
   ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
   ResourceRequest resource_request(test_url);
-  resource_request.SetHTTPHeaderField("range", "bytes=128-255");
+  resource_request.SetHttpHeaderField("range", "bytes=128-255");
   FetchParameters params(resource_request);
   params.SetAllowImagePlaceholder();
   ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
@@ -1483,7 +1483,7 @@
   bad_response.SetMimeType("image/jpeg");
   bad_response.SetExpectedContentLength(sizeof(kBadData));
   bad_response.SetHttpStatusCode(206);
-  bad_response.SetHTTPHeaderField(
+  bad_response.SetHttpHeaderField(
       "content-range", BuildContentRange(sizeof(kBadData), sizeof(kJpegImage)));
 
   image_resource->Loader()->DidReceiveResponse(
@@ -1527,7 +1527,7 @@
   bad_response.SetMimeType("image/jpeg");
   bad_response.SetExpectedContentLength(sizeof(kBadData));
   bad_response.SetHttpStatusCode(206);
-  bad_response.SetHTTPHeaderField(
+  bad_response.SetHttpHeaderField(
       "content-range", BuildContentRange(sizeof(kBadData), sizeof(kJpegImage)));
 
   image_resource->Loader()->DidReceiveResponse(
@@ -1591,7 +1591,7 @@
     partial_response.SetExpectedContentLength(
         kJpegImageSubrangeWithoutDimensionsLength);
     partial_response.SetHttpStatusCode(206);
-    partial_response.SetHTTPHeaderField(
+    partial_response.SetHttpHeaderField(
         "content-range",
         BuildContentRange(kJpegImageSubrangeWithoutDimensionsLength,
                           sizeof(kJpegImage)));
@@ -1742,7 +1742,7 @@
     resource_response.SetExpectedContentLength(sizeof(kJpegImage));
     resource_response.SetHttpStatusCode(test.status_code);
     if (test.content_range != g_null_atom)
-      resource_response.SetHTTPHeaderField("content-range", test.content_range);
+      resource_response.SetHttpHeaderField("content-range", test.content_range);
     image_resource->Loader()->DidReceiveResponse(
         WrappedResourceResponse(resource_response));
     image_resource->Loader()->DidReceiveData(
@@ -1803,7 +1803,7 @@
     resource_response.SetExpectedContentLength(test.data_size);
     resource_response.SetHttpStatusCode(test.status_code);
     if (test.content_range != g_null_atom)
-      resource_response.SetHTTPHeaderField("content-range", test.content_range);
+      resource_response.SetHttpHeaderField("content-range", test.content_range);
     image_resource->Loader()->DidReceiveResponse(
         WrappedResourceResponse(resource_response));
     image_resource->Loader()->DidReceiveData(kBadImageData, test.data_size);
diff --git a/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc b/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc
index e21397f..b750554 100644
--- a/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc
+++ b/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc
@@ -5,8 +5,8 @@
 #include "third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.h"
 
 #include "third_party/blink/renderer/platform/network/http_parsers.h"
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
 
 #include <algorithm>
 
diff --git a/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser_test.cc b/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser_test.cc
index 2a6b3e22..711fed3 100644
--- a/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser_test.cc
+++ b/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser_test.cc
@@ -86,8 +86,8 @@
 TEST(MultipartResponseTest, NoStartBoundary) {
   ResourceResponse response(NullURL());
   response.SetMimeType("multipart/x-mixed-replace");
-  response.SetHTTPHeaderField("Foo", "Bar");
-  response.SetHTTPHeaderField("Content-type", "text/plain");
+  response.SetHttpHeaderField("Foo", "Bar");
+  response.SetHttpHeaderField("Content-type", "text/plain");
   MockClient* client = MakeGarbageCollected<MockClient>();
   Vector<char> boundary;
   boundary.Append("bound", 5);
@@ -114,8 +114,8 @@
 TEST(MultipartResponseTest, NoEndBoundary) {
   ResourceResponse response(NullURL());
   response.SetMimeType("multipart/x-mixed-replace");
-  response.SetHTTPHeaderField("Foo", "Bar");
-  response.SetHTTPHeaderField("Content-type", "text/plain");
+  response.SetHttpHeaderField("Foo", "Bar");
+  response.SetHttpHeaderField("Content-type", "text/plain");
   MockClient* client = MakeGarbageCollected<MockClient>();
   Vector<char> boundary;
   boundary.Append("bound", 5);
@@ -140,8 +140,8 @@
 TEST(MultipartResponseTest, NoStartAndEndBoundary) {
   ResourceResponse response(NullURL());
   response.SetMimeType("multipart/x-mixed-replace");
-  response.SetHTTPHeaderField("Foo", "Bar");
-  response.SetHTTPHeaderField("Content-type", "text/plain");
+  response.SetHttpHeaderField("Foo", "Bar");
+  response.SetHttpHeaderField("Content-type", "text/plain");
   MockClient* client = MakeGarbageCollected<MockClient>();
   Vector<char> boundary;
   boundary.Append("bound", 5);
@@ -167,8 +167,8 @@
   // Some servers send a boundary that is prefixed by "--".  See bug 5786.
   ResourceResponse response(NullURL());
   response.SetMimeType("multipart/x-mixed-replace");
-  response.SetHTTPHeaderField("Foo", "Bar");
-  response.SetHTTPHeaderField("Content-type", "text/plain");
+  response.SetHttpHeaderField("Foo", "Bar");
+  response.SetHttpHeaderField("Content-type", "text/plain");
   MockClient* client = MakeGarbageCollected<MockClient>();
   Vector<char> boundary;
   boundary.Append("--bound", 7);
@@ -321,7 +321,7 @@
 TEST(MultipartResponseTest, SmallChunk) {
   ResourceResponse response(NullURL());
   response.SetMimeType("multipart/x-mixed-replace");
-  response.SetHTTPHeaderField("Content-type", "text/plain");
+  response.SetHttpHeaderField("Content-type", "text/plain");
   MockClient* client = MakeGarbageCollected<MockClient>();
   Vector<char> boundary;
   boundary.Append("bound", 5);
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc
index 8a573da6..f83eab0 100644
--- a/third_party/blink/renderer/core/loader/threadable_loader.cc
+++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -163,7 +163,7 @@
   std::unique_ptr<ResourceRequest> preflight_request =
       std::make_unique<ResourceRequest>(request_url);
   preflight_request->SetHTTPMethod(http_names::kOPTIONS);
-  preflight_request->SetHTTPHeaderField(http_names::kAccessControlRequestMethod,
+  preflight_request->SetHttpHeaderField(http_names::kAccessControlRequestMethod,
                                         request.HttpMethod());
   preflight_request->SetPriority(request.Priority());
   preflight_request->SetRequestContext(request.GetRequestContext());
@@ -174,14 +174,14 @@
   preflight_request->SetReferrerPolicy(request.GetReferrerPolicy());
 
   if (request.IsExternalRequest()) {
-    preflight_request->SetHTTPHeaderField(
+    preflight_request->SetHttpHeaderField(
         http_names::kAccessControlRequestExternal, "true");
   }
 
   const AtomicString request_headers =
       CreateAccessControlRequestHeadersHeader(request.HttpHeaderFields());
   if (request_headers != g_null_atom) {
-    preflight_request->SetHTTPHeaderField(
+    preflight_request->SetHttpHeaderField(
         http_names::kAccessControlRequestHeaders, request_headers);
   }
 
@@ -712,7 +712,7 @@
   // Add any request headers which we previously saved from the
   // original request.
   for (const auto& header : request_headers_)
-    cross_origin_request.SetHTTPHeaderField(header.key, header.value);
+    cross_origin_request.SetHttpHeaderField(header.key, header.value);
   cross_origin_request.SetReportUploadProgress(report_upload_progress_);
   MakeCrossOriginAccessRequest(cross_origin_request);
 
diff --git a/third_party/blink/renderer/core/loader/worker_fetch_context.cc b/third_party/blink/renderer/core/loader/worker_fetch_context.cc
index ce2662b..55c9c9af 100644
--- a/third_party/blink/renderer/core/loader/worker_fetch_context.cc
+++ b/third_party/blink/renderer/core/loader/worker_fetch_context.cc
@@ -212,7 +212,7 @@
     return;
 
   if (save_data_enabled_)
-    request.SetHTTPHeaderField(http_names::kSaveData, "on");
+    request.SetHttpHeaderField(http_names::kSaveData, "on");
 }
 
 void WorkerFetchContext::DispatchWillSendRequest(
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 efeb3fa..c521281 100644
--- a/third_party/blink/renderer/core/paint/link_highlight_impl.cc
+++ b/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -357,9 +357,8 @@
       (kFadeDuration + extra_duration_required).InSecondsF(),
       WebTestSupport::IsRunningWebTest() ? kStartOpacity : 0, timing_function));
 
-  std::unique_ptr<CompositorKeyframeModel> keyframe_model =
-      CompositorKeyframeModel::Create(
-          *curve, compositor_target_property::OPACITY, 0, 0);
+  auto keyframe_model = std::make_unique<CompositorKeyframeModel>(
+      *curve, compositor_target_property::OPACITY, 0, 0);
 
   compositor_animation_->AddKeyframeModel(std::move(keyframe_model));
 
diff --git a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
index 94fffe6..8ddfcd8 100644
--- a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
@@ -961,7 +961,8 @@
   EXPECT_FALSE(layer->NeedsRepaint());
   const auto* transform =
       object->FirstFragment().PaintProperties()->Transform();
-  EXPECT_TRUE(transform->Changed(*transform->Parent()));
+  EXPECT_TRUE(transform->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                 *transform->Parent()));
 
   UpdateAllLifecyclePhasesForTest();
   EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
@@ -972,7 +973,8 @@
                   RasterInvalidationInfo{
                       layer, layer->DebugName(), IntRect(0, 0, 150, 300),
                       PaintInvalidationReason::kPaintProperty}));
-  EXPECT_FALSE(transform->Changed(*transform->Parent()));
+  EXPECT_FALSE(transform->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                  *transform->Parent()));
   GetDocument().View()->SetTracksPaintInvalidations(false);
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index a10bef0..8e11e7dc 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -204,12 +204,10 @@
     property_changed_ = std::max(property_changed_, change);
   }
   // Like |OnUpdate| but sets |clip_changed| if the clip values change.
-  void OnUpdateClip(PaintPropertyChangeType change,
-                    bool only_updated_hit_test_values = false) {
+  void OnUpdateClip(PaintPropertyChangeType change) {
     OnUpdate(change);
     full_context_.clip_changed |=
-        (change != PaintPropertyChangeType::kUnchanged &&
-         !only_updated_hit_test_values);
+        change >= PaintPropertyChangeType::kChangedOnlyValues;
   }
   // Like |OnUpdate| but forces a piercing subtree update if the scroll tree
   // hierarchy changes because the scroll tree does not have isolation nodes
@@ -1506,13 +1504,8 @@
             viewport_container.LocalToSVGParentTransform().Inverse().MapRect(
                 viewport_container.Viewport()));
       }
-      const ClipPaintPropertyNode* existing = properties_->OverflowClip();
-      bool equal_ignoring_hit_test_rects =
-          !!existing &&
-          existing->EqualIgnoringHitTestRects(context_.current.clip, state);
       OnUpdateClip(properties_->UpdateOverflowClip(*context_.current.clip,
-                                                   std::move(state)),
-                   equal_ignoring_hit_test_rects);
+                                                   std::move(state)));
     } else {
       OnClearClip(properties_->ClearOverflowClip());
     }
diff --git a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
index c67641c..12fc9852 100644
--- a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
+++ b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
@@ -209,7 +209,7 @@
   modulator->SetExpectedFetchTreeURL(TestDependencyURL());
 
   auto* promise_resolver =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   ScriptPromise promise = promise_resolver->Promise();
 
   auto* capture = MakeGarbageCollected<CaptureExportedStringFunction>(
@@ -246,7 +246,7 @@
   modulator->SetExpectedFetchTreeURL(TestDependencyURL());
 
   auto* promise_resolver =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   ScriptPromise promise = promise_resolver->Promise();
 
   auto* capture =
@@ -272,7 +272,7 @@
   modulator->SetExpectedFetchTreeURL(TestDependencyURL());
 
   auto* promise_resolver =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   ScriptPromise promise = promise_resolver->Promise();
 
   auto* capture =
@@ -302,7 +302,7 @@
   modulator->SetExpectedFetchTreeURL(TestDependencyURL());
 
   auto* promise_resolver =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   ScriptPromise promise = promise_resolver->Promise();
 
   auto* capture =
@@ -341,7 +341,7 @@
   modulator->SetExpectedFetchTreeURL(TestDependencyURL());
 
   auto* promise_resolver =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   ScriptPromise promise = promise_resolver->Promise();
 
   auto* capture = MakeGarbageCollected<CaptureExportedStringFunction>(
@@ -381,7 +381,7 @@
       KURL("https://example.com/correct/dependency.js"));
 
   auto* promise_resolver =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   auto* resolver = DynamicModuleResolver::Create(modulator);
   KURL wrong_base_url("https://example.com/wrong/bar.js");
   KURL correct_base_url("https://example.com/correct/baz.js");
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 f9eb19a..ac67a734 100644
--- a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
+++ b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
@@ -132,10 +132,8 @@
     // crbug.com/730705
     if (!scrollable_area_->ShouldScrollOnMainThread() &&
         !is_sequenced_scroll_) {
-      std::unique_ptr<CompositorKeyframeModel> animation =
-          CompositorKeyframeModel::Create(
-              *animation_curve_, compositor_target_property::SCROLL_OFFSET, 0,
-              0);
+      auto animation = std::make_unique<CompositorKeyframeModel>(
+          *animation_curve_, compositor_target_property::SCROLL_OFFSET, 0, 0);
 
       int animation_id = animation->Id();
       int animation_group_id = animation->Group();
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator.cc b/third_party/blink/renderer/core/scroll/scroll_animator.cc
index fbdf749..6e5254a 100644
--- a/third_party/blink/renderer/core/scroll/scroll_animator.cc
+++ b/third_party/blink/renderer/core/scroll/scroll_animator.cc
@@ -266,9 +266,8 @@
   if (scrollable_area_->ShouldScrollOnMainThread())
     return false;
 
-  std::unique_ptr<CompositorKeyframeModel> animation =
-      CompositorKeyframeModel::Create(
-          *animation_curve_, compositor_target_property::SCROLL_OFFSET, 0, 0);
+  auto animation = std::make_unique<CompositorKeyframeModel>(
+      *animation_curve_, compositor_target_property::SCROLL_OFFSET, 0, 0);
   // Being here means that either there is an animation that needs
   // to be sent to the compositor, or an animation that needs to
   // be updated (a new scroll event before the previous animation
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index a8db95e..c4a5b44 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -1176,12 +1176,12 @@
     // TODO(ericwilligers): crbug.com/641245 Support <size> for ray paths.
     float float_distance = FloatValueForLength(distance, 0);
 
-    angle = ToStyleRay(*path).Angle() - 90;
+    angle = To<StyleRay>(*path).Angle() - 90;
     point.SetX(float_distance * cos(deg2rad(angle)));
     point.SetY(float_distance * sin(deg2rad(angle)));
   } else {
     float zoom = EffectiveZoom();
-    const StylePath& motion_path = ToStylePath(*path);
+    const StylePath& motion_path = To<StylePath>(*path);
     float path_length = motion_path.length();
     float float_distance =
         FloatValueForLength(distance, path_length * zoom) / zoom;
diff --git a/third_party/blink/renderer/core/style/style_path.cc b/third_party/blink/renderer/core/style/style_path.cc
index c6acccee4..1ada557 100644
--- a/third_party/blink/renderer/core/style/style_path.cc
+++ b/third_party/blink/renderer/core/style/style_path.cc
@@ -60,7 +60,7 @@
 bool StylePath::operator==(const BasicShape& o) const {
   if (!IsSameType(o))
     return false;
-  const StylePath& other = ToStylePath(o);
+  const StylePath& other = To<StylePath>(o);
   return *byte_stream_ == *other.byte_stream_;
 }
 
diff --git a/third_party/blink/renderer/core/style/style_path.h b/third_party/blink/renderer/core/style/style_path.h
index 085aa62..5876df04 100644
--- a/third_party/blink/renderer/core/style/style_path.h
+++ b/third_party/blink/renderer/core/style/style_path.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/core/style/basic_shapes.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -43,7 +44,12 @@
   mutable float path_length_;
 };
 
-DEFINE_BASICSHAPE_TYPE_CASTS(StylePath);
+template <>
+struct DowncastTraits<StylePath> {
+  static bool AllowFrom(const BasicShape& value) {
+    return value.GetType() == BasicShape::kStylePathType;
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/style/style_ray.cc b/third_party/blink/renderer/core/style/style_ray.cc
index 1110685..891b194 100644
--- a/third_party/blink/renderer/core/style/style_ray.cc
+++ b/third_party/blink/renderer/core/style/style_ray.cc
@@ -18,7 +18,7 @@
 bool StyleRay::operator==(const BasicShape& o) const {
   if (!IsSameType(o))
     return false;
-  const StyleRay& other = ToStyleRay(o);
+  const StyleRay& other = To<StyleRay>(o);
   return angle_ == other.angle_ && size_ == other.size_ &&
          contain_ == other.contain_;
 }
diff --git a/third_party/blink/renderer/core/style/style_ray.h b/third_party/blink/renderer/core/style/style_ray.h
index 44ac2745..636b4d6 100644
--- a/third_party/blink/renderer/core/style/style_ray.h
+++ b/third_party/blink/renderer/core/style/style_ray.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_RAY_H_
 
 #include "third_party/blink/renderer/core/style/basic_shapes.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -39,7 +40,12 @@
   bool contain_;
 };
 
-DEFINE_BASICSHAPE_TYPE_CASTS(StyleRay);
+template <>
+struct DowncastTraits<StyleRay> {
+  static bool AllowFrom(const BasicShape& value) {
+    return value.GetType() == BasicShape::kStyleRayType;
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 8304844..3cd89e8 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -3121,7 +3121,7 @@
 
 ScriptPromise Internals::createResolvedPromise(ScriptState* script_state,
                                                ScriptValue value) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   resolver->Resolve(value);
   return promise;
@@ -3129,7 +3129,7 @@
 
 ScriptPromise Internals::createRejectedPromise(ScriptState* script_state,
                                                ScriptValue value) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   resolver->Reject(value);
   return promise;
@@ -3346,7 +3346,7 @@
 ScriptPromise Internals::observeUseCounter(ScriptState* script_state,
                                            Document* document,
                                            uint32_t feature) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (feature >= static_cast<int32_t>(WebFeature::kNumberOfFeatures)) {
     resolver->Reject();
diff --git a/third_party/blink/renderer/core/timing/performance_test.cc b/third_party/blink/renderer/core/timing/performance_test.cc
index 1f28fc5..39e7ebd 100644
--- a/third_party/blink/renderer/core/timing/performance_test.cc
+++ b/third_party/blink/renderer/core/timing/performance_test.cc
@@ -176,7 +176,7 @@
                                     GetExecutionContext()));
 
   // When cross-origin redirect opts in.
-  redirect_chain.back().SetHTTPHeaderField(http_names::kTimingAllowOrigin,
+  redirect_chain.back().SetHttpHeaderField(http_names::kTimingAllowOrigin,
                                            origin_domain);
   EXPECT_TRUE(AllowsTimingRedirect(redirect_chain, final_response,
                                    *security_origin.get(),
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
index 25fccab..a7cddad 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
@@ -31,7 +31,7 @@
     DedicatedWorker* worker_object)
     : ThreadedMessagingProxyBase(execution_context),
       worker_object_(worker_object) {
-  worker_object_proxy_ = DedicatedWorkerObjectProxy::Create(
+  worker_object_proxy_ = std::make_unique<DedicatedWorkerObjectProxy>(
       this, GetParentExecutionContextTaskRunners());
 }
 
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc b/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc
index efac768..548fc07 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc
@@ -53,14 +53,6 @@
 
 namespace blink {
 
-std::unique_ptr<DedicatedWorkerObjectProxy> DedicatedWorkerObjectProxy::Create(
-    DedicatedWorkerMessagingProxy* messaging_proxy_weak_ptr,
-    ParentExecutionContextTaskRunners* parent_execution_context_task_runners) {
-  DCHECK(messaging_proxy_weak_ptr);
-  return base::WrapUnique(new DedicatedWorkerObjectProxy(
-      messaging_proxy_weak_ptr, parent_execution_context_task_runners));
-}
-
 DedicatedWorkerObjectProxy::~DedicatedWorkerObjectProxy() = default;
 
 void DedicatedWorkerObjectProxy::PostMessageToWorkerObject(
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h b/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h
index b374607..39eb28c 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h
@@ -55,9 +55,8 @@
   USING_FAST_MALLOC(DedicatedWorkerObjectProxy);
 
  public:
-  static std::unique_ptr<DedicatedWorkerObjectProxy> Create(
-      DedicatedWorkerMessagingProxy*,
-      ParentExecutionContextTaskRunners*);
+  DedicatedWorkerObjectProxy(DedicatedWorkerMessagingProxy*,
+                             ParentExecutionContextTaskRunners*);
   ~DedicatedWorkerObjectProxy() override;
 
   void PostMessageToWorkerObject(BlinkTransferableMessage);
@@ -74,9 +73,6 @@
   void DidEvaluateModuleScript(bool success) override;
 
  protected:
-  DedicatedWorkerObjectProxy(DedicatedWorkerMessagingProxy*,
-                             ParentExecutionContextTaskRunners*);
-
   CrossThreadWeakPersistent<ThreadedMessagingProxyBase> MessagingProxyWeakPtr()
       final;
 
diff --git a/third_party/blink/renderer/core/workers/experimental/task.cc b/third_party/blink/renderer/core/workers/experimental/task.cc
index 6c3f55d..f3f271c 100644
--- a/third_party/blink/renderer/core/workers/experimental/task.cc
+++ b/third_party/blink/renderer/core/workers/experimental/task.cc
@@ -451,7 +451,7 @@
                nullptr,
                String(),
                exception_state),
-      resolver_(ScriptPromiseResolver::Create(script_state)) {
+      resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)) {
   DCHECK(IsMainThread());
   if (exception_state.HadException())
     return;
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
index ac5a23d..2189877 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -172,7 +172,7 @@
       worker_clients_(worker_clients),
       web_worker_fetch_context_(std::move(web_worker_fetch_context)),
       script_controller_(
-          WorkerOrWorkletScriptController::Create(this, isolate)),
+          MakeGarbageCollected<WorkerOrWorkletScriptController>(this, isolate)),
       v8_cache_options_(v8_cache_options),
       reporting_proxy_(reporting_proxy),
       used_features_(static_cast<int>(WebFeature::kNumberOfFeatures)) {
diff --git a/third_party/blink/renderer/core/workers/worklet.cc b/third_party/blink/renderer/core/workers/worklet.cc
index 6819c3d..fe86ebf 100644
--- a/third_party/blink/renderer/core/workers/worklet.cc
+++ b/third_party/blink/renderer/core/workers/worklet.cc
@@ -50,7 +50,7 @@
                     mojom::WebFeature::kWorkletAddModule);
 
   // Step 1: "Let promise be a new promise."
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // Step 2: "Let worklet be the current Worklet."
diff --git a/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc b/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
index 52b0450..232cf77 100644
--- a/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
+++ b/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
@@ -61,6 +61,7 @@
   button->accessibleNode()->setRole("slider");
   EXPECT_EQ("slider", button->accessibleNode()->role());
 
+  GetDocument().View()->UpdateLifecycleToLayoutClean();
   axButton = cache->GetOrCreate(button);
   EXPECT_EQ(ax::mojom::Role::kSlider, axButton->RoleValue());
 }
@@ -112,6 +113,7 @@
   // Assert that the AX object was affected by ARIA attributes.
   auto* cache = AXObjectCache();
   ASSERT_NE(nullptr, cache);
+  GetDocument().View()->UpdateLifecycleToLayoutClean();
   auto* axButton = cache->GetOrCreate(button);
   EXPECT_EQ(ax::mojom::Role::kCheckBox, axButton->RoleValue());
   ax::mojom::NameFrom name_from;
@@ -123,6 +125,7 @@
   button->accessibleNode()->setRole("radio");
   button->accessibleNode()->setLabel("Radio");
   button->accessibleNode()->setDisabled(false, false);
+  GetDocument().View()->UpdateLifecycleToLayoutClean();
 
   // Assert that the AX object was affected by AOM properties.
   axButton = cache->GetOrCreate(button);
@@ -134,6 +137,7 @@
   button->accessibleNode()->setRole(g_null_atom);
   button->accessibleNode()->setLabel(g_null_atom);
   button->accessibleNode()->setDisabled(false, true);
+  GetDocument().View()->UpdateLifecycleToLayoutClean();
 
   // The AX Object should now revert to ARIA.
   axButton = cache->GetOrCreate(button);
@@ -156,6 +160,7 @@
 
   auto* cache = AXObjectCache();
   ASSERT_NE(nullptr, cache);
+  GetDocument().View()->UpdateLifecycleToLayoutClean();
   auto* ax_slider = cache->GetOrCreate(slider);
   float value = 0.0f;
   EXPECT_TRUE(ax_slider->MinValueForRange(&value));
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
index a65910e..9a09a72 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -2588,7 +2588,8 @@
       // changed event must be fired. This ensures the AT is notified that the
       // selected state has changed, so that it does not read "unselected" as
       // the user navigates through the items.
-      AXObjectCache().HandleAriaSelectedChanged(active_descendant->GetNode());
+      AXObjectCache().HandleAriaSelectedChangedWithCleanLayout(
+          active_descendant->GetNode());
     }
 
     // Mark this node dirty. AXEventGenerator will automatically infer
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index daca6cab..83c3ad4 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -60,9 +60,9 @@
 #include "third_party/blink/renderer/platform/language.h"
 #include "third_party/blink/renderer/platform/text/platform_locale.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
 
 using blink::WebLocalizedString;
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 5aaa514..64634af4 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -92,6 +92,17 @@
 
 using namespace html_names;
 
+namespace {
+// Return a node for the current layout object or ancestor layout object.
+Node* GetClosestNodeForLayoutObject(LayoutObject* layout_object) {
+  if (!layout_object)
+    return nullptr;
+  Node* node = layout_object->GetNode();
+  return node ? node : GetClosestNodeForLayoutObject(layout_object->Parent());
+}
+
+}  // namespace
+
 // static
 AXObjectCache* AXObjectCacheImpl::Create(Document& document) {
   return MakeGarbageCollected<AXObjectCacheImpl>(document);
@@ -103,14 +114,12 @@
       modification_count_(0),
       validation_message_axid_(0),
       relation_cache_(std::make_unique<AXRelationCache>(this)),
-      notification_post_timer_(
-          document.GetTaskRunner(TaskType::kInternalDefault),
-          this,
-          &AXObjectCacheImpl::NotificationPostTimerFired),
       accessibility_event_permission_(mojom::PermissionStatus::ASK),
       permission_observer_binding_(this) {
   if (document_->LoadEventFinished())
     AddPermissionStatusListener();
+  documents_.insert(&document);
+  document.View()->RegisterForLifecycleNotifications(this);
 }
 
 AXObjectCacheImpl::~AXObjectCacheImpl() {
@@ -120,14 +129,18 @@
 }
 
 void AXObjectCacheImpl::Dispose() {
-  notification_post_timer_.Stop();
-
   for (auto& entry : objects_) {
     AXObject* obj = entry.value;
     obj->Detach();
     RemoveAXID(obj);
   }
 
+  for (auto document : documents_) {
+    if (!document || !document->View())
+      continue;
+    document->View()->UnregisterFromLifecycleNotifications(this);
+  }
+
 #if DCHECK_IS_ON()
   has_been_disposed_ = true;
 #endif
@@ -137,6 +150,22 @@
   return GetOrCreate(document_);
 }
 
+void AXObjectCacheImpl::InitializePopup(Document* document) {
+  if (!document || documents_.Contains(document) || document->View())
+    return;
+
+  documents_.insert(document);
+  document->View()->RegisterForLifecycleNotifications(this);
+}
+
+void AXObjectCacheImpl::DisposePopup(Document* document) {
+  if (documents_.Contains(document) || document->View())
+    return;
+
+  document->View()->UnregisterFromLifecycleNotifications(this);
+  documents_.erase(document);
+}
+
 AXObject* AXObjectCacheImpl::FocusedImageMapUIElement(
     HTMLAreaElement* area_element) {
   // Find the corresponding accessibility object for the HTMLAreaElement. This
@@ -686,10 +715,53 @@
   return AXObject::InOrderTraversalIterator();
 }
 
+void AXObjectCacheImpl::DeferTreeUpdateInternal(Node* node,
+                                                base::OnceClosure callback) {
+  tree_update_callback_queue_.push_back(
+      std::make_pair(WrapWeakPersistent(node), std::move(callback)));
+}
+
+void AXObjectCacheImpl::DeferTreeUpdate(
+    void (AXObjectCacheImpl::*method)(Node*),
+    Node* node) {
+  base::OnceClosure callback =
+      WTF::Bind(method, WrapWeakPersistent(this), WrapWeakPersistent(node));
+  DeferTreeUpdateInternal(node, std::move(callback));
+}
+
+void AXObjectCacheImpl::DeferTreeUpdate(
+    void (AXObjectCacheImpl::*method)(const QualifiedName&, Element* element),
+    const QualifiedName& attr_name,
+    Element* element) {
+  base::OnceClosure callback = WTF::Bind(
+      method, WrapWeakPersistent(this), attr_name, WrapWeakPersistent(element));
+  DeferTreeUpdateInternal(element, std::move(callback));
+}
+
+void AXObjectCacheImpl::DeferTreeUpdate(
+    void (AXObjectCacheImpl::*method)(Node*, AXObject*),
+    Node* node,
+    AXObject* obj) {
+  base::OnceClosure callback =
+      WTF::Bind(method, WrapWeakPersistent(this), WrapWeakPersistent(node),
+                WrapWeakPersistent(obj));
+  DeferTreeUpdateInternal(node, std::move(callback));
+}
+
 void AXObjectCacheImpl::SelectionChanged(Node* node) {
-  AXObject* nearestAncestor = NearestExistingAncestor(node);
-  if (nearestAncestor)
-    nearestAncestor->SelectionChanged();
+  if (!node)
+    return;
+
+  DeferTreeUpdate(&AXObjectCacheImpl::SelectionChangedWithCleanLayout, node);
+}
+
+void AXObjectCacheImpl::SelectionChangedWithCleanLayout(Node* node) {
+  if (!node)
+    return;
+
+  AXObject* ax_object = GetOrCreate(node);
+  if (ax_object)
+    ax_object->SelectionChanged();
 }
 
 void AXObjectCacheImpl::UpdateReverseRelations(
@@ -699,16 +771,30 @@
 }
 
 void AXObjectCacheImpl::TextChanged(Node* node) {
-  TextChanged(Get(node), node);
+  if (!node)
+    return;
+
+  DeferTreeUpdate(&AXObjectCacheImpl::TextChangedWithCleanLayout, node);
 }
 
 void AXObjectCacheImpl::TextChanged(LayoutObject* layout_object) {
-  if (layout_object)
-    TextChanged(Get(layout_object), layout_object->GetNode());
+  if (!layout_object)
+    return;
+
+  // TODO(aboxhall): audit calls to this and figure out when this is called
+  // when node might be null
+  Node* node = GetClosestNodeForLayoutObject(layout_object);
+  if (node) {
+    DeferTreeUpdate(&AXObjectCacheImpl::TextChangedWithCleanLayout, node);
+    return;
+  }
+
+  TextChanged(Get(layout_object), layout_object->GetNode());
 }
 
 void AXObjectCacheImpl::TextChanged(AXObject* obj,
                                     Node* node_for_relation_update) {
+  // TODO(aboxhall): Figure out when this may be called with dirty layout
   if (obj)
     obj->TextChanged();
 
@@ -718,7 +804,17 @@
   PostNotification(obj, ax::mojom::Event::kTextChanged);
 }
 
-void AXObjectCacheImpl::FocusableChanged(Element* element) {
+void AXObjectCacheImpl::TextChangedWithCleanLayout(Node* node) {
+  if (!node)
+    return;
+
+  DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
+  TextChanged(Get(node), node);
+}
+
+void AXObjectCacheImpl::FocusableChangedWithCleanLayout(Element* element) {
+  DCHECK(element);
+  DCHECK(!element->GetDocument().NeedsLayoutTreeUpdateForNode(*element));
   AXObject* obj = GetOrCreate(element);
   if (!obj)
     return;
@@ -727,7 +823,7 @@
     // Elements that are hidden but focusable are not ignored. Therefore, if a
     // hidden element's focusable state changes, it's ignored state must be
     // recomputed.
-    ChildrenChanged(element->parentNode());
+    ChildrenChangedWithCleanLayout(element->parentNode());
   } else {
     // Refresh the focusable state on the exposed object.
     MarkAXObjectDirty(obj, false);
@@ -736,6 +832,10 @@
 
 void AXObjectCacheImpl::DocumentTitleChanged() {
   PostNotification(Root(), ax::mojom::Event::kDocumentTitleChanged);
+  // If title changes at a point where paint is clean, send notification
+  // immediately.
+  if (document_->Lifecycle().GetState() >= DocumentLifecycle::kPaintClean)
+    PostNotificationsAfterLayout(document_);
 }
 
 void AXObjectCacheImpl::UpdateCacheAfterNodeIsAttached(Node* node) {
@@ -763,20 +863,8 @@
 void AXObjectCacheImpl::ChildrenChanged(Node* node) {
   if (!node)
     return;
-  if (node->GetDocument().IsFlatTreeTraversalForbidden() ||
-      node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)) {
-    nodes_changed_during_layout_.push_back(node);
-    return;
-  }
-  ChildrenChanged(Get(node), node);
-}
 
-// Return a node for the current layout object or ancestor layout object.
-Node* GetClosestNodeForLayoutObject(LayoutObject* layout_object) {
-  if (!layout_object)
-    return nullptr;
-  Node* node = layout_object->GetNode();
-  return node ? node : GetClosestNodeForLayoutObject(layout_object->Parent());
+  DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout, node);
 }
 
 void AXObjectCacheImpl::ChildrenChanged(LayoutObject* layout_object) {
@@ -785,10 +873,8 @@
 
   Node* node = GetClosestNodeForLayoutObject(layout_object);
 
-  if (node && (node->GetDocument().IsFlatTreeTraversalForbidden() ||
-               node->GetDocument().NeedsLayoutTreeUpdateForNode(*node) ||
-               node->NeedsDistributionRecalc())) {
-    nodes_changed_during_layout_.push_back(node);
+  if (node) {
+    DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout, node);
     return;
   }
 
@@ -799,18 +885,30 @@
 void AXObjectCacheImpl::ChildrenChanged(AccessibleNode* accessible_node) {
   if (!accessible_node)
     return;
-  Element* element = accessible_node->element();
-  if (element &&
-      (element->GetDocument().NeedsLayoutTreeUpdateForNode(*element) ||
-       element->NeedsDistributionRecalc())) {
-    nodes_changed_during_layout_.push_back(element);
-    return;
-  }
+
   AXObject* object = Get(accessible_node);
   ChildrenChanged(object, object ? object->GetNode() : nullptr);
 }
 
+void AXObjectCacheImpl::ChildrenChangedWithCleanLayout(Node* node) {
+  if (!node)
+    return;
+
+  DCHECK(node->GetDocument().Lifecycle().GetState() >=
+         DocumentLifecycle::kLayoutClean);
+#ifndef NDEBUG
+  if (node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)) {
+    LOG(ERROR) << "Node needs layout tree update: " << node;
+    node->ShowTreeForThisAcrossFrame();
+  }
+#endif
+  DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
+
+  ChildrenChanged(Get(node), node);
+}
+
 void AXObjectCacheImpl::ChildrenChanged(AXObject* obj, Node* optional_node) {
+  // TODO(aboxhall): Figure out when this may be called with dirty layout
   if (obj)
     obj->ChildrenChanged();
 
@@ -823,36 +921,27 @@
 void AXObjectCacheImpl::ProcessUpdatesAfterLayout(Document& document) {
   if (document.Lifecycle().GetState() < DocumentLifecycle::kLayoutClean)
     return;
-  VectorOf<Node> old_nodes_changed_during_layout;
-  nodes_changed_during_layout_.swap(old_nodes_changed_during_layout);
-  for (auto node : old_nodes_changed_during_layout) {
+  TreeUpdateCallbackQueue old_tree_update_callback_queue;
+  tree_update_callback_queue_.swap(old_tree_update_callback_queue);
+  for (auto& pair : old_tree_update_callback_queue) {
+    Node* node = pair.first;
+    if (!node)
+      continue;
+    base::OnceClosure& callback = pair.second;
     if (node->GetDocument() != document) {
-      nodes_changed_during_layout_.push_back(node);
+      tree_update_callback_queue_.push_back(
+          std::make_pair(WrapWeakPersistent(node), std::move(callback)));
       continue;
     }
-    ChildrenChanged(Get(node), node);
-  }
-
-  AttributesChangedVector old_attributes_changed_during_layout;
-  attributes_changed_during_layout_.swap(old_attributes_changed_during_layout);
-  for (auto pair : old_attributes_changed_during_layout) {
-    auto attribute_name = pair.first;
-    auto element = pair.second;
-    if (element->GetDocument() != document) {
-      attributes_changed_during_layout_.push_back(
-          std::make_pair(attribute_name, element));
-      continue;
-    }
-    HandleAttributeChanged(attribute_name, element);
+    std::move(callback).Run();
   }
 }
 
-void AXObjectCacheImpl::NotificationPostTimerFired(TimerBase*) {
-  notification_post_timer_.Stop();
-
-  unsigned i = 0, count = notifications_to_post_.size();
-  for (i = 0; i < count; ++i) {
-    AXObject* obj = notifications_to_post_[i].first;
+void AXObjectCacheImpl::PostNotificationsAfterLayout(Document* document) {
+  NotificationVector old_notifications_to_post;
+  notifications_to_post_.swap(old_notifications_to_post);
+  for (auto& pair : old_notifications_to_post) {
+    AXObject* obj = pair.first;
 
     if (!obj->AXObjectID())
       continue;
@@ -860,6 +949,12 @@
     if (obj->IsDetached())
       continue;
 
+    ax::mojom::Event notification = pair.second;
+    if (obj->GetDocument() != document) {
+      notifications_to_post_.push_back(std::make_pair(obj, notification));
+      continue;
+    }
+
 #if DCHECK_IS_ON()
     // Make sure none of the layout views are in the process of being layed out.
     // Notifications should only be sent after the layoutObject has finished
@@ -871,7 +966,6 @@
     }
 #endif
 
-    ax::mojom::Event notification = notifications_to_post_[i].second;
     PostPlatformNotification(obj, notification);
 
     if (notification == ax::mojom::Event::kChildrenChanged &&
@@ -879,8 +973,6 @@
         obj->LastKnownIsIgnoredValue() != obj->AccessibilityIsIgnored())
       ChildrenChanged(obj->ParentObject());
   }
-
-  notifications_to_post_.clear();
 }
 
 void AXObjectCacheImpl::PostNotification(LayoutObject* layout_object,
@@ -904,8 +996,6 @@
 
   modification_count_++;
   notifications_to_post_.push_back(std::make_pair(object, notification));
-  if (!notification_post_timer_.IsActive())
-    notification_post_timer_.StartOneShot(TimeDelta(), FROM_HERE);
 }
 
 bool AXObjectCacheImpl::IsAriaOwned(const AXObject* object) const {
@@ -993,17 +1083,25 @@
 void AXObjectCacheImpl::HandleAttributeChanged(
     const QualifiedName& attr_name,
     AccessibleNode* accessible_node) {
+  if (!accessible_node)
+    return;
   modification_count_++;
   if (AXObject* obj = Get(accessible_node))
     PostNotification(obj, ax::mojom::Event::kAriaAttributeChanged);
 }
 
-void AXObjectCacheImpl::HandleAriaExpandedChange(Node* node) {
+void AXObjectCacheImpl::HandleAriaExpandedChangeWithCleanLayout(Node* node) {
+  if (!node)
+    return;
+
+  DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
   if (AXObject* obj = GetOrCreate(node))
     obj->HandleAriaExpandedChanged();
 }
 
-void AXObjectCacheImpl::HandleAriaSelectedChanged(Node* node) {
+void AXObjectCacheImpl::HandleAriaSelectedChangedWithCleanLayout(Node* node) {
+  DCHECK(node);
+  DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
   AXObject* obj = Get(node);
   if (!obj)
     return;
@@ -1036,7 +1134,10 @@
   }
 }
 
-void AXObjectCacheImpl::HandleActiveDescendantChanged(Node* node) {
+void AXObjectCacheImpl::HandleActiveDescendantChangedWithCleanLayout(
+    Node* node) {
+  DCHECK(node);
+  DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
   // Changing the active descendant should trigger recomputing all
   // cached values even if it doesn't result in a notification, because
   // it can affect what's focusable or not.
@@ -1050,10 +1151,12 @@
 // as this may require a different subclass of AXObject.
 // Role changes are disallowed by the spec but we must handle it gracefully, see
 // https://www.w3.org/TR/wai-aria-1.1/#h-roles for more information.
-void AXObjectCacheImpl::HandleRoleChange(Node* node) {
+void AXObjectCacheImpl::HandleRoleChangeWithCleanLayout(Node* node) {
   if (!node)
     return;  // Virtual AOM node.
 
+  DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
+
   // Invalidate the current object and make the parent reconsider its children.
   if (AXObject* obj = Get(node)) {
     // Save parent for later use.
@@ -1079,81 +1182,108 @@
   }
 }
 
-void AXObjectCacheImpl::HandleRoleChangeIfNotEditable(Node* node) {
+void AXObjectCacheImpl::HandleRoleChangeIfNotEditableWithCleanLayout(
+    Node* node) {
   if (!node)
     return;
 
+  DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
+
   // Do not invalidate object if the role doesn't actually change when it's a
   // text control, otherwise unique id will change on platform side, and confuse
   // some screen readers as user edits.
   // TODO(aleventhal) Ideally the text control check would be removed, and
-  // HandleRoleChange() and only ever invalidate when the role actually changes.
-  // For example:
-  // if (obj->RoleValue() == obj->ComputeAccessibilityRole()) return;
-  // However, doing that would require waiting for layout to complete, as
-  // ComputeAccessibilityRole() looks at layout objects.
+  // HandleRoleChangeWithCleanLayout() and only ever invalidate when the role
+  // actually changes. For example:
+  // if (obj->RoleValue() == obj->ComputeAccessibilityRole())
+  //   return;
+  // However, doing that would require
+  // waiting for layout to complete, as ComputeAccessibilityRole() looks at
+  // layout objects.
   if (AXObject* obj = Get(node)) {
     if (!obj->IsTextControl())
-      HandleRoleChange(node);
+      HandleRoleChangeWithCleanLayout(node);
   }
 }
 
-void AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name,
+bool AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name,
                                                Element* element) {
   if (!element)
-    return;
+    return false;
 
-  if (element->GetDocument().NeedsLayoutTreeUpdateForNode(*element) ||
-      element->NeedsDistributionRecalc()) {
-    attributes_changed_during_layout_.push_back(
-        std::make_pair(attr_name, element));
-    return;
+  DeferTreeUpdate(&AXObjectCacheImpl::HandleAttributeChangedWithCleanLayout,
+                  attr_name, element);
+
+  if (attr_name == kRoleAttr || attr_name == kTypeAttr ||
+      attr_name == kSizeAttr || attr_name == kAltAttr ||
+      attr_name == kTitleAttr ||
+      (attr_name == kForAttr && IsHTMLLabelElement(*element)) ||
+      attr_name == kIdAttr || attr_name == kTabindexAttr ||
+      attr_name == kDisabledAttr) {
+    return true;
   }
+  return attr_name.LocalName().StartsWith("aria-");
+}
 
-  if (attr_name == kRoleAttr || attr_name == kTypeAttr)
-    HandleRoleChange(element);
-  else if (attr_name == kSizeAttr || attr_name == kAriaHaspopupAttr)
-    HandleRoleChangeIfNotEditable(element);  // Role won't change on edits.
-  else if (attr_name == kAltAttr || attr_name == kTitleAttr)
-    TextChanged(element);
-  else if (attr_name == kForAttr && IsHTMLLabelElement(*element))
-    LabelChanged(element);
-  else if (attr_name == kIdAttr)
+void AXObjectCacheImpl::HandleAttributeChangedWithCleanLayout(
+    const QualifiedName& attr_name,
+    Element* element) {
+  DCHECK(element);
+  DCHECK(!element->GetDocument().NeedsLayoutTreeUpdateForNode(*element));
+  if (attr_name == kRoleAttr || attr_name == kTypeAttr) {
+    HandleRoleChangeWithCleanLayout(element);
+  } else if (attr_name == kSizeAttr || attr_name == kAriaHaspopupAttr) {
+    // Role won't change on edits.
+    HandleRoleChangeIfNotEditableWithCleanLayout(element);
+  } else if (attr_name == kAltAttr || attr_name == kTitleAttr) {
+    TextChangedWithCleanLayout(element);
+  } else if (attr_name == kForAttr && IsHTMLLabelElement(*element)) {
+    LabelChangedWithCleanLayout(element);
+  } else if (attr_name == kIdAttr) {
     MaybeNewRelationTarget(element, Get(element));
-  else if (attr_name == kTabindexAttr)
-    FocusableChanged(element);
-  else if (attr_name == kDisabledAttr)
+  } else if (attr_name == kTabindexAttr) {
+    FocusableChangedWithCleanLayout(element);
+  } else if (attr_name == kDisabledAttr) {
     MarkElementDirty(element, false);
+  }
 
   if (!attr_name.LocalName().StartsWith("aria-"))
     return;
 
   // Perform updates specific to each attribute.
-  if (attr_name == kAriaActivedescendantAttr)
-    HandleActiveDescendantChanged(element);
-  else if (attr_name == kAriaValuenowAttr || attr_name == kAriaValuetextAttr)
+  if (attr_name == kAriaActivedescendantAttr) {
+    HandleActiveDescendantChangedWithCleanLayout(element);
+  } else if (attr_name == kAriaValuenowAttr ||
+             attr_name == kAriaValuetextAttr) {
     PostNotification(element, ax::mojom::Event::kValueChanged);
-  else if (attr_name == kAriaLabelAttr || attr_name == kAriaLabeledbyAttr ||
-           attr_name == kAriaLabelledbyAttr)
-    TextChanged(element);
-  else if (attr_name == kAriaDescribedbyAttr)
-    TextChanged(element);  // TODO do we need a DescriptionChanged() ?
-  else if (attr_name == kAriaCheckedAttr || attr_name == kAriaPressedAttr)
+  } else if (attr_name == kAriaLabelAttr || attr_name == kAriaLabeledbyAttr ||
+             attr_name == kAriaLabelledbyAttr) {
+    TextChangedWithCleanLayout(element);
+  } else if (attr_name == kAriaDescribedbyAttr) {
+    // TODO do we need a DescriptionChanged() ?
+    TextChangedWithCleanLayout(element);
+  } else if (attr_name == kAriaCheckedAttr || attr_name == kAriaPressedAttr) {
     CheckedStateChanged(element);
-  else if (attr_name == kAriaSelectedAttr)
-    HandleAriaSelectedChanged(element);
-  else if (attr_name == kAriaExpandedAttr)
-    HandleAriaExpandedChange(element);
-  else if (attr_name == kAriaHiddenAttr)
-    ChildrenChanged(element->parentNode());
-  else if (attr_name == kAriaInvalidAttr)
+  } else if (attr_name == kAriaSelectedAttr) {
+    HandleAriaSelectedChangedWithCleanLayout(element);
+  } else if (attr_name == kAriaExpandedAttr) {
+    HandleAriaExpandedChangeWithCleanLayout(element);
+  } else if (attr_name == kAriaHiddenAttr) {
+    ChildrenChangedWithCleanLayout(element->parentNode());
+  } else if (attr_name == kAriaInvalidAttr) {
     PostNotification(element, ax::mojom::Event::kInvalidStatusChanged);
-  else if (attr_name == kAriaErrormessageAttr)
+  } else if (attr_name == kAriaErrormessageAttr) {
     MarkElementDirty(element, false);
-  else if (attr_name == kAriaOwnsAttr)
-    ChildrenChanged(element);
-  else
+  } else if (attr_name == kAriaOwnsAttr) {
+    ChildrenChangedWithCleanLayout(element);
+    // Ensure aria-owns update fires on original parent as well
+    if (AXObject* obj = GetOrCreate(element)) {
+      obj->ClearChildren();
+      obj->AddChildren();
+    }
+  } else {
     PostNotification(element, ax::mojom::Event::kAriaAttributeChanged);
+  }
 }
 
 void AXObjectCacheImpl::HandleAutofillStateChanged(Element* elem,
@@ -1243,8 +1373,8 @@
   MarkElementDirty(form_control, false);
 }
 
-void AXObjectCacheImpl::LabelChanged(Element* element) {
-  TextChanged(ToHTMLLabelElement(element)->control());
+void AXObjectCacheImpl::LabelChangedWithCleanLayout(Element* element) {
+  TextChangedWithCleanLayout(ToHTMLLabelElement(element)->control());
 }
 
 void AXObjectCacheImpl::InlineTextBoxesUpdated(
@@ -1377,9 +1507,8 @@
     return;
 
   AXObject* old_focused_object = Get(old_focused_node);
-
-  PostPlatformNotification(old_focused_object, ax::mojom::Event::kBlur);
-  PostPlatformNotification(focused_object, ax::mojom::Event::kFocus);
+  PostNotification(old_focused_object, ax::mojom::Event::kBlur);
+  PostNotification(focused_object, ax::mojom::Event::kFocus);
 }
 
 void AXObjectCacheImpl::HandleInitialFocus() {
@@ -1456,6 +1585,10 @@
 
 void AXObjectCacheImpl::HandleLoadComplete(Document* document) {
   PostNotification(GetOrCreate(document), ax::mojom::Event::kLoadComplete);
+  // If load complete comes through after the lifecycle has finished,
+  // send notification immediately.
+  if (document->Lifecycle().GetState() >= DocumentLifecycle::kPaintClean)
+    PostNotificationsAfterLayout(document);
   AddPermissionStatusListener();
 }
 
@@ -1471,21 +1604,20 @@
     return;
   if (obj->AccessibilityIsIgnored())
     obj = obj->ParentObjectUnignored();
-  PostPlatformNotification(obj, ax::mojom::Event::kScrolledToAnchor);
+  PostNotification(obj, ax::mojom::Event::kScrolledToAnchor);
 }
 
 void AXObjectCacheImpl::HandleScrollPositionChanged(
     LocalFrameView* frame_view) {
   AXObject* target_ax_object =
       GetOrCreate(frame_view->GetFrame().GetDocument());
-  PostPlatformNotification(target_ax_object,
-                           ax::mojom::Event::kScrollPositionChanged);
+  PostNotification(target_ax_object, ax::mojom::Event::kScrollPositionChanged);
 }
 
 void AXObjectCacheImpl::HandleScrollPositionChanged(
     LayoutObject* layout_object) {
-  PostPlatformNotification(GetOrCreate(layout_object),
-                           ax::mojom::Event::kScrollPositionChanged);
+  PostNotification(GetOrCreate(layout_object),
+                   ax::mojom::Event::kScrollPositionChanged);
 }
 
 const AtomicString& AXObjectCacheImpl::ComputedRoleForNode(Node* node) {
@@ -1513,7 +1645,7 @@
         hit->GetLayoutObject()->IsLayoutEmbeddedContent())
       return;
 
-    PostPlatformNotification(hit, ax::mojom::Event::kHover);
+    PostNotification(hit, ax::mojom::Event::kHover);
   }
 }
 
@@ -1585,6 +1717,16 @@
                 WrapPersistent(this)));
 }
 
+void AXObjectCacheImpl::WillStartLifecycleUpdate(const LocalFrameView&) {}
+
+void AXObjectCacheImpl::DidFinishLifecycleUpdate(const LocalFrameView& view) {
+  Document* document = view.GetFrame().GetDocument();
+  if (document) {
+    ProcessUpdatesAfterLayout(*document);
+    PostNotificationsAfterLayout(document);
+  }
+}
+
 void AXObjectCacheImpl::ContextDestroyed(ExecutionContext*) {
   permission_service_.reset();
   permission_observer_binding_.Close();
@@ -1597,9 +1739,7 @@
 
   visitor->Trace(objects_);
   visitor->Trace(notifications_to_post_);
-  visitor->Trace(nodes_changed_during_layout_);
-  visitor->Trace(attributes_changed_during_layout_);
-
+  visitor->Trace(documents_);
   AXObjectCache::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 57af4fe..d65b44f5 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -30,6 +30,8 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_OBJECT_CACHE_IMPL_H_
 
 #include <memory>
+#include <utility>
+#include <vector>
 
 #include "base/macros.h"
 #include "mojo/public/cpp/bindings/binding.h"
@@ -37,6 +39,7 @@
 #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache_base.h"
 #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/modules/accessibility/ax_object.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -53,7 +56,8 @@
 // This class should only be used from inside the accessibility directory.
 class MODULES_EXPORT AXObjectCacheImpl
     : public AXObjectCacheBase,
-      public mojom::blink::PermissionObserver {
+      public mojom::blink::PermissionObserver,
+      public LocalFrameView::LifecycleNotificationObserver {
  public:
   static AXObjectCache* Create(Document&);
 
@@ -66,6 +70,10 @@
 
   void Dispose() override;
 
+  // Register/remove popups
+  void InitializePopup(Document* document) override;
+  void DisposePopup(Document* document) override;
+
   //
   // Iterators.
   //
@@ -98,14 +106,14 @@
   // changed.
   void TextChanged(LayoutObject*) override;
   void TextChanged(AXObject*, Node* optional_node = nullptr);
-  void FocusableChanged(Element* element);
+  void FocusableChangedWithCleanLayout(Element* element);
   void DocumentTitleChanged() override;
   // Called when a node has just been attached, so we can make sure we have the
   // right subclass of AXObject.
   void UpdateCacheAfterNodeIsAttached(Node*) override;
   void DidInsertChildrenOfNode(Node*) override;
 
-  void HandleAttributeChanged(const QualifiedName& attr_name,
+  bool HandleAttributeChanged(const QualifiedName& attr_name,
                               Element*) override;
   void HandleAutofillStateChanged(Element*, bool) override;
   void HandleValidationMessageVisibilityChanged(
@@ -175,11 +183,11 @@
 
   void MaybeNewRelationTarget(Node* node, AXObject* obj);
 
-  void HandleActiveDescendantChanged(Node*);
-  void HandleRoleChange(Node*);
-  void HandleRoleChangeIfNotEditable(Node*);
-  void HandleAriaExpandedChange(Node*);
-  void HandleAriaSelectedChanged(Node*);
+  void HandleActiveDescendantChangedWithCleanLayout(Node*);
+  void HandleRoleChangeWithCleanLayout(Node*);
+  void HandleRoleChangeIfNotEditableWithCleanLayout(Node*);
+  void HandleAriaExpandedChangeWithCleanLayout(Node*);
+  void HandleAriaSelectedChangedWithCleanLayout(Node*);
 
   bool AccessibilityEnabled();
   bool InlineTextBoxAccessibilityEnabled();
@@ -235,9 +243,13 @@
   // For built-in HTML form validation messages.
   AXObject* ValidationMessageObjectIfInvalid();
 
+  // LifecycleNotificationObserver overrides.
+  void WillStartLifecycleUpdate(const LocalFrameView&) override;
+  void DidFinishLifecycleUpdate(const LocalFrameView&) override;
+
  protected:
   void PostPlatformNotification(AXObject*, ax::mojom::Event);
-  void LabelChanged(Element*);
+  void LabelChangedWithCleanLayout(Element*);
 
   AXObject* CreateFromRenderer(LayoutObject*);
   AXObject* CreateFromNode(Node*);
@@ -269,10 +281,10 @@
   bool has_been_disposed_ = false;
 #endif
 
-  TaskRunnerTimer<AXObjectCacheImpl> notification_post_timer_;
-  HeapVector<std::pair<Member<AXObject>, ax::mojom::Event>>
-      notifications_to_post_;
-  void NotificationPostTimerFired(TimerBase*);
+  typedef HeapVector<std::pair<Member<AXObject>, ax::mojom::Event>>
+      NotificationVector;
+  NotificationVector notifications_to_post_;
+  void PostNotificationsAfterLayout(Document*);
 
   // ContextLifecycleObserver overrides.
   void ContextDestroyed(ExecutionContext*) override;
@@ -306,6 +318,25 @@
   AXObject* GetOrCreateValidationMessageObject();
   void RemoveValidationMessageObject();
 
+  // Enqueue a callback to the given method to be run after layout is
+  // complete.
+  void DeferTreeUpdate(void (AXObjectCacheImpl::*method)(Node*), Node* node);
+  void DeferTreeUpdate(void (AXObjectCacheImpl::*method)(const QualifiedName&,
+                                                         Element* element),
+                       const QualifiedName& attr_name,
+                       Element* element);
+  void DeferTreeUpdate(void (AXObjectCacheImpl::*method)(Node*, AXObject*),
+                       Node* node,
+                       AXObject* obj);
+
+  void DeferTreeUpdateInternal(Node* node, base::OnceClosure callback);
+
+  void SelectionChangedWithCleanLayout(Node* node);
+  void TextChangedWithCleanLayout(Node* node);
+  void ChildrenChangedWithCleanLayout(Node* node);
+  void HandleAttributeChangedWithCleanLayout(const QualifiedName& attr_name,
+                                             Element* element);
+
   // Whether the user has granted permission for the user to install event
   // listeners for accessibility events using the AOM.
   mojom::PermissionStatus accessibility_event_permission_;
@@ -314,9 +345,11 @@
   mojom::blink::PermissionServicePtr permission_service_;
   mojo::Binding<mojom::blink::PermissionObserver> permission_observer_binding_;
 
-  VectorOf<Node> nodes_changed_during_layout_;
-  typedef VectorOfPairs<QualifiedName, Element> AttributesChangedVector;
-  AttributesChangedVector attributes_changed_during_layout_;
+  // The main document, plus any page popups.
+  HeapHashSet<WeakMember<Document>> documents_;
+  typedef std::vector<std::pair<WeakPersistent<Node>, base::OnceClosure>>
+      TreeUpdateCallbackQueue;
+  TreeUpdateCallbackQueue tree_update_callback_queue_;
 
   DISALLOW_COPY_AND_ASSIGN(AXObjectCacheImpl);
 };
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
index 806b3ee..aaee6db 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
@@ -248,7 +248,7 @@
   UMA_HISTOGRAM_BOOLEAN("BackgroundFetch.HasDuplicateRequests",
                         kurls.size() != fetch_api_requests.size());
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // Pick the best icon, and load it.
@@ -365,7 +365,7 @@
                                           "The provided id is invalid."));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   bridge_->GetRegistration(
@@ -508,7 +508,7 @@
                                v8::Array::New(script_state->GetIsolate()));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   bridge_->GetDeveloperIds(WTF::Bind(
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
index 4c7732e..9f31b51 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
@@ -154,7 +154,7 @@
 }
 
 ScriptPromise BackgroundFetchRegistration::abort(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   DCHECK(registration_);
@@ -217,7 +217,7 @@
             "available."));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // Convert |request| to mojom::blink::FetchAPIRequestPtr.
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
index 043c29e5..ed140d8 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
@@ -75,7 +75,7 @@
     return ScriptPromise::CastUndefined(script_state);
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (ui_options->icons().IsEmpty()) {
diff --git a/third_party/blink/renderer/modules/background_sync/sync_manager.cc b/third_party/blink/renderer/modules/background_sync/sync_manager.cc
index ee000af..2fd5b3a3f 100644
--- a/third_party/blink/renderer/modules/background_sync/sync_manager.cc
+++ b/third_party/blink/renderer/modules/background_sync/sync_manager.cc
@@ -32,7 +32,7 @@
                              "Registration failed - no active Service Worker"));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   mojom::blink::SyncRegistrationOptionsPtr sync_registration =
@@ -48,7 +48,7 @@
 }
 
 ScriptPromise SyncManager::getTags(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   GetBackgroundSyncServicePtr()->GetRegistrations(
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
index d25574f..c03994d 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -210,7 +210,7 @@
   Platform::Current()->RecordRapporURL("Bluetooth.APIUsage.Origin", doc.Url());
 
   // Subsequent steps are handled in the browser process.
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   service_->RequestDevice(
@@ -327,7 +327,7 @@
   Platform::Current()->RecordRapporURL("Bluetooth.APIUsage.Origin", doc.Url());
 
   // Subsequent steps are handled in the browser process.
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   mojom::blink::WebBluetoothScanClientAssociatedPtrInfo client;
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
index f256bd6..38a7d71 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
@@ -133,7 +133,7 @@
         script_state, CreateInvalidCharacteristicError());
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   GetGatt()->AddToActiveAlgorithms(resolver);
 
@@ -202,7 +202,7 @@
   Vector<uint8_t> value_vector;
   value_vector.Append(value.Bytes(), value.ByteLength());
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   GetGatt()->AddToActiveAlgorithms(resolver);
 
@@ -251,7 +251,7 @@
         script_state, CreateInvalidCharacteristicError());
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   GetGatt()->AddToActiveAlgorithms(resolver);
 
@@ -286,7 +286,7 @@
         script_state, CreateInvalidCharacteristicError());
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   GetGatt()->AddToActiveAlgorithms(resolver);
 
@@ -351,7 +351,7 @@
         script_state, CreateInvalidCharacteristicError());
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   GetGatt()->AddToActiveAlgorithms(resolver);
 
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc
index af956437..1bcef85 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc
@@ -69,7 +69,7 @@
         script_state, CreateInvalidDescriptorError());
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   GetGatt()->AddToActiveAlgorithms(resolver);
   GetService()->RemoteDescriptorReadValue(
@@ -135,7 +135,7 @@
   Vector<uint8_t> value_vector;
   value_vector.Append(value.Bytes(), value.ByteLength());
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   GetGatt()->AddToActiveAlgorithms(resolver);
   GetService()->RemoteDescriptorWriteValue(
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
index 33b727f..6ddf67e2 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
@@ -107,7 +107,7 @@
 }
 
 ScriptPromise BluetoothRemoteGATTServer::connect(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   mojom::blink::WebBluetoothService* service =
@@ -230,7 +230,7 @@
                           BluetoothOperation::kServicesRetrieval));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   AddToActiveAlgorithms(resolver);
 
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
index 5f04057..3397225 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
@@ -140,7 +140,7 @@
                               "the service again after reconnecting."));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   device_->gatt()->AddToActiveAlgorithms(resolver);
 
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc
index 21a9ebe..82c02a43 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -731,7 +731,7 @@
                          "request", CacheStorageTracedValue(mojo_request),
                          "options", CacheStorageTracedValue(mojo_options));
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   const ScriptPromise promise = resolver->Promise();
   if (request->method() != http_names::kGET && !options->ignoreMethod()) {
     resolver->Resolve();
@@ -795,7 +795,7 @@
 ScriptPromise Cache::MatchAllImpl(ScriptState* script_state,
                                   const Request* request,
                                   const CacheQueryOptions* options) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   const ScriptPromise promise = resolver->Promise();
 
   mojom::blink::CacheQueryOptionsPtr mojo_options =
@@ -904,7 +904,7 @@
 ScriptPromise Cache::DeleteImpl(ScriptState* script_state,
                                 const Request* request,
                                 const CacheQueryOptions* options) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   const ScriptPromise promise = resolver->Promise();
 
   Vector<mojom::blink::BatchOperationPtr> batch_operations;
@@ -978,7 +978,7 @@
   TRACE_EVENT_WITH_FLOW0("CacheStorage", "Cache::PutImpl",
                          TRACE_ID_GLOBAL(trace_id),
                          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   const ScriptPromise promise = resolver->Promise();
   BarrierCallbackForPut* barrier_callback =
       MakeGarbageCollected<BarrierCallbackForPut>(
@@ -1069,7 +1069,7 @@
 ScriptPromise Cache::KeysImpl(ScriptState* script_state,
                               const Request* request,
                               const CacheQueryOptions* options) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   const ScriptPromise promise = resolver->Promise();
 
   mojom::blink::CacheQueryOptionsPtr mojo_options =
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
index a855bb3..bc0236b 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
@@ -93,7 +93,7 @@
                          TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
                          "name", CacheStorageTracedValue(cache_name));
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!IsAllowed(script_state)) {
@@ -157,7 +157,7 @@
                          TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
                          "name", CacheStorageTracedValue(cache_name));
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!IsAllowed(script_state)) {
@@ -208,7 +208,7 @@
                          TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
                          "name", CacheStorageTracedValue(cache_name));
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!IsAllowed(script_state)) {
@@ -259,7 +259,7 @@
   TRACE_EVENT_WITH_FLOW0("CacheStorage", "CacheStorage::Keys",
                          TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!IsAllowed(script_state)) {
@@ -320,7 +320,7 @@
                          "request", CacheStorageTracedValue(mojo_request),
                          "options", CacheStorageTracedValue(mojo_options));
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   const ScriptPromise promise = resolver->Promise();
 
   if (!IsAllowed(script_state)) {
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
index 27f2d435..2462607 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache_test.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
@@ -75,8 +75,8 @@
     }
 
     if (response_) {
-      ScriptPromiseResolver* resolver =
-          ScriptPromiseResolver::Create(script_state);
+      auto* resolver =
+          MakeGarbageCollected<ScriptPromiseResolver>(script_state);
       const ScriptPromise promise = resolver->Promise();
       resolver->Resolve(response_);
       response_ = nullptr;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
index 37f3864..33220cf 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -116,7 +116,8 @@
 ClipboardPromise::ClipboardPromise(ScriptState* script_state)
     : ContextLifecycleObserver(blink::ExecutionContext::From(script_state)),
       script_state_(script_state),
-      script_promise_resolver_(ScriptPromiseResolver::Create(script_state)),
+      script_promise_resolver_(
+          MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
       buffer_(mojom::ClipboardBuffer::kStandard),
       clipboard_representation_index_(0),
       file_reading_task_runner_(
diff --git a/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc b/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc
index 2512851..dac0583 100644
--- a/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc
+++ b/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc
@@ -98,7 +98,7 @@
                                      "At least one property must be provided"));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   bool include_names = false;
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store.cc b/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
index 81930536..358380e 100644
--- a/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
+++ b/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
@@ -344,7 +344,7 @@
     return ScriptPromise();
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   int64_t service_worker_registration_id =
       scope->registration()->RegistrationId();
   subscription_backend_->AppendSubscriptions(
@@ -366,7 +366,7 @@
     return ScriptPromise();
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   auto* scope = To<ServiceWorkerGlobalScope>(GetExecutionContext());
   int64_t service_worker_registration_id =
       scope->registration()->RegistrationId();
@@ -458,7 +458,7 @@
     return ScriptPromise();
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   backend_->GetAllForUrl(
       default_cookie_url_, default_site_for_cookies_,
       std::move(backend_options),
@@ -519,7 +519,7 @@
     return ScriptPromise();
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   backend_->SetCanonicalCookie(
       std::move(canonical_cookie.value()), default_cookie_url_,
       default_site_for_cookies_,
diff --git a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
index 80f9549..42718f4 100644
--- a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -419,7 +419,7 @@
 ScriptPromise CredentialsContainer::get(
     ScriptState* script_state,
     const CredentialRequestOptions* options) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   auto required_origin_type = RequiredOriginType::kSecureAndSameWithAncestors;
@@ -526,7 +526,7 @@
 
 ScriptPromise CredentialsContainer::store(ScriptState* script_state,
                                           Credential* credential) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   auto required_origin_type =
@@ -571,7 +571,7 @@
     ScriptState* script_state,
     const CredentialCreationOptions* options,
     ExceptionState& exception_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   auto required_origin_type =
@@ -689,7 +689,7 @@
 
 ScriptPromise CredentialsContainer::preventSilentAccess(
     ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   const auto required_origin_type = RequiredOriginType::kSecure;
   if (!CheckSecurityRequirementsBeforeRequest(resolver, required_origin_type))
diff --git a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
index 42d7ab4..3e739db 100644
--- a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
@@ -47,7 +47,7 @@
 ScriptPromise
 PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable(
     ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // Ignore calls if the current realm execution context is no longer valid,
diff --git a/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc b/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc
index 8b42bbd..b32235f 100644
--- a/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc
+++ b/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc
@@ -39,7 +39,7 @@
     ScriptState* script_state,
     const char* interface_name,
     const char* property_name)
-    : resolver_(ScriptPromiseResolver::Create(script_state)),
+    : resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
       interface_name_(interface_name),
       property_name_(property_name) {}
 
diff --git a/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc b/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
index 9b1b7b8..b9dedaf 100644
--- a/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
+++ b/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
@@ -158,7 +158,7 @@
     const String& key_system,
     const HeapVector<Member<MediaKeySystemConfiguration>>&
         supported_configurations)
-    : resolver_(ScriptPromiseResolver::Create(script_state)),
+    : resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
       key_system_(key_system),
       supported_configurations_(supported_configurations.size()) {
   for (wtf_size_t i = 0; i < supported_configurations.size(); ++i) {
diff --git a/third_party/blink/renderer/modules/eventsource/event_source.cc b/third_party/blink/renderer/modules/eventsource/event_source.cc
index a79a1ee..16fe3b9 100644
--- a/third_party/blink/renderer/modules/eventsource/event_source.cc
+++ b/third_party/blink/renderer/modules/eventsource/event_source.cc
@@ -125,8 +125,8 @@
   ExecutionContext& execution_context = *this->GetExecutionContext();
   ResourceRequest request(current_url_);
   request.SetHTTPMethod(http_names::kGET);
-  request.SetHTTPHeaderField(http_names::kAccept, "text/event-stream");
-  request.SetHTTPHeaderField(http_names::kCacheControl, "no-cache");
+  request.SetHttpHeaderField(http_names::kAccept, "text/event-stream");
+  request.SetHttpHeaderField(http_names::kCacheControl, "no-cache");
   request.SetRequestContext(mojom::RequestContextType::EVENT_SOURCE);
   request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors);
   request.SetFetchCredentialsMode(
@@ -143,7 +143,7 @@
     // TODO(davidben): This should be captured in the type of
     // setHTTPHeaderField's arguments.
     CString last_event_id_utf8 = parser_->LastEventId().Utf8();
-    request.SetHTTPHeaderField(
+    request.SetHttpHeaderField(
         http_names::kLastEventID,
         AtomicString(reinterpret_cast<const LChar*>(last_event_id_utf8.data()),
                      last_event_id_utf8.length()));
diff --git a/third_party/blink/renderer/modules/eventsource/event_source_parser.cc b/third_party/blink/renderer/modules/eventsource/event_source_parser.cc
index eb65abb..be4d4db 100644
--- a/third_party/blink/renderer/modules/eventsource/event_source_parser.cc
+++ b/third_party/blink/renderer/modules/eventsource/event_source_parser.cc
@@ -9,10 +9,10 @@
 #include "third_party/blink/renderer/modules/eventsource/event_source.h"
 #include "third_party/blink/renderer/platform/wtf/ascii_ctype.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
 #include "third_party/blink/renderer/platform/wtf/text/text_encoding_registry.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/exported/web_ax_object.cc b/third_party/blink/renderer/modules/exported/web_ax_object.cc
index 421dab0..b60cea9 100644
--- a/third_party/blink/renderer/modules/exported/web_ax_object.cc
+++ b/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -96,19 +96,20 @@
   }
 };
 
-#if DCHECK_IS_ON()
-// It's not safe to call some WebAXObject APIs if a layout is pending.
-// Clients should call updateLayoutAndCheckValidity first.
 static bool IsLayoutClean(Document* document) {
   if (!document || !document->View())
     return false;
-  return document->Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean ||
-         ((document->Lifecycle().GetState() == DocumentLifecycle::kStyleClean ||
-           document->Lifecycle().GetState() ==
-               DocumentLifecycle::kLayoutSubtreeChangeClean) &&
-          !document->View()->NeedsLayout());
+  if (document->View()->NeedsLayout())
+    return false;
+  DocumentLifecycle::LifecycleState state = document->Lifecycle().GetState();
+  if (state >= DocumentLifecycle::kLayoutClean ||
+      state == DocumentLifecycle::kStyleClean ||
+      state == DocumentLifecycle::kLayoutSubtreeChangeClean) {
+    return true;
+  }
+
+  return false;
 }
-#endif
 
 void WebAXObject::Reset() {
   private_.Reset();
@@ -146,8 +147,11 @@
 bool WebAXObject::UpdateLayoutAndCheckValidity() {
   if (!IsDetached()) {
     Document* document = private_->GetDocument();
-    if (!document || !document->View() ||
-        !document->View()->UpdateLifecycleToCompositingCleanPlusScrolling())
+    if (!document || !document->View())
+      return false;
+    if (IsLayoutClean(document))
+      return true;
+    if (!document->View()->UpdateLifecycleToCompositingCleanPlusScrolling())
       return false;
   }
 
diff --git a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
index 5ce2e94..fc6d1c1b 100644
--- a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
+++ b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -66,7 +66,6 @@
 #include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h"
 #include "third_party/blink/renderer/modules/service_worker/service_worker_thread.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h"
diff --git a/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc b/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
index 2b1d796..40b9723d 100644
--- a/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
+++ b/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
@@ -179,7 +179,8 @@
 ScriptPromise CreateFileHandle(ScriptState* script_state,
                                const mojom::blink::FileSystemEntryPtr& entry,
                                bool is_directory) {
-  auto* new_resolver = ScriptPromiseResolver::Create(script_state);
+  auto* new_resolver =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = new_resolver->Promise();
   auto* fs = DOMFileSystem::CreateIsolatedFileSystem(
       ExecutionContext::From(script_state), entry->file_system_id);
@@ -236,7 +237,7 @@
   if (options->hasAccepts())
     accepts = ConvertAccepts(options->accepts());
 
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise resolver_result = resolver->Promise();
   FileSystemDispatcher::From(document).GetFileSystemManager().ChooseEntry(
       ConvertChooserType(options->type(), options->multiple()),
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc b/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
index 8dc6755..01bdbd5d 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
@@ -17,7 +17,7 @@
     : EntryBase(file_system, full_path) {}
 
 ScriptPromise FileSystemBaseHandle::getParent(ScriptState* script_state) {
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
 
   auto success_callback_wrapper =
@@ -32,7 +32,7 @@
 ScriptPromise FileSystemBaseHandle::moveTo(ScriptState* script_state,
                                            FileSystemDirectoryHandle* parent,
                                            const String& name) {
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
 
   auto success_callback_wrapper =
@@ -47,7 +47,7 @@
 ScriptPromise FileSystemBaseHandle::copyTo(ScriptState* script_state,
                                            FileSystemDirectoryHandle* parent,
                                            const String& name) {
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
 
   auto success_callback_wrapper =
@@ -60,7 +60,7 @@
 }
 
 ScriptPromise FileSystemBaseHandle::remove(ScriptState* script_state) {
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
 
   auto success_callback_wrapper =
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc b/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
index 822dfa6..6bddd3f 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
@@ -24,7 +24,7 @@
     const FileSystemGetFileOptions* options) {
   FileSystemFlags* flags = FileSystemFlags::Create();
   flags->setCreateFlag(options->create());
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
 
   auto success_callback_wrapper =
@@ -42,7 +42,7 @@
     const FileSystemGetDirectoryOptions* options) {
   FileSystemFlags* flags = FileSystemFlags::Create();
   flags->setCreateFlag(options->create());
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
 
   auto success_callback_wrapper =
@@ -61,7 +61,7 @@
     const GetSystemDirectoryOptions* options) {
   auto* context = ExecutionContext::From(script_state);
 
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
 
   auto success_callback_wrapper =
@@ -105,7 +105,7 @@
 
 ScriptPromise FileSystemDirectoryHandle::removeRecursively(
     ScriptState* script_state) {
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
 
   auto success_callback_wrapper =
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.cc b/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.cc
index 897f037..d8af75e 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.cc
@@ -44,7 +44,7 @@
 
   if (has_more_entries_) {
     DCHECK(!pending_next_);
-    pending_next_ = ScriptPromiseResolver::Create(script_state);
+    pending_next_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
     return pending_next_->Promise();
   }
 
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc b/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
index 28c1741..d4e9941d 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
@@ -23,7 +23,7 @@
     : FileSystemBaseHandle(file_system, full_path) {}
 
 ScriptPromise FileSystemFileHandle::createWriter(ScriptState* script_state) {
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
   FileSystemDispatcher::From(ExecutionContext::From(script_state))
       .GetFileSystemManager()
@@ -44,7 +44,7 @@
 }
 
 ScriptPromise FileSystemFileHandle::getFile(ScriptState* script_state) {
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
   KURL file_system_url = filesystem()->CreateFileSystemURL(this);
 
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_writer.cc b/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
index 3d3e0b68..18efa9c 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
@@ -49,7 +49,8 @@
         script_state,
         DOMException::Create(DOMExceptionCode::kInvalidStateError));
   }
-  pending_operation_ = ScriptPromiseResolver::Create(script_state);
+  pending_operation_ =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = pending_operation_->Promise();
   writer_->Write(
       position, blob->AsMojoBlob(),
@@ -161,7 +162,8 @@
   stream_loader_ = FetchDataLoader::CreateLoaderAsDataPipe(
       ExecutionContext::From(script_state)
           ->GetTaskRunner(TaskType::kInternalDefault));
-  pending_operation_ = ScriptPromiseResolver::Create(script_state);
+  pending_operation_ =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = pending_operation_->Promise();
   auto* client = MakeGarbageCollected<StreamWriterClient>(this);
   stream_loader_->Start(consumer, client);
@@ -178,7 +180,8 @@
         script_state,
         DOMException::Create(DOMExceptionCode::kInvalidStateError));
   }
-  pending_operation_ = ScriptPromiseResolver::Create(script_state);
+  pending_operation_ =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = pending_operation_->Promise();
   writer_->Truncate(size, WTF::Bind(&FileSystemWriter::TruncateComplete,
                                     WrapPersistent(this)));
diff --git a/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc b/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc
index 817f8db..d7a955a 100644
--- a/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc
+++ b/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc
@@ -90,7 +90,7 @@
     ScriptState* script_state,
     const String& type,
     const GamepadEffectParameters* params) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
   if (params->duration() < 0.0 || params->startDelay() < 0.0 ||
       params->strongMagnitude() < 0.0 || params->strongMagnitude() > 1.0 ||
@@ -162,7 +162,7 @@
 }
 
 ScriptPromise GamepadHapticActuator::reset(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
   auto callback = WTF::Bind(&GamepadHapticActuator::OnResetCompleted,
                             WrapPersistent(this), WrapPersistent(resolver));
diff --git a/third_party/blink/renderer/modules/imagecapture/image_capture.cc b/third_party/blink/renderer/modules/imagecapture/image_capture.cc
index 71ce2f0..bf755d1 100644
--- a/third_party/blink/renderer/modules/imagecapture/image_capture.cc
+++ b/third_party/blink/renderer/modules/imagecapture/image_capture.cc
@@ -122,7 +122,7 @@
 }
 
 ScriptPromise ImageCapture::getPhotoCapabilities(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!service_) {
@@ -148,7 +148,7 @@
 }
 
 ScriptPromise ImageCapture::getPhotoSettings(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!service_) {
@@ -178,7 +178,7 @@
                                        bool trigger_take_photo /* = false */) {
   TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
                        "ImageCapture::setOptions", TRACE_EVENT_SCOPE_PROCESS);
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (TrackIsInactive(*stream_track_)) {
@@ -259,7 +259,7 @@
 ScriptPromise ImageCapture::takePhoto(ScriptState* script_state) {
   TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
                        "ImageCapture::takePhoto", TRACE_EVENT_SCOPE_PROCESS);
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (TrackIsInactive(*stream_track_)) {
@@ -300,7 +300,7 @@
 }
 
 ScriptPromise ImageCapture::grabFrame(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (TrackIsInactive(*stream_track_)) {
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc b/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc
index 284072d..88d4cb7 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc
@@ -84,8 +84,7 @@
 std::unique_ptr<WebIDBDatabaseCallbacks>
 IDBDatabaseCallbacks::CreateWebCallbacks() {
   DCHECK(!web_callbacks_);
-  std::unique_ptr<WebIDBDatabaseCallbacks> callbacks =
-      WebIDBDatabaseCallbacksImpl::Create(this);
+  auto callbacks = std::make_unique<WebIDBDatabaseCallbacksImpl>(this);
   web_callbacks_ = callbacks.get();
   return callbacks;
 }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
index 193cf5ab..a2bd7e0 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
@@ -219,7 +219,7 @@
 
 ScriptPromise IDBFactory::GetDatabaseInfo(ScriptState* script_state,
                                           ExceptionState& exception_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
   if (!ExecutionContext::From(script_state)
            ->GetSecurityOrigin()
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks_impl.cc
index 8193053d..5ac0a0b4 100644
--- a/third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks_impl.cc
+++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks_impl.cc
@@ -37,12 +37,6 @@
 
 namespace blink {
 
-// static
-std::unique_ptr<WebIDBDatabaseCallbacksImpl>
-WebIDBDatabaseCallbacksImpl::Create(IDBDatabaseCallbacks* callbacks) {
-  return base::WrapUnique(new WebIDBDatabaseCallbacksImpl(callbacks));
-}
-
 WebIDBDatabaseCallbacksImpl::WebIDBDatabaseCallbacksImpl(
     IDBDatabaseCallbacks* callbacks)
     : callbacks_(callbacks) {}
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks_impl.h
index 8dccb6e4..8485b35 100644
--- a/third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks_impl.h
+++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks_impl.h
@@ -39,9 +39,7 @@
   USING_FAST_MALLOC(WebIDBDatabaseCallbacksImpl);
 
  public:
-  static std::unique_ptr<WebIDBDatabaseCallbacksImpl> Create(
-      IDBDatabaseCallbacks*);
-
+  explicit WebIDBDatabaseCallbacksImpl(IDBDatabaseCallbacks*);
   ~WebIDBDatabaseCallbacksImpl() override;
 
   void OnForcedClose() override;
@@ -54,8 +52,6 @@
   void Detach() override;
 
  private:
-  explicit WebIDBDatabaseCallbacksImpl(IDBDatabaseCallbacks*);
-
   Persistent<IDBDatabaseCallbacks> callbacks_;
 };
 
diff --git a/third_party/blink/renderer/modules/installedapp/navigator_installed_app.cc b/third_party/blink/renderer/modules/installedapp/navigator_installed_app.cc
index a17c784..206c5e3 100644
--- a/third_party/blink/renderer/modules/installedapp/navigator_installed_app.cc
+++ b/third_party/blink/renderer/modules/installedapp/navigator_installed_app.cc
@@ -70,7 +70,7 @@
 
 ScriptPromise NavigatorInstalledApp::getInstalledRelatedApps(
     ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   InstalledAppController* app_controller = Controller();
diff --git a/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc b/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
index ce239998..c87f8e63 100644
--- a/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
+++ b/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
@@ -56,7 +56,8 @@
                                            kKeyboardMapRequestFailedErrorMsg));
   }
 
-  script_promise_resolver_ = ScriptPromiseResolver::Create(script_state);
+  script_promise_resolver_ =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   service_->GetKeyboardLayoutMap(
       WTF::Bind(&KeyboardLayout::GotKeyboardLayoutMap, WrapPersistent(this),
                 WrapPersistent(script_promise_resolver_.Get())));
diff --git a/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc b/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc
index b61ce67..46d3e09 100644
--- a/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc
+++ b/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc
@@ -62,7 +62,8 @@
                                     kKeyboardLockRequestFailedErrorMsg));
   }
 
-  request_keylock_resolver_ = ScriptPromiseResolver::Create(state);
+  request_keylock_resolver_ =
+      MakeGarbageCollected<ScriptPromiseResolver>(state);
   service_->RequestKeyboardLock(
       keycodes,
       WTF::Bind(&KeyboardLock::LockRequestFinished, WrapPersistent(this),
diff --git a/third_party/blink/renderer/modules/locks/lock_manager.cc b/third_party/blink/renderer/modules/locks/lock_manager.cc
index 7c84b004..83323c7 100644
--- a/third_party/blink/renderer/modules/locks/lock_manager.cc
+++ b/third_party/blink/renderer/modules/locks/lock_manager.cc
@@ -295,7 +295,7 @@
                              ? mojom::blink::LockManager::WaitMode::NO_WAIT
                              : mojom::blink::LockManager::WaitMode::WAIT;
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   mojom::blink::LockRequestAssociatedPtrInfo request_info;
@@ -351,7 +351,7 @@
     }
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   service_->QueryState(WTF::Bind(
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
index 89f1806..12406ff6 100644
--- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
+++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
@@ -403,7 +403,7 @@
 ScriptPromise MediaCapabilities::decodingInfo(
     ScriptState* script_state,
     const MediaDecodingConfiguration* configuration) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   String message;
@@ -494,7 +494,7 @@
 ScriptPromise MediaCapabilities::encodingInfo(
     ScriptState* script_state,
     const MediaEncodingConfiguration* configuration) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!IsValidMediaConfiguration(configuration)) {
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.cc b/third_party/blink/renderer/modules/mediastream/media_devices.cc
index f6644c54..0d3912ce 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -79,7 +79,7 @@
                                            "Current frame is detached."));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   requests_.insert(resolver);
 
@@ -109,7 +109,7 @@
     WebUserMediaRequest::MediaType media_type,
     const MediaStreamConstraints* options,
     ExceptionState& exception_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   PromiseResolverCallbacks* callbacks =
       PromiseResolverCallbacks::Create(resolver);
 
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
index 0a6caebc..cc69226 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -570,7 +570,7 @@
 ScriptPromise MediaStreamTrack::applyConstraints(
     ScriptState* script_state,
     const MediaTrackConstraints* constraints) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   MediaErrorState error_state;
diff --git a/third_party/blink/renderer/modules/mediastream/testing/internals_media_stream.cc b/third_party/blink/renderer/modules/mediastream/testing/internals_media_stream.cc
index 06b08c2a..0a24fb7 100644
--- a/third_party/blink/renderer/modules/mediastream/testing/internals_media_stream.cc
+++ b/third_party/blink/renderer/modules/mediastream/testing/internals_media_stream.cc
@@ -15,7 +15,7 @@
     const MediaDeviceInfo* device_info,
     const MediaTrackConstraints*,
     const MediaStreamTrack* data_source) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   resolver->Reject();
   return promise;
diff --git a/third_party/blink/renderer/modules/nfc/nfc.cc b/third_party/blink/renderer/modules/nfc/nfc.cc
index 6d801f6..5c0272301 100644
--- a/third_party/blink/renderer/modules/nfc/nfc.cc
+++ b/third_party/blink/renderer/modules/nfc/nfc.cc
@@ -722,7 +722,7 @@
         "NDEFMessage exceeds maximum supported size.");
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   requests_.insert(resolver);
   auto callback = WTF::Bind(&NFC::OnRequestCompleted, WrapPersistent(this),
                             WrapPersistent(resolver));
@@ -739,7 +739,7 @@
   if (!promise.IsEmpty())
     return promise;
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   requests_.insert(resolver);
   auto callback = WTF::Bind(&NFC::OnRequestCompleted, WrapPersistent(this),
                             WrapPersistent(resolver));
@@ -767,7 +767,7 @@
     }
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   requests_.insert(resolver);
   auto watch_callback =
       WTF::Bind(&NFC::OnWatchRegistered, WrapPersistent(this),
@@ -792,7 +792,7 @@
                                   "Provided watch id cannot be found.");
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   requests_.insert(resolver);
   nfc_->CancelWatch(id,
                     WTF::Bind(&NFC::OnRequestCompleted, WrapPersistent(this),
@@ -808,7 +808,7 @@
     return promise;
 
   callbacks_.clear();
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   requests_.insert(resolver);
   nfc_->CancelAllWatches(WTF::Bind(&NFC::OnRequestCompleted,
                                    WrapPersistent(this),
diff --git a/third_party/blink/renderer/modules/notifications/notification.h b/third_party/blink/renderer/modules/notifications/notification.h
index 1a17541..b7492dd3 100644
--- a/third_party/blink/renderer/modules/notifications/notification.h
+++ b/third_party/blink/renderer/modules/notifications/notification.h
@@ -32,9 +32,9 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_NOTIFICATIONS_NOTIFICATION_H_
 
 #include "mojo/public/cpp/bindings/binding.h"
+#include "third_party/blink/public/mojom/notifications/notification_service.mojom-blink.h"
 #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
 #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
diff --git a/third_party/blink/renderer/modules/notifications/notification_manager.cc b/third_party/blink/renderer/modules/notifications/notification_manager.cc
index 8134922..fa6ba1c5 100644
--- a/third_party/blink/renderer/modules/notifications/notification_manager.cc
+++ b/third_party/blink/renderer/modules/notifications/notification_manager.cc
@@ -80,7 +80,7 @@
                   WrapWeakPersistent(this)));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   Document* doc = DynamicTo<Document>(context);
diff --git a/third_party/blink/renderer/modules/notifications/notification_manager.h b/third_party/blink/renderer/modules/notifications/notification_manager.h
index c369fce..920a5c1 100644
--- a/third_party/blink/renderer/modules/notifications/notification_manager.h
+++ b/third_party/blink/renderer/modules/notifications/notification_manager.h
@@ -6,8 +6,8 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_NOTIFICATIONS_NOTIFICATION_MANAGER_H_
 
 #include "base/macros.h"
+#include "third_party/blink/public/mojom/notifications/notification_service.mojom-blink.h"
 #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom-blink.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_notification_permission_callback.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
diff --git a/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc b/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc
index 12934065..75a2a8515 100644
--- a/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc
+++ b/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc
@@ -69,7 +69,7 @@
       ("Notifications.PersistentNotificationActionCount", 17));
   notification_count_histogram.Count(options->actions().size());
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   ServiceWorkerRegistrationNotifications::From(execution_context, registration)
@@ -82,7 +82,7 @@
     ScriptState* script_state,
     ServiceWorkerRegistration& registration,
     const GetNotificationOptions* options) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
diff --git a/third_party/blink/renderer/modules/payments/payment_instruments.cc b/third_party/blink/renderer/modules/payments/payment_instruments.cc
index 709676f3..b7cba2b 100644
--- a/third_party/blink/renderer/modules/payments/payment_instruments.cc
+++ b/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -153,7 +153,7 @@
                                            kPaymentManagerUnavailable));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   manager_->DeletePaymentInstrument(
@@ -174,7 +174,7 @@
                                            kPaymentManagerUnavailable));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   manager_->GetPaymentInstrument(
@@ -194,7 +194,7 @@
                                            kPaymentManagerUnavailable));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   manager_->KeysOfPaymentInstruments(
@@ -214,7 +214,7 @@
                                            kPaymentManagerUnavailable));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   manager_->HasPaymentInstrument(
@@ -237,7 +237,7 @@
                                            kPaymentManagerUnavailable));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ExecutionContext* context = ExecutionContext::From(script_state);
   Document* doc = DynamicTo<Document>(context);
 
@@ -267,7 +267,7 @@
                                            kPaymentManagerUnavailable));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   manager_->ClearPaymentInstruments(
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc
index cf2789c..e60f997 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -818,7 +818,7 @@
 
   payment_provider_->Show(is_user_gesture);
 
-  accept_resolver_ = ScriptPromiseResolver::Create(script_state);
+  accept_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   return accept_resolver_->Promise();
 }
 
@@ -845,7 +845,7 @@
             "No show() or retry() in progress, so nothing to abort"));
   }
 
-  abort_resolver_ = ScriptPromiseResolver::Create(script_state);
+  abort_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   payment_provider_->Abort();
   return abort_resolver_->Promise();
 }
@@ -862,7 +862,8 @@
       !RuntimeEnabledFeatures::PaymentRequestHasEnrolledInstrumentEnabled();
   payment_provider_->CanMakePayment(legacy_mode);
 
-  can_make_payment_resolver_ = ScriptPromiseResolver::Create(script_state);
+  can_make_payment_resolver_ =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   return can_make_payment_resolver_->Promise();
 }
 
@@ -884,7 +885,7 @@
   payment_provider_->HasEnrolledInstrument(per_method_quota);
 
   has_enrolled_instrument_resolver_ =
-      ScriptPromiseResolver::Create(script_state);
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   return has_enrolled_instrument_resolver_->Promise();
 }
 
@@ -976,7 +977,7 @@
       payments::mojom::blink::PaymentValidationErrors::From(
           const_cast<PaymentValidationErrors*>(errors)));
 
-  retry_resolver_ = ScriptPromiseResolver::Create(script_state);
+  retry_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
   return retry_resolver_->Promise();
 }
@@ -1022,7 +1023,8 @@
   // The payment provider should respond in PaymentRequest::OnComplete().
   payment_provider_->Complete(payments::mojom::blink::PaymentComplete(result));
 
-  complete_resolver_ = ScriptPromiseResolver::Create(script_state);
+  complete_resolver_ =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   return complete_resolver_->Promise();
 }
 
diff --git a/third_party/blink/renderer/modules/payments/payment_request_event.cc b/third_party/blink/renderer/modules/payments/payment_request_event.cc
index 863cf8e2..a180bed 100644
--- a/third_party/blink/renderer/modules/payments/payment_request_event.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request_event.cc
@@ -72,7 +72,7 @@
 
 ScriptPromise PaymentRequestEvent::openWindow(ScriptState* script_state,
                                               const String& url) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   ExecutionContext* context = ExecutionContext::From(script_state);
 
diff --git a/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc b/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc
index d3a937a..b011213 100644
--- a/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc
@@ -47,8 +47,8 @@
   event->SetTrusted(true);
   event->SetPaymentDetailsUpdater(updater);
   event->SetEventPhase(Event::kCapturingPhase);
-  ScriptPromiseResolver* payment_details =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+  auto* payment_details =
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   event->updateWith(scope.GetScriptState(), payment_details->Promise(),
                     scope.GetExceptionState());
   EXPECT_FALSE(scope.GetExceptionState().HadException());
@@ -67,8 +67,8 @@
   event->SetTrusted(true);
   event->SetPaymentDetailsUpdater(updater);
   event->SetEventPhase(Event::kCapturingPhase);
-  ScriptPromiseResolver* payment_details =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+  auto* payment_details =
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   event->updateWith(scope.GetScriptState(), payment_details->Promise(),
                     scope.GetExceptionState());
   EXPECT_FALSE(scope.GetExceptionState().HadException());
@@ -87,7 +87,8 @@
 
   event->updateWith(
       scope.GetScriptState(),
-      ScriptPromiseResolver::Create(scope.GetScriptState())->Promise(),
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState())
+          ->Promise(),
       scope.GetExceptionState());
 
   EXPECT_TRUE(scope.GetExceptionState().HadException());
@@ -103,13 +104,15 @@
   event->SetEventPhase(Event::kCapturingPhase);
   event->updateWith(
       scope.GetScriptState(),
-      ScriptPromiseResolver::Create(scope.GetScriptState())->Promise(),
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState())
+          ->Promise(),
       scope.GetExceptionState());
   EXPECT_FALSE(scope.GetExceptionState().HadException());
 
   event->updateWith(
       scope.GetScriptState(),
-      ScriptPromiseResolver::Create(scope.GetScriptState())->Promise(),
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState())
+          ->Promise(),
       scope.GetExceptionState());
 
   EXPECT_TRUE(scope.GetExceptionState().HadException());
@@ -123,7 +126,8 @@
 
   event->updateWith(
       scope.GetScriptState(),
-      ScriptPromiseResolver::Create(scope.GetScriptState())->Promise(),
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState())
+          ->Promise(),
       scope.GetExceptionState());
 
   EXPECT_FALSE(scope.GetExceptionState().HadException());
@@ -156,7 +160,8 @@
 
   event->updateWith(
       scope.GetScriptState(),
-      ScriptPromiseResolver::Create(scope.GetScriptState())->Promise(),
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState())
+          ->Promise(),
       scope.GetExceptionState());
 
   EXPECT_FALSE(scope.GetExceptionState().HadException());
@@ -189,7 +194,8 @@
 
   event->updateWith(
       scope.GetScriptState(),
-      ScriptPromiseResolver::Create(scope.GetScriptState())->Promise(),
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState())
+          ->Promise(),
       scope.GetExceptionState());
 
   EXPECT_FALSE(scope.GetExceptionState().HadException());
@@ -208,8 +214,8 @@
   event->SetTrusted(true);
   event->SetPaymentDetailsUpdater(request);
   event->SetEventPhase(Event::kCapturingPhase);
-  ScriptPromiseResolver* payment_details =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+  auto* payment_details =
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   String error_message;
   request->show(scope.GetScriptState())
       .Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
@@ -241,8 +247,8 @@
   event->SetTrusted(true);
   event->SetPaymentDetailsUpdater(request);
   event->SetEventPhase(Event::kCapturingPhase);
-  ScriptPromiseResolver* payment_details =
-      ScriptPromiseResolver::Create(scope.GetScriptState());
+  auto* payment_details =
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState());
   String error_message;
   request->show(scope.GetScriptState())
       .Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
@@ -269,7 +275,8 @@
 
   event->updateWith(
       scope.GetScriptState(),
-      ScriptPromiseResolver::Create(scope.GetScriptState())->Promise(),
+      MakeGarbageCollected<ScriptPromiseResolver>(scope.GetScriptState())
+          ->Promise(),
       scope.GetExceptionState());
 
   EXPECT_TRUE(scope.GetExceptionState().HadException());
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
index e6fbe128..87c3a5e 100644
--- a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
@@ -4,7 +4,7 @@
 
 #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h"
 
-#include <memory>
+#include <utility>
 
 #include "third_party/blink/renderer/modules/peerconnection/adapters/quic_packet_transport_adapter.h"
 #include "third_party/webrtc/api/ice_transport_factory.h"
@@ -34,27 +34,33 @@
   port_allocator_->Initialize();
 
   ice_transport_channel_ = webrtc::CreateIceTransport(port_allocator_.get());
-  p2p_transport_channel()->SignalGatheringState.connect(
-      this, &IceTransportAdapterImpl::OnGatheringStateChanged);
-  p2p_transport_channel()->SignalCandidateGathered.connect(
-      this, &IceTransportAdapterImpl::OnCandidateGathered);
-  p2p_transport_channel()->SignalIceTransportStateChanged.connect(
-      this, &IceTransportAdapterImpl::OnStateChanged);
-  p2p_transport_channel()->SignalNetworkRouteChanged.connect(
-      this, &IceTransportAdapterImpl::OnNetworkRouteChanged);
-  p2p_transport_channel()->SignalRoleConflict.connect(
-      this, &IceTransportAdapterImpl::OnRoleConflict);
+  SetupIceTransportChannel();
   // We need to set the ICE role even before Start is called since the Port
   // assumes that the role has been set before receiving incoming connectivity
   // checks. These checks can race with the information signaled for Start.
-  p2p_transport_channel()->SetIceRole(cricket::ICEROLE_CONTROLLING);
+  ice_transport_channel()->SetIceRole(cricket::ICEROLE_CONTROLLING);
   // The ICE tiebreaker is used to determine which side is controlling/
   // controlled when both sides start in the same role. The number is randomly
   // generated so that each peer can calculate a.tiebreaker <= b.tiebreaker
   // consistently.
-  p2p_transport_channel()->SetIceTiebreaker(rtc::CreateRandomId64());
+  ice_transport_channel()->SetIceTiebreaker(rtc::CreateRandomId64());
+
   quic_packet_transport_adapter_ =
-      std::make_unique<QuicPacketTransportAdapter>(p2p_transport_channel());
+      std::make_unique<QuicPacketTransportAdapter>(ice_transport_channel());
+}
+
+IceTransportAdapterImpl::IceTransportAdapterImpl(
+    Delegate* delegate,
+    rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_channel,
+    rtc::Thread* thread)
+    : delegate_(delegate), ice_transport_channel_(ice_transport_channel) {
+  DCHECK(ice_transport_channel);
+  // TODO(bugs.webrtc.org/9419): Remove once WebRTC can be built as a component.
+  if (!rtc::ThreadManager::Instance()->CurrentThread()) {
+    rtc::ThreadManager::Instance()->SetCurrentThread(thread);
+  }
+
+  SetupIceTransportChannel();
 }
 
 IceTransportAdapterImpl::~IceTransportAdapterImpl() = default;
@@ -75,14 +81,16 @@
     const cricket::ServerAddresses& stun_servers,
     const std::vector<cricket::RelayServerConfig>& turn_servers,
     IceTransportPolicy policy) {
-  port_allocator_->set_candidate_filter(GetCandidateFilterForPolicy(policy));
-  port_allocator_->SetConfiguration(stun_servers, turn_servers,
-                                    port_allocator_->candidate_pool_size(),
-                                    port_allocator_->prune_turn_ports());
+  if (port_allocator_) {
+    port_allocator_->set_candidate_filter(GetCandidateFilterForPolicy(policy));
+    port_allocator_->SetConfiguration(stun_servers, turn_servers,
+                                      port_allocator_->candidate_pool_size(),
+                                      port_allocator_->prune_turn_ports());
+  }
 
-  p2p_transport_channel()->SetIceParameters(local_parameters);
-  p2p_transport_channel()->MaybeStartGathering();
-  DCHECK_EQ(p2p_transport_channel()->gathering_state(),
+  ice_transport_channel()->SetIceParameters(local_parameters);
+  ice_transport_channel()->MaybeStartGathering();
+  DCHECK_EQ(ice_transport_channel()->gathering_state(),
             cricket::kIceGatheringGathering);
 }
 
@@ -90,52 +98,65 @@
     const cricket::IceParameters& remote_parameters,
     cricket::IceRole role,
     const std::vector<cricket::Candidate>& initial_remote_candidates) {
-  p2p_transport_channel()->SetRemoteIceParameters(remote_parameters);
-  p2p_transport_channel()->SetIceRole(role);
+  ice_transport_channel()->SetRemoteIceParameters(remote_parameters);
+  ice_transport_channel()->SetIceRole(role);
   for (const auto& candidate : initial_remote_candidates) {
-    p2p_transport_channel()->AddRemoteCandidate(candidate);
+    ice_transport_channel()->AddRemoteCandidate(candidate);
   }
 }
 
 void IceTransportAdapterImpl::HandleRemoteRestart(
     const cricket::IceParameters& new_remote_parameters) {
-  p2p_transport_channel()->RemoveAllRemoteCandidates();
-  p2p_transport_channel()->SetRemoteIceParameters(new_remote_parameters);
+  ice_transport_channel()->RemoveAllRemoteCandidates();
+  ice_transport_channel()->SetRemoteIceParameters(new_remote_parameters);
 }
 
 void IceTransportAdapterImpl::AddRemoteCandidate(
     const cricket::Candidate& candidate) {
-  p2p_transport_channel()->AddRemoteCandidate(candidate);
+  ice_transport_channel()->AddRemoteCandidate(candidate);
 }
 
 P2PQuicPacketTransport* IceTransportAdapterImpl::packet_transport() const {
   return quic_packet_transport_adapter_.get();
 }
 
+void IceTransportAdapterImpl::SetupIceTransportChannel() {
+  ice_transport_channel()->SignalGatheringState.connect(
+      this, &IceTransportAdapterImpl::OnGatheringStateChanged);
+  ice_transport_channel()->SignalCandidateGathered.connect(
+      this, &IceTransportAdapterImpl::OnCandidateGathered);
+  ice_transport_channel()->SignalIceTransportStateChanged.connect(
+      this, &IceTransportAdapterImpl::OnStateChanged);
+  ice_transport_channel()->SignalNetworkRouteChanged.connect(
+      this, &IceTransportAdapterImpl::OnNetworkRouteChanged);
+  ice_transport_channel()->SignalRoleConflict.connect(
+      this, &IceTransportAdapterImpl::OnRoleConflict);
+}
+
 void IceTransportAdapterImpl::OnGatheringStateChanged(
     cricket::IceTransportInternal* transport) {
-  DCHECK_EQ(transport, p2p_transport_channel());
+  DCHECK_EQ(transport, ice_transport_channel());
   delegate_->OnGatheringStateChanged(
-      p2p_transport_channel()->gathering_state());
+      ice_transport_channel()->gathering_state());
 }
 
 void IceTransportAdapterImpl::OnCandidateGathered(
     cricket::IceTransportInternal* transport,
     const cricket::Candidate& candidate) {
-  DCHECK_EQ(transport, p2p_transport_channel());
+  DCHECK_EQ(transport, ice_transport_channel());
   delegate_->OnCandidateGathered(candidate);
 }
 
 void IceTransportAdapterImpl::OnStateChanged(
     cricket::IceTransportInternal* transport) {
-  DCHECK_EQ(transport, p2p_transport_channel());
-  delegate_->OnStateChanged(p2p_transport_channel()->GetIceTransportState());
+  DCHECK_EQ(transport, ice_transport_channel());
+  delegate_->OnStateChanged(ice_transport_channel()->GetIceTransportState());
 }
 
 void IceTransportAdapterImpl::OnNetworkRouteChanged(
     absl::optional<rtc::NetworkRoute> new_network_route) {
   const cricket::CandidatePairInterface* selected_connection =
-      p2p_transport_channel()->selected_connection();
+      ice_transport_channel()->selected_connection();
   if (!selected_connection) {
     // The selected connection will only be null if the ICE connection has
     // totally failed, at which point we'll get a StateChanged signal. The
@@ -173,13 +194,13 @@
 
 void IceTransportAdapterImpl::OnRoleConflict(
     cricket::IceTransportInternal* transport) {
-  DCHECK_EQ(transport, p2p_transport_channel());
+  DCHECK_EQ(transport, ice_transport_channel());
   // This logic is copied from JsepTransportController.
   cricket::IceRole reversed_role =
-      IceRoleReversed(p2p_transport_channel()->GetIceRole());
+      IceRoleReversed(ice_transport_channel()->GetIceRole());
   LOG(INFO) << "Got role conflict; switching to "
             << IceRoleToString(reversed_role) << " role.";
-  p2p_transport_channel()->SetIceRole(reversed_role);
+  ice_transport_channel()->SetIceRole(reversed_role);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h
index 8727cb8..e039f2f7 100644
--- a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h
+++ b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h
@@ -5,6 +5,9 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_IMPL_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_IMPL_H_
 
+#include <memory>
+#include <vector>
+
 #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h"
 #include "third_party/webrtc/api/ice_transport_interface.h"
 
@@ -24,6 +27,15 @@
       std::unique_ptr<cricket::PortAllocator> port_allocator,
       std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory,
       rtc::Thread* thread);
+
+  // Create an IceTransportAdapter for an existing |ice_transport_channel|
+  // object. In this case, |port_allocator_|, |async_resolver_factory_| and
+  // |quic_packet_transport_adapter_| are not used (and null).
+  IceTransportAdapterImpl(
+      Delegate* delegate,
+      rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_channel,
+      rtc::Thread* thread);
+
   ~IceTransportAdapterImpl() override;
 
   // IceTransportAdapter overrides.
@@ -42,9 +54,10 @@
   P2PQuicPacketTransport* packet_transport() const override;
 
  private:
-  cricket::IceTransportInternal* p2p_transport_channel() {
+  cricket::IceTransportInternal* ice_transport_channel() {
     return ice_transport_channel_->internal();
   }
+  void SetupIceTransportChannel();
   // Callbacks from P2PTransportChannel.
   void OnGatheringStateChanged(cricket::IceTransportInternal* transport);
   void OnCandidateGathered(cricket::IceTransportInternal* transport,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
index 32333d9..546d172b 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
 
+#include <vector>
+
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -22,6 +24,8 @@
 #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event_init.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/webrtc/api/ice_transport_factory.h"
+#include "third_party/webrtc/api/ice_transport_interface.h"
 #include "third_party/webrtc/api/jsep_ice_candidate.h"
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/p2p/base/port_allocator.h"
@@ -52,6 +56,36 @@
       WebString::FromUTF8(webrtc::SdpSerializeCandidate(candidate)), "", 0));
 }
 
+class DtlsIceTransportAdapterCrossThreadFactory
+    : public IceTransportAdapterCrossThreadFactory {
+ public:
+  explicit DtlsIceTransportAdapterCrossThreadFactory(
+      rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport)
+      : ice_transport_(ice_transport) {}
+  void InitializeOnMainThread(LocalFrame& frame) override {
+    DCHECK(!worker_thread_rtc_thread_);
+    DCHECK(!async_resolver_factory_);
+    async_resolver_factory_ =
+        Platform::Current()->CreateWebRtcAsyncResolverFactory();
+    worker_thread_rtc_thread_ =
+        Platform::Current()->GetWebRtcWorkerThreadRtcThread();
+  }
+
+  std::unique_ptr<IceTransportAdapter> ConstructOnWorkerThread(
+      IceTransportAdapter::Delegate* delegate) override {
+    DCHECK(ice_transport_);
+    DCHECK(worker_thread_rtc_thread_);
+    DCHECK(async_resolver_factory_);
+    return std::make_unique<IceTransportAdapterImpl>(
+        delegate, std::move(ice_transport_), worker_thread_rtc_thread_);
+  }
+
+ private:
+  rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_;
+  std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory_;
+  rtc::Thread* worker_thread_rtc_thread_ = nullptr;
+};
+
 class DefaultIceTransportAdapterCrossThreadFactory
     : public IceTransportAdapterCrossThreadFactory {
  public:
@@ -98,6 +132,20 @@
 
 RTCIceTransport* RTCIceTransport::Create(
     ExecutionContext* context,
+    rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport) {
+  LocalFrame* frame = To<Document>(context)->GetFrame();
+  scoped_refptr<base::SingleThreadTaskRunner> proxy_thread =
+      frame->GetTaskRunner(TaskType::kNetworking);
+  scoped_refptr<base::SingleThreadTaskRunner> host_thread =
+      Platform::Current()->GetWebRtcWorkerThread();
+  return MakeGarbageCollected<RTCIceTransport>(
+      context, std::move(proxy_thread), std::move(host_thread),
+      std::make_unique<DtlsIceTransportAdapterCrossThreadFactory>(
+          std::move(ice_transport)));
+}
+
+RTCIceTransport* RTCIceTransport::Create(
+    ExecutionContext* context,
     scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
     scoped_refptr<base::SingleThreadTaskRunner> host_thread,
     std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
index 2c65b3c..4b3fd86 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
@@ -5,6 +5,9 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_TRANSPORT_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_TRANSPORT_H_
 
+#include <memory>
+#include <utility>
+
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate_pair.h"
 #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
@@ -15,6 +18,10 @@
 #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
 #include "third_party/webrtc/api/transport/enums.h"
 
+namespace webrtc {
+class IceTransportInterface;
+}
+
 namespace blink {
 
 class ExceptionState;
@@ -51,6 +58,9 @@
   static RTCIceTransport* Create(ExecutionContext* context);
   static RTCIceTransport* Create(
       ExecutionContext* context,
+      rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_channel);
+  static RTCIceTransport* Create(
+      ExecutionContext* context,
       scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
       scoped_refptr<base::SingleThreadTaskRunner> host_thread,
       std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index e8302f9..bd5a796 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -840,7 +840,7 @@
   }
   call_setup_state_tracker_.NoteOffererStateEvent(
       OffererState::kCreateOfferPending, HasDocumentMedia());
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   RTCSessionDescriptionRequest* request =
       RTCSessionDescriptionRequestPromiseImpl::Create(
@@ -940,7 +940,7 @@
 
   call_setup_state_tracker_.NoteAnswererStateEvent(
       AnswererState::kCreateAnswerPending, HasDocumentMedia());
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   RTCSessionDescriptionRequest* request =
       RTCSessionDescriptionRequestPromiseImpl::Create(
@@ -1221,7 +1221,7 @@
   }
   NoteCallSetupStateEventPending(SetSdpOperationType::kSetLocalDescription,
                                  *session_description_init);
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   RTCVoidRequest* request = RTCVoidRequestPromiseImpl::Create(
       GetRTCVoidRequestOperationType(SetSdpOperationType::kSetLocalDescription,
@@ -1322,7 +1322,7 @@
 
   NoteCallSetupStateEventPending(SetSdpOperationType::kSetRemoteDescription,
                                  *session_description_init);
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   RTCVoidRequest* request = RTCVoidRequestPromiseImpl::Create(
       GetRTCVoidRequestOperationType(SetSdpOperationType::kSetRemoteDescription,
@@ -1646,7 +1646,7 @@
                                            unsupported_params_string));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   std::unique_ptr<WebRTCCertificateObserver> certificate_observer(
@@ -1687,7 +1687,7 @@
     return ScriptPromise();
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   RTCVoidRequest* request = RTCVoidRequestPromiseImpl::Create(
       base::nullopt, this, resolver, "RTCPeerConnection", "addIceCandidate");
@@ -1980,7 +1980,7 @@
     V8RTCStatsCallback* success_callback,
     MediaStreamTrack* selector) {
   ExecutionContext* context = ExecutionContext::From(script_state);
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   UseCounter::Count(context,
@@ -2008,8 +2008,7 @@
           DOMException::Create(DOMExceptionCode::kOperationError,
                                "Internal error: release in progress"));
     }
-    ScriptPromiseResolver* resolver =
-        ScriptPromiseResolver::Create(script_state);
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
     ScriptPromise promise = resolver->Promise();
     peer_handler_->GetStats(
         std::make_unique<WebRTCStatsReportCallbackResolver>(resolver),
@@ -2457,9 +2456,8 @@
   if (transport_locator != ice_transports_by_native_transport_.end()) {
     return transport_locator->value;
   }
-  // TODO(crbug.com/907849): Create a functional ICE transport object.
-  // This is a dummy.
-  RTCIceTransport* transport = RTCIceTransport::Create(GetExecutionContext());
+  RTCIceTransport* transport =
+      RTCIceTransport::Create(GetExecutionContext(), ice_transport);
   ice_transports_by_native_transport_.insert(ice_transport.get(), transport);
   return transport;
 }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc b/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
index ac4de7c5..c1bef2e 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
@@ -225,8 +225,8 @@
         String::Number(kReadBufferSize) + ".");
     return ScriptPromise();
   }
-  ScriptPromiseResolver* promise_resolver =
-      ScriptPromiseResolver::Create(script_state);
+  auto* promise_resolver =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = promise_resolver->Promise();
   if (received_fin_ || receive_buffer_.size() >= amount) {
     promise_resolver->Resolve();
@@ -245,8 +245,8 @@
   if (RaiseIfNotWritable(exception_state)) {
     return ScriptPromise();
   }
-  ScriptPromiseResolver* promise_resolver =
-      ScriptPromiseResolver::Create(script_state);
+  auto* promise_resolver =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = promise_resolver->Promise();
   if (write_buffered_amount_ <= threshold) {
     promise_resolver->Resolve();
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
index 0ce5a8c6..4e1cd1e 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
@@ -350,8 +350,8 @@
         "The RTCQuicTransport's state is not 'connecting' or 'connected'.");
     return ScriptPromise();
   }
-  ScriptPromiseResolver* promise_resolver =
-      ScriptPromiseResolver::Create(script_state);
+  auto* promise_resolver =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   uint32_t request_id = ++get_stats_id_counter_;
   stats_promise_map_.Set(request_id, promise_resolver);
   proxy_->GetStats(request_id);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
index 0e22b56..d72e6ca 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -82,7 +82,7 @@
 }
 
 ScriptPromise RTCRtpReceiver::getStats(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   receiver_->GetStats(
       std::make_unique<WebRTCStatsReportCallbackResolver>(resolver),
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
index 4cdc907..b0b204dd 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -333,7 +333,7 @@
 
 ScriptPromise RTCRtpSender::replaceTrack(ScriptState* script_state,
                                          MediaStreamTrack* with_track) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (pc_->IsClosed()) {
     resolver->Reject(DOMException::Create(DOMExceptionCode::kInvalidStateError,
@@ -413,7 +413,7 @@
 ScriptPromise RTCRtpSender::setParameters(
     ScriptState* script_state,
     const RTCRtpSendParameters* parameters) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!last_returned_parameters_) {
@@ -452,7 +452,7 @@
 }
 
 ScriptPromise RTCRtpSender::getStats(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   sender_->GetStats(
       std::make_unique<WebRTCStatsReportCallbackResolver>(resolver),
diff --git a/third_party/blink/renderer/modules/permissions/permissions.cc b/third_party/blink/renderer/modules/permissions/permissions.cc
index 7988916a..461d120 100644
--- a/third_party/blink/renderer/modules/permissions/permissions.cc
+++ b/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -26,8 +26,8 @@
 #include "third_party/blink/renderer/modules/permissions/permission_utils.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
 
 namespace blink {
 
@@ -158,7 +158,7 @@
   if (exception_state.HadException())
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // If the current origin is a file scheme, it will unlikely return a
@@ -184,7 +184,7 @@
 
   ExecutionContext* context = ExecutionContext::From(script_state);
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   PermissionDescriptorPtr descriptor_copy = descriptor->Clone();
@@ -209,7 +209,7 @@
   if (exception_state.HadException())
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   PermissionDescriptorPtr descriptor_copy = descriptor->Clone();
@@ -254,7 +254,7 @@
 
   ExecutionContext* context = ExecutionContext::From(script_state);
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   Vector<PermissionDescriptorPtr> internal_permissions_copy;
diff --git a/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc b/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc
index 0cb6b586..bb4871f 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc
+++ b/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc
@@ -41,7 +41,7 @@
                                            kNoPictureInPictureElement));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   DCHECK(IsHTMLVideoElement(picture_in_picture_element));
diff --git a/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc b/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
index 5144aa0..c7bd7c4 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
+++ b/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
@@ -89,7 +89,7 @@
                                            kUserGestureRequired));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   controller.EnterPictureInPicture(&element, resolver);
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection.cc b/third_party/blink/renderer/modules/presentation/presentation_connection.cc
index f286ef7..84fff5f 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_connection.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_connection.cc
@@ -284,7 +284,9 @@
 
   DidChangeState(mojom::blink::PresentationConnectionState::CONNECTING);
   target_connection_ = std::move(connection_ptr);
-  connection_binding_.Bind(std::move(connection_request));
+  connection_binding_.Bind(
+      std::move(connection_request),
+      GetExecutionContext()->GetTaskRunner(blink::TaskType::kPresentation));
 }
 
 void ControllerPresentationConnection::CloseInternal() {
@@ -332,7 +334,9 @@
     mojom::blink::PresentationConnectionPtr controller_connection_ptr,
     mojom::blink::PresentationConnectionRequest receiver_connection_request) {
   target_connection_ = std::move(controller_connection_ptr);
-  connection_binding_.Bind(std::move(receiver_connection_request));
+  connection_binding_.Bind(
+      std::move(receiver_connection_request),
+      GetExecutionContext()->GetTaskRunner(blink::TaskType::kPresentation));
 
   target_connection_->DidChangeState(
       mojom::blink::PresentationConnectionState::CONNECTED);
diff --git a/third_party/blink/renderer/modules/presentation/presentation_request.cc b/third_party/blink/renderer/modules/presentation/presentation_request.cc
index 7d5c646..e967c09 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_request.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_request.cc
@@ -158,7 +158,7 @@
             DOMExceptionCode::kInvalidStateError,
             "The PresentationRequest is no longer associated to a frame."));
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
   controller->GetPresentationService()->StartPresentation(
       urls_,
@@ -179,7 +179,7 @@
             DOMExceptionCode::kInvalidStateError,
             "The PresentationRequest is no longer associated to a frame."));
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
   ControllerPresentationConnection* existing_connection =
       controller->FindExistingConnection(urls_, id);
diff --git a/third_party/blink/renderer/modules/push_messaging/push_manager.cc b/third_party/blink/renderer/modules/push_messaging/push_manager.cc
index 0c3cdc3a..66ef19f3 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_manager.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_manager.cc
@@ -64,7 +64,7 @@
   if (exception_state.HadException())
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // The document context is the only reasonable context from which to ask the
@@ -95,7 +95,7 @@
 }
 
 ScriptPromise PushManager::getSubscription(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   PushProvider()->GetSubscription(
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
index 57dbbcb8..1ef83bd2 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
@@ -71,7 +71,7 @@
                                mojo::MakeRequest(&permission_service_));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // The `userVisibleOnly` flag on |options| must be set, as it's intended to be
diff --git a/third_party/blink/renderer/modules/push_messaging/push_subscription.cc b/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
index 4d677717..a2781f1 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
@@ -95,7 +95,7 @@
 }
 
 ScriptPromise PushSubscription::unsubscribe(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   WebPushProvider* web_push_provider = Platform::Current()->PushProvider();
diff --git a/third_party/blink/renderer/modules/quota/storage_manager.cc b/third_party/blink/renderer/modules/quota/storage_manager.cc
index 764d93a..3d9cd81 100644
--- a/third_party/blink/renderer/modules/quota/storage_manager.cc
+++ b/third_party/blink/renderer/modules/quota/storage_manager.cc
@@ -76,7 +76,7 @@
 }  // namespace
 
 ScriptPromise StorageManager::persist(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
   DCHECK(execution_context->IsSecureContext());  // [SecureContext] in IDL
@@ -100,7 +100,7 @@
 }
 
 ScriptPromise StorageManager::persisted(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
   DCHECK(execution_context->IsSecureContext());  // [SecureContext] in IDL
@@ -121,7 +121,7 @@
 }
 
 ScriptPromise StorageManager::estimate(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
   DCHECK(execution_context->IsSecureContext());  // [SecureContext] in IDL
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
index 605ca74e..bfe6538 100644
--- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
+++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -102,7 +102,7 @@
 ScriptPromise RemotePlayback::watchAvailability(
     ScriptState* script_state,
     V8RemotePlaybackAvailabilityCallback* callback) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (media_element_->FastHasAttribute(
@@ -134,7 +134,7 @@
 
 ScriptPromise RemotePlayback::cancelWatchAvailability(ScriptState* script_state,
                                                       int id) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (media_element_->FastHasAttribute(
@@ -158,7 +158,7 @@
 
 ScriptPromise RemotePlayback::cancelWatchAvailability(
     ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (media_element_->FastHasAttribute(
@@ -177,7 +177,7 @@
 }
 
 ScriptPromise RemotePlayback::prompt(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (media_element_->FastHasAttribute(
diff --git a/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc b/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc
index b02b276..d4f68b30 100644
--- a/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc
+++ b/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc
@@ -148,7 +148,7 @@
 
 ScriptPromise ScreenOrientation::lock(ScriptState* state,
                                       const AtomicString& lock_string) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(state);
   ScriptPromise promise = resolver->Promise();
 
   Document* document = GetFrame() ? GetFrame()->GetDocument() : nullptr;
diff --git a/third_party/blink/renderer/modules/serial/serial.cc b/third_party/blink/renderer/modules/serial/serial.cc
index af09b85..25f99f1 100644
--- a/third_party/blink/renderer/modules/serial/serial.cc
+++ b/third_party/blink/renderer/modules/serial/serial.cc
@@ -66,7 +66,7 @@
                                            kFeaturePolicyBlocked));
   }
 
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   get_ports_promises_.insert(resolver);
 
   EnsureServiceConnection();
@@ -101,7 +101,7 @@
             "Must be handling a user gesture to show a permission request."));
   }
 
-  auto* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   request_port_promises_.insert(resolver);
 
   EnsureServiceConnection();
diff --git a/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc b/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc
index 7183dc9..3c48c20 100644
--- a/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc
+++ b/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc
@@ -32,14 +32,14 @@
                               "') is not a valid HTTP header field value."));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   registration_->SetNavigationPreloadHeader(value, resolver);
   return promise;
 }
 
 ScriptPromise NavigationPreloadManager::getState(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   registration_->GetNavigationPreloadState(resolver);
   return promise;
@@ -51,7 +51,7 @@
 
 ScriptPromise NavigationPreloadManager::SetEnabled(bool enable,
                                                    ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   registration_->EnableNavigationPreload(enable, resolver);
   return promise;
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker.cc b/third_party/blink/renderer/modules/service_worker/service_worker.cc
index 89173f7..bb61236 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker.cc
@@ -101,7 +101,7 @@
 }
 
 ScriptPromise ServiceWorker::InternalsTerminate(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   host_->TerminateForTesting(
       WTF::Bind([](ScriptPromiseResolver* resolver) { resolver->Resolve(); },
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc b/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
index 6ea5d17..f0a4897a 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
@@ -117,7 +117,7 @@
   if (!execution_context)
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ServiceWorkerGlobalScopeClient::From(execution_context)
       ->GetClient(id, WTF::Bind(&DidGetClient, WrapPersistent(resolver)));
   return resolver->Promise();
@@ -131,7 +131,7 @@
   if (!execution_context)
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ServiceWorkerGlobalScopeClient::From(execution_context)
       ->GetClients(
           mojom::blink::ServiceWorkerClientQueryOptions::New(
@@ -147,7 +147,7 @@
   if (!execution_context)
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ServiceWorkerGlobalScopeClient::From(execution_context)
       ->Claim(WTF::Bind(&DidClaim, WrapPersistent(resolver)));
   return resolver->Promise();
@@ -155,7 +155,7 @@
 
 ScriptPromise ServiceWorkerClients::openWindow(ScriptState* script_state,
                                                const String& url) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   ExecutionContext* context = ExecutionContext::From(script_state);
 
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
index ca5e8c65..1f847cbc 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
@@ -234,7 +234,7 @@
     ScriptState* script_state,
     const String& url,
     const RegistrationOptions* options) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // TODO(asamidoi): Remove this check after module loading for
@@ -370,7 +370,7 @@
 ScriptPromise ServiceWorkerContainer::getRegistration(
     ScriptState* script_state,
     const String& document_url) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
@@ -422,7 +422,7 @@
 
 ScriptPromise ServiceWorkerContainer::getRegistrations(
     ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!provider_) {
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index 6fd7678..9901fb2 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -457,7 +457,7 @@
   if (!execution_context)
     return ScriptPromise();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ServiceWorkerGlobalScopeClient::From(execution_context)
       ->SkipWaiting(WTF::Bind(&DidSkipWaiting, WrapPersistent(resolver)));
   return resolver->Promise();
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc b/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
index 1f9aba8..918c9e28 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
@@ -228,7 +228,7 @@
                              "Failed to update a ServiceWorkerRegistration: No "
                              "associated provider is available."));
   }
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   host_->Update(
       WTF::Bind(&DidUpdate, WrapPersistent(resolver), WrapPersistent(this)));
   return resolver->Promise();
@@ -243,7 +243,7 @@
                              "ServiceWorkerRegistration: No "
                              "associated provider is available."));
   }
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   host_->Unregister(WTF::Bind(&DidUnregister, WrapPersistent(resolver)));
   return resolver->Promise();
 }
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc b/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
index 72637d1..3cd6cc0 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
@@ -71,7 +71,7 @@
 }
 
 ScriptPromise ServiceWorkerWindowClient::focus(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!ExecutionContext::From(script_state)->IsWindowInteractionAllowed()) {
@@ -88,7 +88,7 @@
 
 ScriptPromise ServiceWorkerWindowClient::navigate(ScriptState* script_state,
                                                   const String& url) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   ExecutionContext* context = ExecutionContext::From(script_state);
 
diff --git a/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc b/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
index 6abb770..a16a5af 100644
--- a/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
+++ b/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
@@ -40,7 +40,7 @@
   ExecutionContext* context = ExecutionContext::From(script_state);
   BarcodeDetector* detector = BarcodeDetector::Create(context);
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (!detector->barcode_service_) {
     resolver->Reject(
diff --git a/third_party/blink/renderer/modules/shapedetection/shape_detector.cc b/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
index 7127f3ca..ef3cd33 100644
--- a/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
+++ b/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
@@ -24,7 +24,7 @@
 ScriptPromise ShapeDetector::detect(
     ScriptState* script_state,
     const ImageBitmapSourceUnion& image_source) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // ImageDatas cannot be tainted by definition.
diff --git a/third_party/blink/renderer/modules/vr/navigator_vr.cc b/third_party/blink/renderer/modules/vr/navigator_vr.cc
index 489678d..26c7130 100644
--- a/third_party/blink/renderer/modules/vr/navigator_vr.cc
+++ b/third_party/blink/renderer/modules/vr/navigator_vr.cc
@@ -167,7 +167,7 @@
   Platform::Current()->RecordRapporURL("VR.WebVR.GetDisplays",
                                        GetDocument()->Url());
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   Controller()->GetDisplays(resolver);
 
diff --git a/third_party/blink/renderer/modules/vr/vr_display.cc b/third_party/blink/renderer/modules/vr/vr_display.cc
index 1e37c86f..2268016 100644
--- a/third_party/blink/renderer/modules/vr/vr_display.cc
+++ b/third_party/blink/renderer/modules/vr/vr_display.cc
@@ -395,7 +395,7 @@
 
   ReportPresentationResult(PresentationResult::kRequested);
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // If the VRDisplay does not advertise the ability to present reject the
@@ -624,7 +624,7 @@
 
 ScriptPromise VRDisplay::exitPresent(ScriptState* script_state) {
   DVLOG(1) << __FUNCTION__;
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (!is_presenting_) {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.cc b/third_party/blink/renderer/modules/webaudio/audio_context.cc
index 0fca282..754520b 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_context.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -173,7 +173,7 @@
 ScriptPromise AudioContext::suspendContext(ScriptState* script_state) {
   DCHECK(IsMainThread());
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (ContextState() == kClosed) {
@@ -208,7 +208,7 @@
                              "cannot resume a closed AudioContext"));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // If we're already running, just resolve; nothing else needs to be done.
@@ -289,7 +289,7 @@
                              "has already been closed."));
   }
 
-  close_resolver_ = ScriptPromiseResolver::Create(script_state);
+  close_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = close_resolver_->Promise();
 
   // Stops the rendering, but it doesn't release the resources here.
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
index 0746bec..de98097 100644
--- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
@@ -305,7 +305,7 @@
   DCHECK(IsMainThread());
   DCHECK(audio_data);
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   v8::Isolate* isolate = script_state->GetIsolate();
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
index 6b8c876..489a0ffc 100644
--- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
+++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
@@ -194,7 +194,8 @@
 
   DCHECK(!is_rendering_started_);
 
-  complete_resolver_ = ScriptPromiseResolver::Create(script_state);
+  complete_resolver_ =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
   // Allocate the AudioBuffer to hold the rendered result.
   float sample_rate = DestinationHandler().SampleRate();
@@ -228,7 +229,7 @@
                                                   double when) {
   DCHECK(IsMainThread());
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // If the rendering is finished, reject the promise.
@@ -308,7 +309,7 @@
 ScriptPromise OfflineAudioContext::resumeContext(ScriptState* script_state) {
   DCHECK(IsMainThread());
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // If the rendering has not started, reject the promise.
diff --git a/third_party/blink/renderer/modules/webgpu/gpu.cc b/third_party/blink/renderer/modules/webgpu/gpu.cc
index 687f2b7..3cd445b 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu.cc
@@ -63,7 +63,7 @@
 
 ScriptPromise GPU::requestAdapter(ScriptState* script_state,
                                   const GPURequestAdapterOptions* options) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // TODO(enga): Request the adapter from the WebGPUInterface.
diff --git a/third_party/blink/renderer/modules/webmidi/midi_port.cc b/third_party/blink/renderer/modules/webmidi/midi_port.cc
index f271681..a5648ac 100644
--- a/third_party/blink/renderer/modules/webmidi/midi_port.cc
+++ b/third_party/blink/renderer/modules/webmidi/midi_port.cc
@@ -103,7 +103,7 @@
   if (connection_ == kConnectionStateOpen)
     return Accept(script_state);
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   GetExecutionContext()
       ->GetTaskRunner(TaskType::kMiscPlatformAPI)
       ->PostTask(FROM_HERE,
@@ -127,7 +127,7 @@
   if (connection_ == kConnectionStateClosed)
     return Accept(script_state);
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   GetExecutionContext()
       ->GetTaskRunner(TaskType::kMiscPlatformAPI)
       ->PostTask(FROM_HERE,
diff --git a/third_party/blink/renderer/modules/webshare/navigator_share.cc b/third_party/blink/renderer/modules/webshare/navigator_share.cc
index c618616..2d39183b 100644
--- a/third_party/blink/renderer/modules/webshare/navigator_share.cc
+++ b/third_party/blink/renderer/modules/webshare/navigator_share.cc
@@ -181,7 +181,7 @@
     DCHECK(service_);
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ShareClientImpl* client =
       MakeGarbageCollected<ShareClientImpl>(this, resolver);
   clients_.insert(client);
diff --git a/third_party/blink/renderer/modules/webusb/usb.cc b/third_party/blink/renderer/modules/webusb/usb.cc
index 9fd45a29..9ac19ab 100644
--- a/third_party/blink/renderer/modules/webusb/usb.cc
+++ b/third_party/blink/renderer/modules/webusb/usb.cc
@@ -130,7 +130,7 @@
   }
 
   EnsureServiceConnection();
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   get_devices_requests_.insert(resolver);
   service_->GetDevices(WTF::Bind(&USB::OnGetDevices, WrapPersistent(this),
                                  WrapPersistent(resolver)));
@@ -163,7 +163,7 @@
             "Must be handling a user gesture to show a permission request."));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   Vector<UsbDeviceFilterPtr> filters;
   if (options->hasFilters()) {
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc
index c8aad9d..79d3ad2c 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -160,7 +160,7 @@
 }
 
 ScriptPromise USBDevice::open(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureNoDeviceOrInterfaceChangeInProgress(resolver)) {
     if (opened_) {
@@ -176,7 +176,7 @@
 }
 
 ScriptPromise USBDevice::close(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureNoDeviceOrInterfaceChangeInProgress(resolver)) {
     if (!opened_) {
@@ -193,7 +193,7 @@
 
 ScriptPromise USBDevice::selectConfiguration(ScriptState* script_state,
                                              uint8_t configuration_value) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureNoDeviceOrInterfaceChangeInProgress(resolver)) {
     if (!opened_) {
@@ -225,7 +225,7 @@
 
 ScriptPromise USBDevice::claimInterface(ScriptState* script_state,
                                         uint8_t interface_number) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureDeviceConfigured(resolver)) {
     wtf_size_t interface_index = FindInterfaceIndex(interface_number);
@@ -261,7 +261,7 @@
 
 ScriptPromise USBDevice::releaseInterface(ScriptState* script_state,
                                           uint8_t interface_number) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureDeviceConfigured(resolver)) {
     wtf_size_t interface_index = FindInterfaceIndex(interface_number);
@@ -294,7 +294,7 @@
 ScriptPromise USBDevice::selectAlternateInterface(ScriptState* script_state,
                                                   uint8_t interface_number,
                                                   uint8_t alternate_setting) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureInterfaceClaimed(interface_number, resolver)) {
     // TODO(reillyg): This is duplicated work.
@@ -327,7 +327,7 @@
     ScriptState* script_state,
     const USBControlTransferParameters* setup,
     unsigned length) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureDeviceConfigured(resolver)) {
     auto parameters = ConvertControlTransferParameters(setup, resolver);
@@ -345,7 +345,7 @@
 ScriptPromise USBDevice::controlTransferOut(
     ScriptState* script_state,
     const USBControlTransferParameters* setup) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureDeviceConfigured(resolver)) {
     auto parameters = ConvertControlTransferParameters(setup, resolver);
@@ -364,7 +364,7 @@
     ScriptState* script_state,
     const USBControlTransferParameters* setup,
     const ArrayBufferOrArrayBufferView& data) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureDeviceConfigured(resolver)) {
     auto parameters = ConvertControlTransferParameters(setup, resolver);
@@ -384,7 +384,7 @@
 ScriptPromise USBDevice::clearHalt(ScriptState* script_state,
                                    String direction,
                                    uint8_t endpoint_number) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureEndpointAvailable(direction == "in", endpoint_number, resolver)) {
     device_requests_.insert(resolver);
@@ -398,7 +398,7 @@
 ScriptPromise USBDevice::transferIn(ScriptState* script_state,
                                     uint8_t endpoint_number,
                                     unsigned length) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureEndpointAvailable(true /* in */, endpoint_number, resolver)) {
     device_requests_.insert(resolver);
@@ -413,7 +413,7 @@
 ScriptPromise USBDevice::transferOut(ScriptState* script_state,
                                      uint8_t endpoint_number,
                                      const ArrayBufferOrArrayBufferView& data) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureEndpointAvailable(false /* out */, endpoint_number, resolver)) {
     Vector<uint8_t> buffer = ConvertBufferSource(data);
@@ -431,7 +431,7 @@
     ScriptState* script_state,
     uint8_t endpoint_number,
     Vector<unsigned> packet_lengths) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureEndpointAvailable(true /* in */, endpoint_number, resolver)) {
     device_requests_.insert(resolver);
@@ -448,7 +448,7 @@
     uint8_t endpoint_number,
     const ArrayBufferOrArrayBufferView& data,
     Vector<unsigned> packet_lengths) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureEndpointAvailable(false /* out */, endpoint_number, resolver)) {
     device_requests_.insert(resolver);
@@ -461,7 +461,7 @@
 }
 
 ScriptPromise USBDevice::reset(ScriptState* script_state) {
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (EnsureNoDeviceOrInterfaceChangeInProgress(resolver)) {
     if (!opened_) {
diff --git a/third_party/blink/renderer/modules/xr/xr.cc b/third_party/blink/renderer/modules/xr/xr.cc
index 9c3c022..85b0d39 100644
--- a/third_party/blink/renderer/modules/xr/xr.cc
+++ b/third_party/blink/renderer/modules/xr/xr.cc
@@ -138,7 +138,7 @@
                                            kFeaturePolicyBlocked));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   if (mode == "inline") {
@@ -250,7 +250,7 @@
         "Inline AR is deprecated and will be removed soon."));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   PendingSessionQuery* query = MakeGarbageCollected<PendingSessionQuery>(
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc
index 42409ed..f00320fed 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -312,7 +312,7 @@
                                            kUnknownReferenceSpace));
   }
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   resolver->Resolve(reference_space);
 
@@ -401,7 +401,7 @@
   ray_mojo->direction->y = ray->direction()->y();
   ray_mojo->direction->z = ray->direction()->z();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   EnsureEnvironmentErrorHandler();
@@ -470,7 +470,7 @@
 
   ForceEnd();
 
-  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
   // TODO(bajones): If there's any work that needs to be done asynchronously on
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 e5408e49..196cc0a9 100644
--- a/third_party/blink/renderer/platform/animation/animated_layers_test.cc
+++ b/third_party/blink/renderer/platform/animation/animated_layers_test.cc
@@ -67,9 +67,8 @@
       CompositorFloatKeyframe(0.0, 0.0,
                               *CubicBezierTimingFunction::Preset(
                                   CubicBezierTimingFunction::EaseType::EASE)));
-  std::unique_ptr<CompositorKeyframeModel> float_keyframe_model(
-      CompositorKeyframeModel::Create(
-          *curve, compositor_target_property::OPACITY, 0, 0));
+  auto float_keyframe_model(std::make_unique<CompositorKeyframeModel>(
+      *curve, compositor_target_property::OPACITY, 0, 0));
   int keyframe_model_id = float_keyframe_model->Id();
 
   auto compositor_timeline = std::make_unique<CompositorAnimationTimeline>();
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 e0cef4b6..4c2cf8e 100644
--- a/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
+++ b/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
@@ -61,9 +61,8 @@
   cc::SingleKeyframeEffectAnimation* cc_animation = animation->CcAnimation();
 
   auto curve = std::make_unique<CompositorFloatAnimationCurve>();
-  std::unique_ptr<CompositorKeyframeModel> keyframe_model =
-      CompositorKeyframeModel::Create(
-          *curve, compositor_target_property::TRANSFORM, 1, 0);
+  auto keyframe_model = std::make_unique<CompositorKeyframeModel>(
+      *curve, compositor_target_property::TRANSFORM, 0, 1);
   animation->AddKeyframeModel(std::move(keyframe_model));
 
   animation->SetAnimationDelegate(delegate.get());
@@ -91,9 +90,8 @@
       animation->CcAnimation();
 
   auto curve = std::make_unique<CompositorFloatAnimationCurve>();
-  std::unique_ptr<CompositorKeyframeModel> keyframe_model =
-      CompositorKeyframeModel::Create(
-          *curve, compositor_target_property::OPACITY, 1, 0);
+  auto keyframe_model = std::make_unique<CompositorKeyframeModel>(
+      *curve, compositor_target_property::OPACITY, 0, 1);
   animation->AddKeyframeModel(std::move(keyframe_model));
 
   animation->SetAnimationDelegate(delegate.get());
diff --git a/third_party/blink/renderer/platform/animation/compositor_keyframe_model.h b/third_party/blink/renderer/platform/animation/compositor_keyframe_model.h
index ebdff81..673cbb0 100644
--- a/third_party/blink/renderer/platform/animation/compositor_keyframe_model.h
+++ b/third_party/blink/renderer/platform/animation/compositor_keyframe_model.h
@@ -32,15 +32,10 @@
   using Direction = cc::KeyframeModel::Direction;
   using FillMode = cc::KeyframeModel::FillMode;
 
-  static std::unique_ptr<CompositorKeyframeModel> Create(
-      const blink::CompositorAnimationCurve& curve,
-      compositor_target_property::Type target,
-      int group_id,
-      int keyframe_model_id) {
-    return base::WrapUnique(new CompositorKeyframeModel(
-        curve, target, keyframe_model_id, group_id));
-  }
-
+  CompositorKeyframeModel(const CompositorAnimationCurve&,
+                          compositor_target_property::Type,
+                          int keyframe_model_id,
+                          int group_id);
   ~CompositorKeyframeModel();
 
   // An id must be unique.
@@ -80,11 +75,6 @@
   std::unique_ptr<CompositorFloatAnimationCurve> FloatCurveForTesting() const;
 
  private:
-  CompositorKeyframeModel(const CompositorAnimationCurve&,
-                          compositor_target_property::Type,
-                          int keyframe_model_id,
-                          int group_id);
-
   std::unique_ptr<cc::KeyframeModel> keyframe_model_;
 
   DISALLOW_COPY_AND_ASSIGN(CompositorKeyframeModel);
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 1f5b28e6..d6e98d70 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
@@ -11,9 +11,8 @@
 
 TEST(WebCompositorAnimationTest, DefaultSettings) {
   auto curve = std::make_unique<CompositorFloatAnimationCurve>();
-  std::unique_ptr<CompositorKeyframeModel> keyframe_model =
-      CompositorKeyframeModel::Create(
-          *curve, compositor_target_property::OPACITY, 1, 0);
+  auto keyframe_model = std::make_unique<CompositorKeyframeModel>(
+      *curve, compositor_target_property::OPACITY, 0, 1);
 
   // Ensure that the defaults are correct.
   EXPECT_EQ(1, keyframe_model->Iterations());
@@ -25,9 +24,8 @@
 
 TEST(WebCompositorAnimationTest, ModifiedSettings) {
   auto curve = std::make_unique<CompositorFloatAnimationCurve>();
-  std::unique_ptr<CompositorKeyframeModel> keyframe_model =
-      CompositorKeyframeModel::Create(
-          *curve, compositor_target_property::OPACITY, 1, 0);
+  auto keyframe_model = std::make_unique<CompositorKeyframeModel>(
+      *curve, compositor_target_property::OPACITY, 0, 1);
   keyframe_model->SetIterations(2);
   keyframe_model->SetStartTime(2);
   keyframe_model->SetTimeOffset(2);
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc
index e775de5..f77094a8 100644
--- a/third_party/blink/renderer/platform/exported/web_url_request.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -152,10 +152,10 @@
   return resource_request_->HttpHeaderField(name);
 }
 
-void WebURLRequest::SetHTTPHeaderField(const WebString& name,
+void WebURLRequest::SetHttpHeaderField(const WebString& name,
                                        const WebString& value) {
   CHECK(!DeprecatedEqualIgnoringCase(name, "referer"));
-  resource_request_->SetHTTPHeaderField(name, value);
+  resource_request_->SetHttpHeaderField(name, value);
 }
 
 void WebURLRequest::SetHTTPReferrer(
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc
index 89042a6..7efce2d 100644
--- a/third_party/blink/renderer/platform/exported/web_url_response.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -169,9 +169,9 @@
   return resource_response_->HttpHeaderField(name);
 }
 
-void WebURLResponse::SetHTTPHeaderField(const WebString& name,
+void WebURLResponse::SetHttpHeaderField(const WebString& name,
                                         const WebString& value) {
-  resource_response_->SetHTTPHeaderField(name, value);
+  resource_response_->SetHttpHeaderField(name, value);
 }
 
 void WebURLResponse::AddHTTPHeaderField(const WebString& name,
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
index 9b22f89..c1dc0bb8 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -323,9 +323,10 @@
 bool PaintArtifactCompositor::PropertyTreeStateChanged(
     const PropertyTreeState& state) const {
   const auto& root = PropertyTreeState::Root();
-  return state.Transform().Changed(root.Transform()) ||
-         state.Clip().Changed(root, &state.Transform()) ||
-         state.Effect().Changed(root, &state.Transform());
+  auto change = PaintPropertyChangeType::kChangedOnlyNonRerasterValues;
+  return state.Transform().Changed(change, root.Transform()) ||
+         state.Clip().Changed(change, root, &state.Transform()) ||
+         state.Effect().Changed(change, root, &state.Transform());
 }
 
 PaintArtifactCompositor::PendingLayer::PendingLayer(
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc b/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
index c7f8a04b..d3e41e9 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
@@ -128,15 +128,21 @@
 
   transform1->Update(transform_root,
                      TransformPaintPropertyNode::State{FloatSize(20, 30)});
-  EXPECT_TRUE(transform1->Changed(transform_root));
-  EXPECT_TRUE(transform2->Changed(transform_root));
+  EXPECT_TRUE(transform1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                  transform_root));
+  EXPECT_TRUE(transform2->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                  transform_root));
   layers_.graphics_layer_client().SetNeedsRepaint(true);
   layers_.graphics_layer().PaintRecursively();
 
   // With BlinkGenPropertyTrees, these are not cleared until after paint.
   if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
-    EXPECT_FALSE(transform1->Changed(transform_root));
-    EXPECT_FALSE(transform2->Changed(transform_root));
+    EXPECT_FALSE(transform1->Changed(
+        PaintPropertyChangeType::kChangedOnlyCompositedAnimationValues,
+        transform_root));
+    EXPECT_FALSE(transform2->Changed(
+        PaintPropertyChangeType::kChangedOnlyCompositedAnimationValues,
+        transform_root));
   }
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.cc b/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.cc
index 726a5e0..82ee23a 100644
--- a/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.cc
@@ -20,14 +20,16 @@
 }
 
 bool ClipPaintPropertyNode::Changed(
+    PaintPropertyChangeType change,
     const PropertyTreeState& relative_to_state,
     const TransformPaintPropertyNode* transform_not_to_check) const {
   for (const auto* node = this; node && node != &relative_to_state.Clip();
        node = node->Parent()) {
-    if (node->NodeChanged())
+    if (node->NodeChanged() >= change)
       return true;
     if (&node->LocalTransformSpace() != transform_not_to_check &&
-        node->LocalTransformSpace().Changed(relative_to_state.Transform()))
+        node->LocalTransformSpace().Changed(change,
+                                            relative_to_state.Transform()))
       return true;
   }
 
@@ -38,8 +40,8 @@
   auto json = std::make_unique<JSONObject>();
   if (Parent())
     json->SetString("parent", String::Format("%p", Parent()));
-  if (NodeChanged())
-    json->SetBoolean("changed", true);
+  if (NodeChanged() != PaintPropertyChangeType::kUnchanged)
+    json->SetString("changed", PaintPropertyChangeTypeToString(NodeChanged()));
   json->SetString("localTransformSpace",
                   String::Format("%p", state_.local_transform_space.get()));
   json->SetString("rect", state_.clip_rect.ToString());
diff --git a/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h
index 36af18b..ffe70115 100644
--- a/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h
@@ -38,19 +38,15 @@
     scoped_refptr<const RefCountedPath> clip_path;
     CompositingReasons direct_compositing_reasons = CompositingReason::kNone;
 
-    // Returns true if the states are equal, ignoring the clip rect excluding
-    // overlay scrollbars which is only used for hit testing.
-    bool EqualIgnoringHitTestRects(const State& other) const {
-      return local_transform_space == other.local_transform_space &&
-             clip_rect == other.clip_rect && clip_path == other.clip_path &&
-             direct_compositing_reasons == other.direct_compositing_reasons;
-    }
-
     PaintPropertyChangeType ComputeChange(const State& other) const {
-      if (!EqualIgnoringHitTestRects(other) ||
+      if (local_transform_space != other.local_transform_space ||
+          clip_rect != other.clip_rect || clip_path != other.clip_path) {
+        return PaintPropertyChangeType::kChangedOnlyValues;
+      }
+      if (direct_compositing_reasons != other.direct_compositing_reasons ||
           clip_rect_excluding_overlay_scrollbars !=
               other.clip_rect_excluding_overlay_scrollbars) {
-        return PaintPropertyChangeType::kChangedOnlyValues;
+        return PaintPropertyChangeType::kChangedOnlyNonRerasterValues;
       }
       return PaintPropertyChangeType::kUnchanged;
     }
@@ -84,25 +80,22 @@
     if (state_changed != PaintPropertyChangeType::kUnchanged) {
       DCHECK(!IsParentAlias()) << "Changed the state of an alias node.";
       state_ = std::move(state);
-      SetChanged();
+      AddChanged(state_changed);
     }
     return std::max(parent_changed, state_changed);
   }
 
   // Checks if the accumulated clip from |this| to |relative_to_state.Clip()|
-  // has changed in the space of |relative_to_state.Transform()|. We check for
-  // changes of not only clip nodes, but also LocalTransformSpace relative to
-  // |relative_to_state.Transform()| of the clip nodes. |transform_not_to_check|
-  // specifies a transform node that the caller has checked or will check its
-  // change in other ways and this function should treat it as unchanged.
-  bool Changed(const PropertyTreeState& relative_to_state,
+  // has changed, at least significance of |change|, in the space of
+  // |relative_to_state.Transform()|. We check for changes of not only clip
+  // nodes, but also LocalTransformSpace relative to |relative_to_state
+  // .Transform()| of the clip nodes. |transform_not_to_check| specifies a
+  // transform node that the caller has checked or will check its change in
+  // other ways and this function should treat it as unchanged.
+  bool Changed(PaintPropertyChangeType change,
+               const PropertyTreeState& relative_to_state,
                const TransformPaintPropertyNode* transform_not_to_check) const;
 
-  bool EqualIgnoringHitTestRects(const ClipPaintPropertyNode* parent,
-                                 const State& state) const {
-    return parent == Parent() && state_.EqualIgnoringHitTestRects(state);
-  }
-
   // Returns the local transform space of this node. Note that the function
   // first unaliases the node, meaning that it walks up the parent chain until
   // it finds a concrete node (not a parent alias) or root. The reason for this
@@ -144,15 +137,16 @@
                         bool is_parent_alias)
       : PaintPropertyNode(parent, is_parent_alias), state_(std::move(state)) {}
 
-  void SetChanged() {
+  void AddChanged(PaintPropertyChangeType changed) {
     // TODO(crbug.com/814815): This is a workaround of the bug. When the bug is
     // fixed, change the following condition to
     //   DCHECK(!clip_cache_ || !clip_cache_->IsValid());
+    DCHECK_NE(PaintPropertyChangeType::kUnchanged, changed);
     if (clip_cache_ && clip_cache_->IsValid()) {
       DLOG(WARNING) << "Clip tree changed without invalidating the cache.";
       GeometryMapperClipCache::ClearCache();
     }
-    PaintPropertyNode::SetChanged();
+    PaintPropertyNode::AddChanged(changed);
   }
 
   // For access to GetClipCache();
diff --git a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc
index 9170d86..0c82591 100644
--- a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc
@@ -30,6 +30,7 @@
 }
 
 bool EffectPaintPropertyNode::Changed(
+    PaintPropertyChangeType change,
     const PropertyTreeState& relative_to_state,
     const TransformPaintPropertyNode* transform_not_to_check) const {
   const auto& relative_effect = relative_to_state.Effect();
@@ -40,7 +41,7 @@
   // might change).
   for (const auto* node = this; node && node != &relative_effect;
        node = node->Parent()) {
-    if (node->NodeChanged())
+    if (node->NodeChanged() >= change)
       return true;
 
     // We shouldn't check state on aliased nodes, other than NodeChanged().
@@ -50,7 +51,7 @@
     const auto& local_transform = node->LocalTransformSpace();
     if (node->HasFilterThatMovesPixels() &&
         &local_transform != transform_not_to_check &&
-        local_transform.Changed(relative_transform)) {
+        local_transform.Changed(change, relative_transform)) {
       return true;
     }
     // We don't check for change of OutputClip here to avoid N^3 complexity.
@@ -64,8 +65,8 @@
   auto json = std::make_unique<JSONObject>();
   if (Parent())
     json->SetString("parent", String::Format("%p", Parent()));
-  if (NodeChanged())
-    json->SetBoolean("changed", true);
+  if (NodeChanged() != PaintPropertyChangeType::kUnchanged)
+    json->SetString("changed", PaintPropertyChangeTypeToString(NodeChanged()));
   json->SetString("localTransformSpace",
                   String::Format("%p", state_.local_transform_space.get()));
   json->SetString("outputClip", String::Format("%p", state_.output_clip.get()));
diff --git a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
index 84b9b81..49c5a711 100644
--- a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
@@ -69,8 +69,6 @@
           color_filter != other.color_filter ||
           backdrop_filter_bounds != other.backdrop_filter_bounds ||
           blend_mode != other.blend_mode ||
-          direct_compositing_reasons != other.direct_compositing_reasons ||
-          compositor_element_id != other.compositor_element_id ||
           filters_origin != other.filters_origin) {
         return PaintPropertyChangeType::kChangedOnlyValues;
       }
@@ -89,6 +87,10 @@
           !animation_state.is_running_backdrop_filter_animation_on_compositor) {
         return PaintPropertyChangeType::kChangedOnlyValues;
       }
+      if (direct_compositing_reasons != other.direct_compositing_reasons ||
+          compositor_element_id != other.compositor_element_id) {
+        return PaintPropertyChangeType::kChangedOnlyNonRerasterValues;
+      }
       if (opacity_changed || filter_changed || backdrop_filter_changed) {
         return PaintPropertyChangeType::kChangedOnlyCompositedAnimationValues;
       }
@@ -120,20 +122,22 @@
     if (state_changed != PaintPropertyChangeType::kUnchanged) {
       DCHECK(!IsParentAlias()) << "Changed the state of an alias node.";
       state_ = std::move(state);
-      SetChanged();
+      AddChanged(state_changed);
     }
     return std::max(parent_changed, state_changed);
   }
 
   // Checks if the accumulated effect from |this| to |relative_to_state
-  // .Effect()| has changed in the space of |relative_to_state.Transform()|.
-  // We check for changes of not only effect nodes, but also LocalTransformSpace
-  // relative to |relative_to_state.Transform()| of the effect nodes having
-  // filters that move pixels. Change of OutputClip is not checked and the
-  // caller should check in other ways. |transform_not_to_check| specifies the
-  // transform node that the caller has checked or will check its change in
-  // other ways and this function should treat it as unchanged.
-  bool Changed(const PropertyTreeState& relative_to_state,
+  // .Effect()| has changed, at least significance of |change|, in the space of
+  // |relative_to_state.Transform()|. We check for changes of not only effect
+  // nodes, but also LocalTransformSpace relative to |relative_to_state
+  // .Transform()| of the effect nodes having filters that move pixels. Change
+  // of OutputClip is not checked and the caller should check in other ways.
+  // |transform_not_to_check| specifies the transform node that the caller has
+  // checked or will check its change in other ways and this function should
+  // treat it as unchanged.
+  bool Changed(PaintPropertyChangeType change,
+               const PropertyTreeState& relative_to_state,
                const TransformPaintPropertyNode* transform_not_to_check) const;
 
   const TransformPaintPropertyNode& LocalTransformSpace() const {
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.cc b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.cc
index 5bdf8fe..65c9dbd9 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.cc
@@ -90,4 +90,19 @@
   return LowestCommonAncestorTemplate(a, b);
 }
 
+const char* PaintPropertyChangeTypeToString(PaintPropertyChangeType change) {
+  switch (change) {
+    case PaintPropertyChangeType::kUnchanged:
+      return "unchanged";
+    case PaintPropertyChangeType::kChangedOnlyCompositedAnimationValues:
+      return "animation";
+    case PaintPropertyChangeType::kChangedOnlyNonRerasterValues:
+      return "non-reraster";
+    case PaintPropertyChangeType::kChangedOnlyValues:
+      return "values";
+    case PaintPropertyChangeType::kNodeAddedOrRemoved:
+      return "node-add-remove";
+  }
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
index f26547b..c4fe555 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
@@ -5,6 +5,8 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_PROPERTY_NODE_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_PROPERTY_NODE_H_
 
+#include <algorithm>
+#include <iosfwd>
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/platform/json/json_values.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
@@ -16,8 +18,6 @@
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 #endif
 
-#include <iosfwd>
-
 namespace blink {
 
 class ClipPaintPropertyNode;
@@ -27,12 +27,11 @@
 
 // Used to report whether and how paint properties have changed. The order is
 // important - it must go from no change to the most significant change.
-enum class PaintPropertyChangeType {
+enum class PaintPropertyChangeType : unsigned char {
   kUnchanged,
   kChangedOnlyCompositedAnimationValues,
+  kChangedOnlyNonRerasterValues,
   kChangedOnlyValues,
-  // A paint property node is added or removed. This value is used only in
-  // renderer/core classes.
   kNodeAddedOrRemoved,
 };
 
@@ -88,7 +87,7 @@
   void ClearChangedToRoot() const { ClearChangedTo(nullptr); }
   void ClearChangedTo(const NodeType* node) const {
     for (auto* n = this; n && n != node; n = n->Parent())
-      n->changed_ = false;
+      n->changed_ = PaintPropertyChangeType::kUnchanged;
   }
 
   // Returns true if this node is an alias for its parent. A parent alias is a
@@ -126,7 +125,8 @@
   PaintPropertyNode(const NodeType* parent, bool is_parent_alias = false)
       : parent_(parent),
         is_parent_alias_(is_parent_alias),
-        changed_(!!parent) {}
+        changed_(parent ? PaintPropertyChangeType::kNodeAddedOrRemoved
+                        : PaintPropertyChangeType::kUnchanged) {}
 
   PaintPropertyChangeType SetParent(const NodeType* parent) {
     DCHECK(!IsRoot());
@@ -135,15 +135,16 @@
       return PaintPropertyChangeType::kUnchanged;
 
     parent_ = parent;
-    static_cast<NodeType*>(this)->SetChanged();
+    static_cast<NodeType*>(this)->AddChanged(
+        PaintPropertyChangeType::kChangedOnlyValues);
     return PaintPropertyChangeType::kChangedOnlyValues;
   }
 
-  void SetChanged() {
+  void AddChanged(PaintPropertyChangeType changed) {
     DCHECK(!IsRoot());
-    changed_ = true;
+    changed_ = std::max(changed_, changed);
   }
-  bool NodeChanged() const { return changed_; }
+  PaintPropertyChangeType NodeChanged() const { return changed_; }
 
  private:
   friend class PaintPropertyNodeTest;
@@ -151,10 +152,11 @@
   friend class ObjectPaintProperties;
 
   scoped_refptr<const NodeType> parent_;
+
   // Indicates whether this node is an alias for its parent. Parent aliases are
   // nodes that do not affect rendering and are ignored for the purposes of
   // display item list generation.
-  bool is_parent_alias_ = false;
+  bool is_parent_alias_;
 
   // Indicates that the paint property value changed in the last update in the
   // prepaint lifecycle step. This is used for raster invalidation and damage
@@ -162,7 +164,7 @@
   // BlinkGenPropertyTrees, this is cleared explicitly at the end of paint (see:
   // LocalFrameView::RunPaintLifecyclePhase), otherwise this is cleared through
   // PaintController::FinishCycle.
-  mutable bool changed_ = true;
+  mutable PaintPropertyChangeType changed_;
 
 #if DCHECK_IS_ON()
   String debug_name_;
@@ -235,6 +237,14 @@
   return os << static_cast<const NodeType&>(node).ToString().Utf8().data();
 }
 
+PLATFORM_EXPORT const char* PaintPropertyChangeTypeToString(
+    PaintPropertyChangeType);
+
+inline std::ostream& operator<<(std::ostream& os,
+                                PaintPropertyChangeType change) {
+  return os << PaintPropertyChangeTypeToString(change);
+}
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_PROPERTY_NODE_H_
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc b/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc
index 17f7b59..40b63d49 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc
@@ -82,22 +82,30 @@
 
   template <typename NodeType>
   void ExpectInitialState(const Tree<NodeType>& tree) {
-    EXPECT_FALSE(tree.root->NodeChanged());
-    EXPECT_TRUE(tree.ancestor->NodeChanged());
-    EXPECT_TRUE(tree.child1->NodeChanged());
-    EXPECT_TRUE(tree.child2->NodeChanged());
-    EXPECT_TRUE(tree.grandchild1->NodeChanged());
-    EXPECT_TRUE(tree.grandchild2->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kUnchanged, tree.root->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kNodeAddedOrRemoved,
+              tree.ancestor->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kNodeAddedOrRemoved,
+              tree.child1->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kNodeAddedOrRemoved,
+              tree.child2->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kNodeAddedOrRemoved,
+              tree.grandchild1->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kNodeAddedOrRemoved,
+              tree.grandchild2->NodeChanged());
   }
 
   template <typename NodeType>
   void ExpectUnchangedState(const Tree<NodeType>& tree) {
-    EXPECT_FALSE(tree.root->NodeChanged());
-    EXPECT_FALSE(tree.ancestor->NodeChanged());
-    EXPECT_FALSE(tree.child1->NodeChanged());
-    EXPECT_FALSE(tree.child2->NodeChanged());
-    EXPECT_FALSE(tree.grandchild1->NodeChanged());
-    EXPECT_FALSE(tree.grandchild2->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kUnchanged, tree.root->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kUnchanged,
+              tree.ancestor->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kUnchanged, tree.child1->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kUnchanged, tree.child2->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kUnchanged,
+              tree.grandchild1->NodeChanged());
+    EXPECT_EQ(PaintPropertyChangeType::kUnchanged,
+              tree.grandchild2->NodeChanged());
   }
 
   void ExpectUnchangedState() {
@@ -156,17 +164,25 @@
       *transform.root, TransformPaintPropertyNode::State{FloatSize(1, 2)});
 
   // Test descendant->Changed(ancestor).
-  EXPECT_TRUE(transform.ancestor->Changed(*transform.root));
-  EXPECT_FALSE(transform.ancestor->Changed(*transform.ancestor));
-  EXPECT_TRUE(transform.child1->Changed(*transform.root));
-  EXPECT_FALSE(transform.child1->Changed(*transform.ancestor));
-  EXPECT_TRUE(transform.grandchild1->Changed(*transform.root));
-  EXPECT_FALSE(transform.grandchild1->Changed(*transform.ancestor));
+  EXPECT_TRUE(transform.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.root));
+  EXPECT_FALSE(transform.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.root));
+  EXPECT_FALSE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
+  EXPECT_TRUE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.root));
+  EXPECT_FALSE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
 
   // Test property->Changed(non-ancestor-property). Should combine the changed
   // flags of the two paths to the root.
-  EXPECT_TRUE(transform.grandchild1->Changed(*transform.child2));
-  EXPECT_TRUE(transform.grandchild1->Changed(*transform.grandchild2));
+  EXPECT_TRUE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.child2));
+  EXPECT_TRUE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.grandchild2));
 
   ResetAllChanged();
   ExpectUnchangedState();
@@ -180,17 +196,26 @@
                                                FloatRoundedRect(1, 2, 3, 4)});
 
   // Test descendant->Changed(ancestor).
-  EXPECT_TRUE(clip.ancestor->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(clip.ancestor->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(clip.child1->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(clip.child1->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(clip.grandchild1->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(clip.grandchild1->Changed(STATE(ancestor), nullptr));
+  EXPECT_TRUE(clip.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(clip.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_TRUE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                   STATE(root), nullptr));
+  EXPECT_FALSE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                    STATE(ancestor), nullptr));
+  EXPECT_TRUE(clip.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(clip.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
 
   // Test property->Changed(non-ancestor-property).
   // Simply walk to the root.
-  EXPECT_TRUE(clip.grandchild1->Changed(STATE(child2), nullptr));
-  EXPECT_TRUE(clip.grandchild1->Changed(STATE(grandchild2), nullptr));
+  EXPECT_TRUE(clip.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child2), nullptr));
+  EXPECT_TRUE(
+      clip.grandchild1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                STATE(grandchild2), nullptr));
 
   ResetAllChanged();
   ExpectUnchangedState();
@@ -205,17 +230,68 @@
   effect.ancestor->Update(*effect.root, std::move(state));
 
   // Test descendant->Changed(ancestor).
-  EXPECT_TRUE(effect.ancestor->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(effect.ancestor->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(effect.child1->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(effect.child1->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(effect.grandchild1->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(effect.grandchild1->Changed(STATE(ancestor), nullptr));
+  EXPECT_TRUE(effect.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(effect.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_TRUE(effect.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(effect.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_TRUE(effect.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(effect.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
 
   // Test property->Changed(non-ancestor-property).
   // Simply walk to the root.
-  EXPECT_TRUE(effect.grandchild1->Changed(STATE(child2), nullptr));
-  EXPECT_TRUE(effect.grandchild1->Changed(STATE(grandchild2), nullptr));
+  EXPECT_TRUE(effect.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child2), nullptr));
+  EXPECT_TRUE(
+      effect.grandchild1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                  STATE(grandchild2), nullptr));
+
+  ResetAllChanged();
+  ExpectUnchangedState();
+}
+
+TEST_F(PaintPropertyNodeTest, ChangeDirectCompositingReason) {
+  ResetAllChanged();
+  ExpectUnchangedState();
+  TransformPaintPropertyNode::State state;
+  state.direct_compositing_reasons =
+      CompositingReason::kActiveTransformAnimation;
+  transform.child1->Update(*transform.ancestor, std::move(state));
+
+  EXPECT_FALSE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.root));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyNonRerasterValues, *transform.root));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyCompositedAnimationValues,
+      *transform.root));
+
+  ResetAllChanged();
+  ExpectUnchangedState();
+}
+
+TEST_F(PaintPropertyNodeTest, ChangeTransformDuringCompositedAnimation) {
+  ResetAllChanged();
+  ExpectUnchangedState();
+  TransformPaintPropertyNode::AnimationState animation_state;
+  animation_state.is_running_animation_on_compositor = true;
+  transform.child1->Update(
+      *transform.ancestor,
+      TransformPaintPropertyNode::State{TransformationMatrix().Scale(2)},
+      animation_state);
+
+  EXPECT_FALSE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.root));
+  EXPECT_FALSE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyNonRerasterValues, *transform.root));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyCompositedAnimationValues,
+      *transform.root));
 
   ResetAllChanged();
   ExpectUnchangedState();
@@ -228,25 +304,41 @@
                            TransformPaintPropertyNode::State{FloatSize(1, 2)});
 
   // Test descendant->Changed(ancestor).
-  EXPECT_FALSE(transform.ancestor->Changed(*transform.root));
-  EXPECT_FALSE(transform.ancestor->Changed(*transform.ancestor));
-  EXPECT_TRUE(transform.child1->Changed(*transform.root));
-  EXPECT_TRUE(transform.child1->Changed(*transform.ancestor));
-  EXPECT_TRUE(transform.grandchild1->Changed(*transform.ancestor));
-  EXPECT_FALSE(transform.grandchild1->Changed(*transform.child1));
-  EXPECT_FALSE(transform.child2->Changed(*transform.ancestor));
-  EXPECT_FALSE(transform.grandchild2->Changed(*transform.ancestor));
+  EXPECT_FALSE(transform.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.root));
+  EXPECT_FALSE(transform.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.root));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
+  EXPECT_TRUE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
+  EXPECT_FALSE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.child1));
+  EXPECT_FALSE(transform.child2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
+  EXPECT_FALSE(transform.grandchild2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
 
   // Test property->Changed(non-ancestor-property). Need to combine the changed
   // flags of the two paths to the root.
-  EXPECT_TRUE(transform.child2->Changed(*transform.child1));
-  EXPECT_TRUE(transform.child1->Changed(*transform.child2));
-  EXPECT_TRUE(transform.child2->Changed(*transform.grandchild1));
-  EXPECT_TRUE(transform.child1->Changed(*transform.grandchild2));
-  EXPECT_TRUE(transform.grandchild1->Changed(*transform.child2));
-  EXPECT_TRUE(transform.grandchild1->Changed(*transform.grandchild2));
-  EXPECT_TRUE(transform.grandchild2->Changed(*transform.child1));
-  EXPECT_TRUE(transform.grandchild2->Changed(*transform.grandchild1));
+  EXPECT_TRUE(transform.child2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.child1));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.child2));
+  EXPECT_TRUE(transform.child2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.grandchild1));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.grandchild2));
+  EXPECT_TRUE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.child2));
+  EXPECT_TRUE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.grandchild2));
+  EXPECT_TRUE(transform.grandchild2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.child1));
+  EXPECT_TRUE(transform.grandchild2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.grandchild1));
 
   ResetAllChanged();
   ExpectUnchangedState();
@@ -260,25 +352,44 @@
                                                FloatRoundedRect(1, 2, 3, 4)});
 
   // Test descendant->Changed(ancestor).
-  EXPECT_FALSE(clip.ancestor->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(clip.ancestor->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(clip.child1->Changed(STATE(root), nullptr));
-  EXPECT_TRUE(clip.child1->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(clip.grandchild1->Changed(STATE(ancestor), nullptr));
-  EXPECT_FALSE(clip.grandchild1->Changed(STATE(child1), nullptr));
-  EXPECT_FALSE(clip.child2->Changed(STATE(ancestor), nullptr));
-  EXPECT_FALSE(clip.grandchild2->Changed(STATE(ancestor), nullptr));
+  EXPECT_FALSE(clip.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(clip.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_TRUE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                   STATE(root), nullptr));
+  EXPECT_TRUE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                   STATE(ancestor), nullptr));
+  EXPECT_TRUE(clip.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_FALSE(clip.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child1), nullptr));
+  EXPECT_FALSE(clip.child2->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                    STATE(ancestor), nullptr));
+  EXPECT_FALSE(clip.grandchild2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
 
-  // Test property->Changed(non-ancestor-property).
-  // Simply walk to the root, regardless of relative_to_state's path.
-  EXPECT_FALSE(clip.child2->Changed(STATE(child1), nullptr));
-  EXPECT_TRUE(clip.child1->Changed(STATE(child2), nullptr));
-  EXPECT_FALSE(clip.child2->Changed(STATE(grandchild1), nullptr));
-  EXPECT_TRUE(clip.child1->Changed(STATE(grandchild2), nullptr));
-  EXPECT_TRUE(clip.grandchild1->Changed(STATE(child2), nullptr));
-  EXPECT_TRUE(clip.grandchild1->Changed(STATE(grandchild2), nullptr));
-  EXPECT_FALSE(clip.grandchild2->Changed(STATE(child1), nullptr));
-  EXPECT_FALSE(clip.grandchild2->Changed(STATE(grandchild1), nullptr));
+  // Test property->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+  // non-ancestor-property). Simply walk to the root, regardless of
+  // relative_to_state's path.
+  EXPECT_FALSE(clip.child2->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                    STATE(child1), nullptr));
+  EXPECT_TRUE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                   STATE(child2), nullptr));
+  EXPECT_FALSE(clip.child2->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                    STATE(grandchild1), nullptr));
+  EXPECT_TRUE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                   STATE(grandchild2), nullptr));
+  EXPECT_TRUE(clip.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child2), nullptr));
+  EXPECT_TRUE(
+      clip.grandchild1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                STATE(grandchild2), nullptr));
+  EXPECT_FALSE(clip.grandchild2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child1), nullptr));
+  EXPECT_FALSE(
+      clip.grandchild2->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                STATE(grandchild1), nullptr));
 
   ResetAllChanged();
   ExpectUnchangedState();
@@ -292,26 +403,48 @@
   state.opacity = 0.9;
   effect.child1->Update(*effect.root, std::move(state));
 
-  // Test descendant->Changed(ancestor).
-  EXPECT_FALSE(effect.ancestor->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(effect.ancestor->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(effect.child1->Changed(STATE(root), nullptr));
-  EXPECT_TRUE(effect.child1->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(effect.grandchild1->Changed(STATE(ancestor), nullptr));
-  EXPECT_FALSE(effect.grandchild1->Changed(STATE(child1), nullptr));
-  EXPECT_FALSE(effect.child2->Changed(STATE(ancestor), nullptr));
-  EXPECT_FALSE(effect.grandchild2->Changed(STATE(ancestor), nullptr));
+  // Test descendant->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+  // ancestor).
+  EXPECT_FALSE(effect.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(effect.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_TRUE(effect.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_TRUE(effect.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_TRUE(effect.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_FALSE(effect.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child1), nullptr));
+  EXPECT_FALSE(effect.child2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_FALSE(effect.grandchild2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
 
-  // Test property->Changed(non-ancestor-property).
-  // Simply walk to the root, regardless of relative_to_state's path.
-  EXPECT_FALSE(effect.child2->Changed(STATE(child1), nullptr));
-  EXPECT_TRUE(effect.child1->Changed(STATE(child2), nullptr));
-  EXPECT_FALSE(effect.child2->Changed(STATE(grandchild1), nullptr));
-  EXPECT_TRUE(effect.child1->Changed(STATE(grandchild2), nullptr));
-  EXPECT_TRUE(effect.grandchild1->Changed(STATE(child2), nullptr));
-  EXPECT_TRUE(effect.grandchild1->Changed(STATE(grandchild2), nullptr));
-  EXPECT_FALSE(effect.grandchild2->Changed(STATE(child1), nullptr));
-  EXPECT_FALSE(effect.grandchild2->Changed(STATE(grandchild1), nullptr));
+  // Test property->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+  // non-ancestor-property). Simply walk to the root, regardless of
+  // relative_to_state's path.
+  EXPECT_FALSE(effect.child2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child1), nullptr));
+  EXPECT_TRUE(effect.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child2), nullptr));
+  EXPECT_FALSE(
+      effect.child2->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                             STATE(grandchild1), nullptr));
+  EXPECT_TRUE(
+      effect.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                             STATE(grandchild2), nullptr));
+  EXPECT_TRUE(effect.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child2), nullptr));
+  EXPECT_TRUE(
+      effect.grandchild1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                  STATE(grandchild2), nullptr));
+  EXPECT_FALSE(effect.grandchild2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child1), nullptr));
+  EXPECT_FALSE(
+      effect.grandchild2->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                  STATE(grandchild1), nullptr));
 
   ResetAllChanged();
   ExpectUnchangedState();
@@ -322,13 +455,20 @@
   ExpectUnchangedState();
   transform.child1->Update(*transform.child2,
                            TransformPaintPropertyNode::State{FloatSize(1, 2)});
-  EXPECT_FALSE(transform.ancestor->Changed(*transform.root));
-  EXPECT_TRUE(transform.child1->Changed(*transform.ancestor));
-  EXPECT_TRUE(transform.child1->Changed(*transform.child2));
-  EXPECT_FALSE(transform.child2->Changed(*transform.ancestor));
-  EXPECT_TRUE(transform.grandchild1->Changed(*transform.ancestor));
-  EXPECT_FALSE(transform.grandchild1->Changed(*transform.child1));
-  EXPECT_TRUE(transform.grandchild1->Changed(*transform.child2));
+  EXPECT_FALSE(transform.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.root));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
+  EXPECT_TRUE(transform.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.child2));
+  EXPECT_FALSE(transform.child2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
+  EXPECT_TRUE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.ancestor));
+  EXPECT_FALSE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.child1));
+  EXPECT_TRUE(transform.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, *transform.child2));
 
   ResetAllChanged();
   ExpectUnchangedState();
@@ -340,22 +480,34 @@
   transform.child1->Update(*transform.ancestor,
                            TransformPaintPropertyNode::State{FloatSize(1, 2)});
 
-  EXPECT_FALSE(clip.ancestor->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(clip.ancestor->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(clip.child1->Changed(STATE(root), nullptr));
-  EXPECT_TRUE(clip.child1->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(clip.grandchild1->Changed(STATE(ancestor), nullptr));
-  EXPECT_FALSE(clip.grandchild1->Changed(STATE(child1), nullptr));
+  EXPECT_FALSE(clip.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(clip.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_TRUE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                   STATE(root), nullptr));
+  EXPECT_TRUE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                   STATE(ancestor), nullptr));
+  EXPECT_TRUE(clip.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_FALSE(clip.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child1), nullptr));
 
   // Test with transform_not_to_check.
-  EXPECT_FALSE(clip.child1->Changed(STATE(root), transform.child1.get()));
-  EXPECT_FALSE(clip.child1->Changed(STATE(ancestor), transform.child1.get()));
+  EXPECT_FALSE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                    STATE(root), transform.child1.get()));
+  EXPECT_FALSE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                    STATE(ancestor), transform.child1.get()));
   EXPECT_TRUE(
-      clip.grandchild1->Changed(STATE(ancestor), transform.child1.get()));
-  EXPECT_TRUE(clip.child1->Changed(STATE(root), transform.ancestor.get()));
-  EXPECT_TRUE(clip.child1->Changed(STATE(ancestor), transform.ancestor.get()));
+      clip.grandchild1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                STATE(ancestor), transform.child1.get()));
+  EXPECT_TRUE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                   STATE(root), transform.ancestor.get()));
+  EXPECT_TRUE(clip.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                   STATE(ancestor), transform.ancestor.get()));
   EXPECT_TRUE(
-      clip.grandchild1->Changed(STATE(ancestor), transform.ancestor.get()));
+      clip.grandchild1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                                STATE(ancestor), transform.ancestor.get()));
 
   ResetAllChanged();
   ExpectUnchangedState();
@@ -373,21 +525,34 @@
   transform.ancestor->Update(
       *transform.root, TransformPaintPropertyNode::State{FloatSize(1, 2)});
 
-  EXPECT_FALSE(effect.ancestor->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(effect.ancestor->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(effect.child1->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(effect.child1->Changed(STATE(ancestor), nullptr));
-  EXPECT_TRUE(effect.grandchild1->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(effect.grandchild1->Changed(STATE(ancestor), nullptr));
-  EXPECT_FALSE(effect.grandchild1->Changed(STATE(child1), nullptr));
+  EXPECT_FALSE(effect.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(effect.ancestor->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_TRUE(effect.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(effect.child1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_TRUE(effect.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(effect.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(ancestor), nullptr));
+  EXPECT_FALSE(effect.grandchild1->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(child1), nullptr));
   // Effects without self or ancestor pixel-moving filter are not affected by
   // change of LocalTransformSpace.
-  EXPECT_FALSE(effect.child2->Changed(STATE(root), nullptr));
-  EXPECT_FALSE(effect.grandchild2->Changed(STATE(root), nullptr));
+  EXPECT_FALSE(effect.child2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
+  EXPECT_FALSE(effect.grandchild2->Changed(
+      PaintPropertyChangeType::kChangedOnlyValues, STATE(root), nullptr));
 
   // Test with transform_not_to_check.
-  EXPECT_FALSE(effect.child1->Changed(STATE(root), transform.child1.get()));
-  EXPECT_TRUE(effect.child1->Changed(STATE(root), transform.ancestor.get()));
+  EXPECT_FALSE(
+      effect.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                             STATE(root), transform.child1.get()));
+  EXPECT_TRUE(
+      effect.child1->Changed(PaintPropertyChangeType::kChangedOnlyValues,
+                             STATE(root), transform.ancestor.get()));
 
   ResetAllChanged();
   ExpectUnchangedState();
diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
index 86ecc007..e1399727 100644
--- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
@@ -106,8 +106,9 @@
   // different, or the effect node's value changed between the layer state and
   // the chunk state.
   if (&new_chunk_state.Effect() != &old_chunk_state.Effect() ||
-      new_chunk_state.Effect().Changed(layer_state,
-                                       &new_chunk_state.Transform()))
+      new_chunk_state.Effect().Changed(
+          PaintPropertyChangeType::kChangedOnlyValues, layer_state,
+          &new_chunk_state.Transform()))
     return PaintInvalidationReason::kPaintProperty;
 
   // Check for accumulated clip rect change, if the clip rects are tight.
@@ -127,7 +128,9 @@
   // different, or the clip node's value changed between the layer state and the
   // chunk state.
   if (&new_chunk_state.Clip() != &old_chunk_state.Clip() ||
-      new_chunk_state.Clip().Changed(layer_state, &new_chunk_state.Transform()))
+      new_chunk_state.Clip().Changed(
+          PaintPropertyChangeType::kChangedOnlyValues, layer_state,
+          &new_chunk_state.Transform()))
     return PaintInvalidationReason::kPaintProperty;
 
   return PaintInvalidationReason::kNone;
diff --git a/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h
index 39c9aa4..5f35934 100644
--- a/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h
@@ -102,7 +102,7 @@
     if (state_changed != PaintPropertyChangeType::kUnchanged) {
       state_ = std::move(state);
       Validate();
-      SetChanged();
+      AddChanged(state_changed);
     }
     return std::max(parent_changed, state_changed);
   }
diff --git a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc
index 96a9e1c0..a236f4f 100644
--- a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc
@@ -30,25 +30,26 @@
 }
 
 bool TransformPaintPropertyNode::Changed(
+    PaintPropertyChangeType change,
     const TransformPaintPropertyNode& relative_to_node) const {
   for (const auto* node = this; node; node = node->Parent()) {
     if (node == &relative_to_node)
       return false;
-    if (node->NodeChanged())
+    if (node->NodeChanged() >= change)
       return true;
   }
 
   // |this| is not a descendant of |relative_to_node|. We have seen no changed
   // flag from |this| to the root. Now check |relative_to_node| to the root.
-  return relative_to_node.Changed(Root());
+  return relative_to_node.Changed(change, Root());
 }
 
 std::unique_ptr<JSONObject> TransformPaintPropertyNode::ToJSON() const {
   auto json = std::make_unique<JSONObject>();
   if (Parent())
     json->SetString("parent", String::Format("%p", Parent()));
-  if (NodeChanged())
-    json->SetBoolean("changed", true);
+  if (NodeChanged() != PaintPropertyChangeType::kUnchanged)
+    json->SetString("changed", PaintPropertyChangeTypeToString(NodeChanged()));
   if (IsIdentityOr2DTranslation()) {
     if (!Translation2D().IsZero())
       json->SetString("translation2d", Translation2D().ToString());
diff --git a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
index 1510db5b..4c05cbf 100644
--- a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
@@ -129,19 +129,23 @@
               other.affected_by_outer_viewport_bounds_delta ||
           backface_visibility != other.backface_visibility ||
           rendering_context_id != other.rendering_context_id ||
-          direct_compositing_reasons != other.direct_compositing_reasons ||
           compositor_element_id != other.compositor_element_id ||
           scroll != other.scroll ||
-          affected_by_outer_viewport_bounds_delta !=
-              other.affected_by_outer_viewport_bounds_delta ||
           !StickyConstraintEquals(other)) {
         return PaintPropertyChangeType::kChangedOnlyValues;
       }
-      if (!transform_and_origin.TransformEquals(other.transform_and_origin)) {
-        return animation_state.is_running_animation_on_compositor
-                   ? PaintPropertyChangeType::
-                         kChangedOnlyCompositedAnimationValues
-                   : PaintPropertyChangeType::kChangedOnlyValues;
+      bool transform_changed =
+          !transform_and_origin.TransformEquals(other.transform_and_origin);
+      if (!animation_state.is_running_animation_on_compositor &&
+          transform_changed) {
+        return PaintPropertyChangeType::kChangedOnlyValues;
+      }
+      if (direct_compositing_reasons != other.direct_compositing_reasons) {
+        return PaintPropertyChangeType::kChangedOnlyNonRerasterValues;
+      }
+      if (animation_state.is_running_animation_on_compositor &&
+          transform_changed) {
+        return PaintPropertyChangeType::kChangedOnlyCompositedAnimationValues;
       }
       return PaintPropertyChangeType::kUnchanged;
     }
@@ -179,17 +183,18 @@
     if (state_changed != PaintPropertyChangeType::kUnchanged) {
       DCHECK(!IsParentAlias()) << "Changed the state of an alias node.";
       state_ = std::move(state);
-      SetChanged();
+      AddChanged(state_changed);
       Validate();
     }
     return std::max(parent_changed, state_changed);
   }
 
   // If |relative_to_node| is an ancestor of |this|, returns true if any node is
-  // marked changed along the path from |this| to |relative_to_node| (not
-  // included). Otherwise returns the combined changed status of the paths
-  // from |this| and |relative_to_node| to the root.
-  bool Changed(const TransformPaintPropertyNode& relative_to_node) const;
+  // marked changed, at least significance of |change|, along the path from
+  // |this| to |relative_to_node| (not included). Otherwise returns the combined
+  // changed status of the paths from |this| and |relative_to_node| to the root.
+  bool Changed(PaintPropertyChangeType change,
+               const TransformPaintPropertyNode& relative_to_node) const;
 
   bool IsIdentityOr2DTranslation() const {
     return state_.transform_and_origin.IsIdentityOr2DTranslation();
@@ -320,16 +325,17 @@
 #endif
   }
 
-  void SetChanged() {
+  void AddChanged(PaintPropertyChangeType changed) {
     // TODO(crbug.com/814815): This is a workaround of the bug. When the bug is
     // fixed, change the following condition to
     //   DCHECK(!transform_cache_ || !transform_cache_->IsValid());
+    DCHECK_NE(PaintPropertyChangeType::kUnchanged, changed);
     if (transform_cache_ && transform_cache_->IsValid()) {
       DLOG(WARNING) << "Transform tree changed without invalidating the cache.";
       GeometryMapperTransformCache::ClearCache();
       GeometryMapperClipCache::ClearCache();
     }
-    PaintPropertyNode::SetChanged();
+    PaintPropertyNode::AddChanged(changed);
   }
 
   // For access to GetTransformCache() and SetCachedTransform.
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc
index 09b23ba5b..0e4c5c62 100644
--- a/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -1696,7 +1696,7 @@
   current_gc_data_.reason = reason;
   current_gc_data_.visitor =
       IsUnifiedGCMarkingInProgress()
-          ? UnifiedHeapMarkingVisitor::Create(
+          ? std::make_unique<UnifiedHeapMarkingVisitor>(
                 this, GetMarkingMode(should_compact, take_snapshot),
                 GetIsolate())
           : std::make_unique<MarkingVisitor>(
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
index 2340a92..fada1f9 100644
--- a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
+++ b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
@@ -11,16 +11,6 @@
 
 namespace blink {
 
-std::unique_ptr<UnifiedHeapMarkingVisitor> UnifiedHeapMarkingVisitor::Create(
-    ThreadState* thread_state,
-    MarkingMode mode,
-    v8::Isolate* isolate) {
-  DCHECK(thread_state);
-  DCHECK(isolate);
-  return std::unique_ptr<UnifiedHeapMarkingVisitor>(
-      new UnifiedHeapMarkingVisitor(thread_state, mode, isolate));
-}
-
 UnifiedHeapMarkingVisitor::UnifiedHeapMarkingVisitor(ThreadState* thread_state,
                                                      MarkingMode mode,
                                                      v8::Isolate* isolate)
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
index f14c8729..17c4b85 100644
--- a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
+++ b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
@@ -21,9 +21,8 @@
 // methods that allow for announcing reachable objects to V8.
 class PLATFORM_EXPORT UnifiedHeapMarkingVisitor final : public MarkingVisitor {
  public:
-  static std::unique_ptr<UnifiedHeapMarkingVisitor> Create(ThreadState*,
-                                                           MarkingMode,
-                                                           v8::Isolate*);
+  UnifiedHeapMarkingVisitor(ThreadState*, MarkingMode, v8::Isolate*);
+
   // Write barriers for annotating a write during incremental marking.
   static void WriteBarrier(const TraceWrapperV8Reference<v8::Value>&);
   static void WriteBarrier(v8::Isolate*, const WrapperTypeInfo*, void*);
@@ -34,8 +33,6 @@
   void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
 
  private:
-  UnifiedHeapMarkingVisitor(ThreadState*, MarkingMode, v8::Isolate*);
-
   v8::Isolate* const isolate_;
   v8::EmbedderHeapTracer* const controller_;
 
diff --git a/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.cc
index 087126e..2a8640b 100644
--- a/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.cc
+++ b/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.cc
@@ -27,7 +27,7 @@
 
 #include <limits>
 #include "third_party/blink/renderer/platform/image-decoders/segment_stream.h"
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc b/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc
index 9e876c5..c9db129 100644
--- a/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc
+++ b/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc
@@ -110,7 +110,7 @@
     Persistent<MockConsoleLogger> logger =
         MakeGarbageCollected<MockConsoleLogger>();
     ResourceResponse response(url);
-    response.SetHTTPHeaderField("Content-Type", testcase.mimetype);
+    response.SetHttpHeaderField("Content-Type", testcase.mimetype);
 
     // Nosniff 'legacy' setting: Both worker + non-worker obey the 'allowed'
     // setting. Warnings for any blocked script.
@@ -221,7 +221,7 @@
     Persistent<MockConsoleLogger> logger =
         MakeGarbageCollected<MockConsoleLogger>();
     ResourceResponse response(KURL(testcase.url));
-    response.SetHTTPHeaderField("Content-Type", testcase.mimetype);
+    response.SetHttpHeaderField("Content-Type", testcase.mimetype);
 
     EXPECT_CALL(*context, CountUsage(testcase.expected));
     EXPECT_CALL(*context, CountUsage(::testing::Ne(testcase.expected)))
@@ -269,8 +269,8 @@
     SCOPED_TRACE(testing::Message() << "\n  url: " << testcase.url
                                     << "\n  allowed: " << testcase.allowed);
     ResourceResponse response(KURL(testcase.url));
-    response.SetHTTPHeaderField("Content-Type", "invalid");
-    response.SetHTTPHeaderField("X-Content-Type-Options", "nosniff");
+    response.SetHttpHeaderField("Content-Type", "invalid");
+    response.SetHttpHeaderField("X-Content-Type-Options", "nosniff");
     EXPECT_EQ(testcase.allowed,
               AllowedByNosniff::MimeTypeAsScript(*context, logger, response,
                                                  MimeTypeCheck::kLax, false));
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
index 01674de..44ec3ca7 100644
--- a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
@@ -148,7 +148,7 @@
   // likely capture the entire image for small images and (b) likely contain
   // the dimensions for larger images.
   // TODO(sclittle): Calculate the optimal value for this number.
-  resource_request_.SetHTTPHeaderField("range", "bytes=0-2047");
+  resource_request_.SetHttpHeaderField("range", "bytes=0-2047");
 
   // TODO(sclittle): Indicate somehow (e.g. through a new request bit) to the
   // embedder that it should return the full resource if the entire resource is
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 c6ac975..e44330c 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
@@ -139,8 +139,8 @@
 TEST_F(MemoryCacheCorrectnessTest, FreshFromLastModified) {
   ResourceResponse fresh200_response;
   fresh200_response.SetHttpStatusCode(200);
-  fresh200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
-  fresh200_response.SetHTTPHeaderField("Last-Modified",
+  fresh200_response.SetHttpHeaderField("Date", kOriginalRequestDateAsString);
+  fresh200_response.SetHttpHeaderField("Last-Modified",
                                        kOneDayBeforeOriginalRequest);
 
   MockResource* fresh200 = ResourceFromResourceResponse(fresh200_response);
@@ -156,8 +156,8 @@
 TEST_F(MemoryCacheCorrectnessTest, FreshFromExpires) {
   ResourceResponse fresh200_response;
   fresh200_response.SetHttpStatusCode(200);
-  fresh200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
-  fresh200_response.SetHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+  fresh200_response.SetHttpHeaderField("Date", kOriginalRequestDateAsString);
+  fresh200_response.SetHttpHeaderField("Expires", kOneDayAfterOriginalRequest);
 
   MockResource* fresh200 = ResourceFromResourceResponse(fresh200_response);
 
@@ -172,8 +172,8 @@
 TEST_F(MemoryCacheCorrectnessTest, FreshFromMaxAge) {
   ResourceResponse fresh200_response;
   fresh200_response.SetHttpStatusCode(200);
-  fresh200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
-  fresh200_response.SetHTTPHeaderField("Cache-Control", "max-age=600");
+  fresh200_response.SetHttpHeaderField("Date", kOriginalRequestDateAsString);
+  fresh200_response.SetHttpHeaderField("Cache-Control", "max-age=600");
 
   MockResource* fresh200 = ResourceFromResourceResponse(fresh200_response);
 
@@ -188,8 +188,8 @@
 TEST_F(MemoryCacheCorrectnessTest, ExpiredFromLastModified) {
   ResourceResponse expired200_response;
   expired200_response.SetHttpStatusCode(200);
-  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
-  expired200_response.SetHTTPHeaderField("Last-Modified",
+  expired200_response.SetHttpHeaderField("Date", kOriginalRequestDateAsString);
+  expired200_response.SetHttpHeaderField("Last-Modified",
                                          kOneDayBeforeOriginalRequest);
 
   MockResource* expired200 = ResourceFromResourceResponse(expired200_response);
@@ -209,8 +209,8 @@
 TEST_F(MemoryCacheCorrectnessTest, ExpiredFromExpires) {
   ResourceResponse expired200_response;
   expired200_response.SetHttpStatusCode(200);
-  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
-  expired200_response.SetHTTPHeaderField("Expires",
+  expired200_response.SetHttpHeaderField("Date", kOriginalRequestDateAsString);
+  expired200_response.SetHttpHeaderField("Expires",
                                          kOneDayAfterOriginalRequest);
 
   MockResource* expired200 = ResourceFromResourceResponse(expired200_response);
@@ -228,8 +228,8 @@
 TEST_F(MemoryCacheCorrectnessTest, NewMockResourceExpiredFromExpires) {
   ResourceResponse expired200_response;
   expired200_response.SetHttpStatusCode(200);
-  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
-  expired200_response.SetHTTPHeaderField("Expires",
+  expired200_response.SetHttpHeaderField("Date", kOriginalRequestDateAsString);
+  expired200_response.SetHttpHeaderField("Expires",
                                          kOneDayAfterOriginalRequest);
 
   MockResource* expired200 = ResourceFromResourceResponse(expired200_response);
@@ -248,8 +248,8 @@
 TEST_F(MemoryCacheCorrectnessTest, ReuseMockResourceExpiredFromExpires) {
   ResourceResponse expired200_response;
   expired200_response.SetHttpStatusCode(200);
-  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
-  expired200_response.SetHTTPHeaderField("Expires",
+  expired200_response.SetHttpHeaderField("Date", kOriginalRequestDateAsString);
+  expired200_response.SetHttpHeaderField("Expires",
                                          kOneDayAfterOriginalRequest);
 
   MockResource* expired200 = ResourceFromResourceResponse(expired200_response);
@@ -271,8 +271,8 @@
 TEST_F(MemoryCacheCorrectnessTest, ExpiredFromMaxAge) {
   ResourceResponse expired200_response;
   expired200_response.SetHttpStatusCode(200);
-  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
-  expired200_response.SetHTTPHeaderField("Cache-Control", "max-age=600");
+  expired200_response.SetHttpHeaderField("Date", kOriginalRequestDateAsString);
+  expired200_response.SetHttpHeaderField("Cache-Control", "max-age=600");
 
   MockResource* expired200 = ResourceFromResourceResponse(expired200_response);
 
@@ -287,11 +287,11 @@
 TEST_F(MemoryCacheCorrectnessTest, FreshButNoCache) {
   ResourceResponse fresh200_nocache_response;
   fresh200_nocache_response.SetHttpStatusCode(200);
-  fresh200_nocache_response.SetHTTPHeaderField(http_names::kDate,
+  fresh200_nocache_response.SetHttpHeaderField(http_names::kDate,
                                                kOriginalRequestDateAsString);
-  fresh200_nocache_response.SetHTTPHeaderField(http_names::kExpires,
+  fresh200_nocache_response.SetHttpHeaderField(http_names::kExpires,
                                                kOneDayAfterOriginalRequest);
-  fresh200_nocache_response.SetHTTPHeaderField(http_names::kCacheControl,
+  fresh200_nocache_response.SetHttpHeaderField(http_names::kCacheControl,
                                                "no-cache");
 
   MockResource* fresh200_nocache =
@@ -307,7 +307,7 @@
 
 TEST_F(MemoryCacheCorrectnessTest, RequestWithNoCache) {
   ResourceRequest no_cache_request;
-  no_cache_request.SetHTTPHeaderField(http_names::kCacheControl, "no-cache");
+  no_cache_request.SetHttpHeaderField(http_names::kCacheControl, "no-cache");
   no_cache_request.SetRequestorOrigin(GetSecurityOrigin());
   MockResource* no_cache_resource =
       ResourceFromResourceRequest(no_cache_request);
@@ -318,11 +318,11 @@
 TEST_F(MemoryCacheCorrectnessTest, FreshButNoStore) {
   ResourceResponse fresh200_nostore_response;
   fresh200_nostore_response.SetHttpStatusCode(200);
-  fresh200_nostore_response.SetHTTPHeaderField(http_names::kDate,
+  fresh200_nostore_response.SetHttpHeaderField(http_names::kDate,
                                                kOriginalRequestDateAsString);
-  fresh200_nostore_response.SetHTTPHeaderField(http_names::kExpires,
+  fresh200_nostore_response.SetHttpHeaderField(http_names::kExpires,
                                                kOneDayAfterOriginalRequest);
-  fresh200_nostore_response.SetHTTPHeaderField(http_names::kCacheControl,
+  fresh200_nostore_response.SetHttpHeaderField(http_names::kCacheControl,
                                                "no-store");
 
   MockResource* fresh200_nostore =
@@ -338,7 +338,7 @@
 
 TEST_F(MemoryCacheCorrectnessTest, RequestWithNoStore) {
   ResourceRequest no_store_request;
-  no_store_request.SetHTTPHeaderField(http_names::kCacheControl, "no-store");
+  no_store_request.SetHttpHeaderField(http_names::kCacheControl, "no-store");
   no_store_request.SetRequestorOrigin(GetSecurityOrigin());
   MockResource* no_store_resource =
       ResourceFromResourceRequest(no_store_request);
@@ -351,11 +351,11 @@
 TEST_F(MemoryCacheCorrectnessTest, DISABLED_FreshButMustRevalidate) {
   ResourceResponse fresh200_must_revalidate_response;
   fresh200_must_revalidate_response.SetHttpStatusCode(200);
-  fresh200_must_revalidate_response.SetHTTPHeaderField(
+  fresh200_must_revalidate_response.SetHttpHeaderField(
       http_names::kDate, kOriginalRequestDateAsString);
-  fresh200_must_revalidate_response.SetHTTPHeaderField(
+  fresh200_must_revalidate_response.SetHttpHeaderField(
       http_names::kExpires, kOneDayAfterOriginalRequest);
-  fresh200_must_revalidate_response.SetHTTPHeaderField(
+  fresh200_must_revalidate_response.SetHttpHeaderField(
       http_names::kCacheControl, "must-revalidate");
 
   MockResource* fresh200_must_revalidate =
@@ -380,11 +380,11 @@
 
   ResourceResponse fresh301_response(redirect_url);
   fresh301_response.SetHttpStatusCode(301);
-  fresh301_response.SetHTTPHeaderField(http_names::kDate,
+  fresh301_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  fresh301_response.SetHTTPHeaderField(http_names::kLocation,
+  fresh301_response.SetHttpHeaderField(http_names::kLocation,
                                        kRedirectTargetUrlString);
-  fresh301_response.SetHTTPHeaderField(http_names::kCacheControl,
+  fresh301_response.SetHttpHeaderField(http_names::kCacheControl,
                                        "max-age=600");
 
   // Add the redirect to our request.
@@ -395,9 +395,9 @@
   // Add the final response to our request.
   ResourceResponse fresh200_response(redirect_target_url);
   fresh200_response.SetHttpStatusCode(200);
-  fresh200_response.SetHTTPHeaderField(http_names::kDate,
+  fresh200_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
+  fresh200_response.SetHttpHeaderField(http_names::kExpires,
                                        kOneDayAfterOriginalRequest);
 
   first_resource->SetResponse(fresh200_response);
@@ -421,9 +421,9 @@
 
   ResourceResponse stale301_response(redirect_url);
   stale301_response.SetHttpStatusCode(301);
-  stale301_response.SetHTTPHeaderField(http_names::kDate,
+  stale301_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  stale301_response.SetHTTPHeaderField(http_names::kLocation,
+  stale301_response.SetHttpHeaderField(http_names::kLocation,
                                        kRedirectTargetUrlString);
 
   // Add the redirect to our request.
@@ -434,9 +434,9 @@
   // Add the final response to our request.
   ResourceResponse fresh200_response(redirect_target_url);
   fresh200_response.SetHttpStatusCode(200);
-  fresh200_response.SetHTTPHeaderField(http_names::kDate,
+  fresh200_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
+  fresh200_response.SetHttpHeaderField(http_names::kExpires,
                                        kOneDayAfterOriginalRequest);
 
   first_resource->SetResponse(fresh200_response);
@@ -476,11 +476,11 @@
 
   ResourceResponse fresh302_response(redirect_url);
   fresh302_response.SetHttpStatusCode(302);
-  fresh302_response.SetHTTPHeaderField(http_names::kDate,
+  fresh302_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  fresh302_response.SetHTTPHeaderField(http_names::kLastModified,
+  fresh302_response.SetHttpHeaderField(http_names::kLastModified,
                                        kOneDayBeforeOriginalRequest);
-  fresh302_response.SetHTTPHeaderField(http_names::kLocation,
+  fresh302_response.SetHttpHeaderField(http_names::kLocation,
                                        kRedirectTargetUrlString);
 
   // Add the redirect to our request.
@@ -491,9 +491,9 @@
   // Add the final response to our request.
   ResourceResponse fresh200_response(redirect_target_url);
   fresh200_response.SetHttpStatusCode(200);
-  fresh200_response.SetHTTPHeaderField(http_names::kDate,
+  fresh200_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
+  fresh200_response.SetHttpHeaderField(http_names::kExpires,
                                        kOneDayAfterOriginalRequest);
 
   first_resource->SetResponse(fresh200_response);
@@ -517,11 +517,11 @@
 
   ResourceResponse fresh302_response(redirect_url);
   fresh302_response.SetHttpStatusCode(302);
-  fresh302_response.SetHTTPHeaderField(http_names::kDate,
+  fresh302_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  fresh302_response.SetHTTPHeaderField(http_names::kCacheControl,
+  fresh302_response.SetHttpHeaderField(http_names::kCacheControl,
                                        "max-age=600");
-  fresh302_response.SetHTTPHeaderField(http_names::kLocation,
+  fresh302_response.SetHttpHeaderField(http_names::kLocation,
                                        kRedirectTargetUrlString);
 
   // Add the redirect to our request.
@@ -532,9 +532,9 @@
   // Add the final response to our request.
   ResourceResponse fresh200_response(redirect_target_url);
   fresh200_response.SetHttpStatusCode(200);
-  fresh200_response.SetHTTPHeaderField(http_names::kDate,
+  fresh200_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
+  fresh200_response.SetHttpHeaderField(http_names::kExpires,
                                        kOneDayAfterOriginalRequest);
 
   first_resource->SetResponse(fresh200_response);
@@ -558,11 +558,11 @@
 
   ResourceResponse fresh302_response(redirect_url);
   fresh302_response.SetHttpStatusCode(302);
-  fresh302_response.SetHTTPHeaderField(http_names::kDate,
+  fresh302_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  fresh302_response.SetHTTPHeaderField(http_names::kExpires,
+  fresh302_response.SetHttpHeaderField(http_names::kExpires,
                                        kOneDayAfterOriginalRequest);
-  fresh302_response.SetHTTPHeaderField(http_names::kLocation,
+  fresh302_response.SetHttpHeaderField(http_names::kLocation,
                                        kRedirectTargetUrlString);
 
   // Add the redirect to our request.
@@ -572,9 +572,9 @@
   // Add the final response to our request.
   ResourceResponse fresh200_response(redirect_target_url);
   fresh200_response.SetHttpStatusCode(200);
-  fresh200_response.SetHTTPHeaderField(http_names::kDate,
+  fresh200_response.SetHttpHeaderField(http_names::kDate,
                                        kOriginalRequestDateAsString);
-  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
+  fresh200_response.SetHttpHeaderField(http_names::kExpires,
                                        kOneDayAfterOriginalRequest);
 
   first_resource->SetResponse(fresh200_response);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.cc b/third_party/blink/renderer/platform/loader/fetch/resource.cc
index ba52e0e..ad6b958 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -961,7 +961,7 @@
     // care about.
     if (!ShouldUpdateHeaderAfterRevalidation(header.key))
       continue;
-    response_.SetHTTPHeaderField(header.key, header.value);
+    response_.SetHttpHeaderField(header.key, header.value);
   }
 
   is_revalidating_ = false;
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 046ce7e6..7482ba11 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -831,7 +831,7 @@
         DetermineRequestContext(resource_type, kImageNotImageSet));
   }
   if (resource_type == ResourceType::kLinkPrefetch)
-    resource_request.SetHTTPHeaderField(http_names::kPurpose, "prefetch");
+    resource_request.SetHttpHeaderField(http_names::kPurpose, "prefetch");
 
   bool resource_allows_stale_while_revalidate = false;
   bool host_matches_control =
@@ -1134,16 +1134,16 @@
               revalidating_request.GetCacheMode());
     if (revalidating_request.GetCacheMode() ==
         mojom::FetchCacheMode::kValidateCache) {
-      revalidating_request.SetHTTPHeaderField(http_names::kCacheControl,
+      revalidating_request.SetHttpHeaderField(http_names::kCacheControl,
                                               "max-age=0");
     }
   }
   if (!last_modified.IsEmpty()) {
-    revalidating_request.SetHTTPHeaderField(http_names::kIfModifiedSince,
+    revalidating_request.SetHttpHeaderField(http_names::kIfModifiedSince,
                                             last_modified);
   }
   if (!e_tag.IsEmpty())
-    revalidating_request.SetHTTPHeaderField(http_names::kIfNoneMatch, e_tag);
+    revalidating_request.SetHttpHeaderField(http_names::kIfNoneMatch, e_tag);
 
   resource->SetRevalidatingRequest(revalidating_request);
 }
@@ -1787,7 +1787,7 @@
       response.SetAlpnNegotiatedProtocol(
           WebString::FromUTF8(timing_info.alpn_negotiated_protocol));
       response.SetConnectionInfo(timing_info.connection_info);
-      response.SetHTTPHeaderField(
+      response.SetHttpHeaderField(
           http_names::kTimingAllowOrigin,
           WebString::FromUTF8(timing_info.timing_allow_origin));
       response.SetEncodedDataLength(timing_info.transfer_size);
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 9e6d89f5..7714be3 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
@@ -154,7 +154,7 @@
   KURL url("http://127.0.0.1:8000/foo.html");
   ResourceResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
+  response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
   RegisterMockedURLLoadWithCustomResponse(url, response);
 
   FetchParameters fetch_params{ResourceRequest(url)};
@@ -183,7 +183,7 @@
   AddResourceToMemoryCache(resource);
   ResourceResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
+  response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
   resource->ResponseReceived(response);
   resource->FinishForTest();
 
@@ -214,8 +214,8 @@
 
   ResourceResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
-  response.SetHTTPHeaderField(http_names::kVary, "*");
+  response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
+  response.SetHttpHeaderField(http_names::kVary, "*");
   resource->ResponseReceived(response);
   resource->FinishForTest();
   ASSERT_TRUE(resource->MustReloadDueToVaryHeader(ResourceRequest(url)));
@@ -256,8 +256,8 @@
 
   ResourceResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
-  response.SetHTTPHeaderField(http_names::kVary, "*");
+  response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
+  response.SetHttpHeaderField(http_names::kVary, "*");
   resource->ResponseReceived(response);
   resource->FinishForTest();
   ASSERT_TRUE(resource->MustReloadDueToVaryHeader(ResourceRequest(url)));
@@ -276,8 +276,8 @@
   KURL url("http://127.0.0.1:8000/foo.html");
   ResourceResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
-  response.SetHTTPHeaderField(http_names::kVary, "*");
+  response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
+  response.SetHttpHeaderField(http_names::kVary, "*");
   RegisterMockedURLLoadWithCustomResponse(url, response);
 
   FetchParameters fetch_params_original{ResourceRequest(url)};
@@ -343,14 +343,14 @@
 
   ResourceResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
-  response.SetHTTPHeaderField(http_names::kETag, "1234567890");
+  response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
+  response.SetHttpHeaderField(http_names::kETag, "1234567890");
   RegisterMockedURLLoadWithCustomResponse(url, response);
 
   ResourceFetcher* fetcher1 = CreateFetcher(
       *MakeGarbageCollected<TestResourceFetcherProperties>(source_origin));
   ResourceRequest request1(url);
-  request1.SetHTTPHeaderField(http_names::kCacheControl, "no-cache");
+  request1.SetHttpHeaderField(http_names::kCacheControl, "no-cache");
   FetchParameters fetch_params1(request1);
   Persistent<RequestSameResourceOnComplete> client =
       MakeGarbageCollected<RequestSameResourceOnComplete>(fetch_params1,
@@ -452,7 +452,7 @@
     WebURLResponse redirect_response;
     redirect_response.SetCurrentRequestUrl(redirect_url);
     redirect_response.SetHttpStatusCode(301);
-    redirect_response.SetHTTPHeaderField(http_names::kLocation, to_url);
+    redirect_response.SetHttpHeaderField(http_names::kLocation, to_url);
     redirect_response.SetEncodedDataLength(kRedirectResponseOverheadBytes);
     Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
         redirect_url, redirect_response, "");
@@ -775,7 +775,7 @@
 
   ResourceResponse response(url);
   response.SetHttpStatusCode(304);
-  response.SetHTTPHeaderField("etag", "1234567890");
+  response.SetHttpHeaderField("etag", "1234567890");
   resource->ResponseReceived(response);
   resource->FinishForTest();
 
@@ -869,7 +869,7 @@
 
   ResourceResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(http_names::kCacheControl,
+  response.SetHttpHeaderField(http_names::kCacheControl,
                               "max-age=0, stale-while-revalidate=40");
 
   RegisterMockedURLLoadWithCustomResponse(url, response);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
index 1a5a09b..fa8a630 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
@@ -192,7 +192,7 @@
     response.SetType(test.original_response_type);
     response.SetWasFetchedViaServiceWorker(test.from == From::kServiceWorker);
     if (test.allowed_origin) {
-      response.SetHTTPHeaderField("access-control-allow-origin",
+      response.SetHttpHeaderField("access-control-allow-origin",
                                   test.allowed_origin->ToAtomicString());
     }
     response.SetType(test.original_response_type);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
index f10939d..af516008 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -212,7 +212,7 @@
   return http_header_fields_.Get(name);
 }
 
-void ResourceRequest::SetHTTPHeaderField(const AtomicString& name,
+void ResourceRequest::SetHttpHeaderField(const AtomicString& name,
                                          const AtomicString& value) {
   http_header_fields_.Set(name, value);
 }
@@ -221,7 +221,7 @@
   if (referrer.referrer.IsEmpty())
     http_header_fields_.Remove(http_names::kReferer);
   else
-    SetHTTPHeaderField(http_names::kReferer, referrer.referrer);
+    SetHttpHeaderField(http_names::kReferer, referrer.referrer);
   referrer_policy_ = referrer.referrer_policy;
   did_set_http_referrer_ = true;
 }
@@ -233,7 +233,7 @@
 }
 
 void ResourceRequest::SetHTTPOrigin(const SecurityOrigin* origin) {
-  SetHTTPHeaderField(http_names::kOrigin, origin->ToAtomicString());
+  SetHttpHeaderField(http_names::kOrigin, origin->ToAtomicString());
 }
 
 void ResourceRequest::ClearHTTPOrigin() {
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
index 6834b30..4eecef2 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -134,7 +134,7 @@
 
   const HTTPHeaderMap& HttpHeaderFields() const;
   const AtomicString& HttpHeaderField(const AtomicString& name) const;
-  void SetHTTPHeaderField(const AtomicString& name, const AtomicString& value);
+  void SetHttpHeaderField(const AtomicString& name, const AtomicString& value);
   void AddHTTPHeaderField(const AtomicString& name, const AtomicString& value);
   void AddHTTPHeaderFields(const HTTPHeaderMap& header_fields);
   void ClearHttpHeaderField(const AtomicString& name);
@@ -143,7 +143,7 @@
     return HttpHeaderField(http_names::kContentType);
   }
   void SetHTTPContentType(const AtomicString& http_content_type) {
-    SetHTTPHeaderField(http_names::kContentType, http_content_type);
+    SetHttpHeaderField(http_names::kContentType, http_content_type);
   }
 
   // TODO(domfarolino): Remove this once we stop storing the generated referrer
@@ -177,12 +177,12 @@
   void SetHTTPOriginToMatchReferrerIfNeeded();
 
   void SetHTTPUserAgent(const AtomicString& http_user_agent) {
-    SetHTTPHeaderField(http_names::kUserAgent, http_user_agent);
+    SetHttpHeaderField(http_names::kUserAgent, http_user_agent);
   }
   void ClearHTTPUserAgent();
 
   void SetHTTPAccept(const AtomicString& http_accept) {
-    SetHTTPHeaderField(http_names::kAccept, http_accept);
+    SetHttpHeaderField(http_names::kAccept, http_accept);
   }
 
   EncodedFormData* HttpBody() const;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.cc b/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
index e7f0f96..6852f306 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
@@ -237,7 +237,7 @@
   security_details_.sct_list = sct_list;
 }
 
-void ResourceResponse::SetHTTPHeaderField(const AtomicString& name,
+void ResourceResponse::SetHttpHeaderField(const AtomicString& name,
                                           const AtomicString& value) {
   UpdateHeaderParsedState(name);
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.h b/third_party/blink/renderer/platform/loader/fetch/resource_response.h
index 29691fe..09defd4 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_response.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.h
@@ -205,7 +205,7 @@
   void SetHttpStatusText(const AtomicString&);
 
   const AtomicString& HttpHeaderField(const AtomicString& name) const;
-  void SetHTTPHeaderField(const AtomicString& name, const AtomicString& value);
+  void SetHttpHeaderField(const AtomicString& name, const AtomicString& value);
   void AddHTTPHeaderField(const AtomicString& name, const AtomicString& value);
   void ClearHttpHeaderField(const AtomicString& name);
   const HTTPHeaderMap& HttpHeaderFields() const;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_test.cc
index 9a220d1..4265029 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_test.cc
@@ -173,46 +173,46 @@
   ResourceRequest new_request(url);
   EXPECT_FALSE(resource->MustReloadDueToVaryHeader(new_request));
 
-  response.SetHTTPHeaderField(http_names::kVary, "*");
+  response.SetHttpHeaderField(http_names::kVary, "*");
   resource->SetResponse(response);
   EXPECT_TRUE(resource->MustReloadDueToVaryHeader(new_request));
 
   // Irrelevant header
-  response.SetHTTPHeaderField(http_names::kVary, "definitelynotarealheader");
+  response.SetHttpHeaderField(http_names::kVary, "definitelynotarealheader");
   resource->SetResponse(response);
   EXPECT_FALSE(resource->MustReloadDueToVaryHeader(new_request));
 
   // Header present on new but not old
-  new_request.SetHTTPHeaderField(http_names::kUserAgent, "something");
-  response.SetHTTPHeaderField(http_names::kVary, http_names::kUserAgent);
+  new_request.SetHttpHeaderField(http_names::kUserAgent, "something");
+  response.SetHttpHeaderField(http_names::kVary, http_names::kUserAgent);
   resource->SetResponse(response);
   EXPECT_TRUE(resource->MustReloadDueToVaryHeader(new_request));
   new_request.ClearHttpHeaderField(http_names::kUserAgent);
 
   ResourceRequest old_request(url);
-  old_request.SetHTTPHeaderField(http_names::kUserAgent, "something");
-  old_request.SetHTTPHeaderField(http_names::kReferer, "http://foo.com");
+  old_request.SetHttpHeaderField(http_names::kUserAgent, "something");
+  old_request.SetHttpHeaderField(http_names::kReferer, "http://foo.com");
   resource = MockResource::Create(old_request);
   resource->ResponseReceived(response);
   resource->FinishForTest();
 
   // Header present on old but not new
   new_request.ClearHttpHeaderField(http_names::kUserAgent);
-  response.SetHTTPHeaderField(http_names::kVary, http_names::kUserAgent);
+  response.SetHttpHeaderField(http_names::kVary, http_names::kUserAgent);
   resource->SetResponse(response);
   EXPECT_TRUE(resource->MustReloadDueToVaryHeader(new_request));
 
   // Header present on both
-  new_request.SetHTTPHeaderField(http_names::kUserAgent, "something");
+  new_request.SetHttpHeaderField(http_names::kUserAgent, "something");
   EXPECT_FALSE(resource->MustReloadDueToVaryHeader(new_request));
 
   // One matching, one mismatching
-  response.SetHTTPHeaderField(http_names::kVary, "User-Agent, Referer");
+  response.SetHttpHeaderField(http_names::kVary, "User-Agent, Referer");
   resource->SetResponse(response);
   EXPECT_TRUE(resource->MustReloadDueToVaryHeader(new_request));
 
   // Two matching
-  new_request.SetHTTPHeaderField(http_names::kReferer, "http://foo.com");
+  new_request.SetHttpHeaderField(http_names::kReferer, "http://foo.com");
   EXPECT_FALSE(resource->MustReloadDueToVaryHeader(new_request));
 }
 
@@ -449,7 +449,7 @@
 
   // The revalidating request is redirected.
   ResourceResponse redirect_response(url);
-  redirect_response.SetHTTPHeaderField(
+  redirect_response.SetHttpHeaderField(
       "location", AtomicString(redirect_target_url.GetString()));
   redirect_response.SetHttpStatusCode(308);
   ResourceRequest redirected_revalidating_request(redirect_target_url);
@@ -505,7 +505,7 @@
   const KURL url("http://127.0.0.1:8000/foo.html");
   ResourceResponse response(url);
   response.SetHttpStatusCode(200);
-  response.SetHTTPHeaderField(http_names::kCacheControl,
+  response.SetHttpHeaderField(http_names::kCacheControl,
                               "max-age=0, stale-while-revalidate=40");
 
   MockResource* resource = MockResource::Create(url);
@@ -532,15 +532,15 @@
   const KURL url("http://127.0.0.1:8000/foo.html");
   const KURL redirect_target_url("http://127.0.0.1:8000/food.html");
   ResourceResponse response(url);
-  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=50");
+  response.SetHttpHeaderField(http_names::kCacheControl, "max-age=50");
   response.SetHttpStatusCode(200);
 
   // The revalidating request is redirected.
   ResourceResponse redirect_response(url);
-  redirect_response.SetHTTPHeaderField(
+  redirect_response.SetHttpHeaderField(
       "location", AtomicString(redirect_target_url.GetString()));
   redirect_response.SetHttpStatusCode(302);
-  redirect_response.SetHTTPHeaderField(http_names::kCacheControl,
+  redirect_response.SetHttpHeaderField(http_names::kCacheControl,
                                        "max-age=0, stale-while-revalidate=40");
   redirect_response.SetAsyncRevalidationRequested(true);
   ResourceRequest redirected_revalidating_request(redirect_target_url);
diff --git a/third_party/blink/renderer/platform/loader/testing/crypto_testing_platform_support.h b/third_party/blink/renderer/platform/loader/testing/crypto_testing_platform_support.h
index 19ba9b6..14e3865 100644
--- a/third_party/blink/renderer/platform/loader/testing/crypto_testing_platform_support.h
+++ b/third_party/blink/renderer/platform/loader/testing/crypto_testing_platform_support.h
@@ -27,7 +27,7 @@
     explicit SetMockCryptoScope(CryptoTestingPlatformSupport& platform)
         : platform_(platform) {
       DCHECK(!platform_.Crypto());
-      platform_.SetMockCrypto(MockWebCrypto::Create());
+      platform_.SetMockCrypto(std::make_unique<MockWebCrypto>());
     }
     ~SetMockCryptoScope() { platform_.SetMockCrypto(nullptr); }
     MockWebCrypto& MockCrypto() { return *platform_.mock_web_crypto_; }
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_center.cc b/third_party/blink/renderer/platform/mediastream/media_stream_center.cc
index 354c2af..b357fe4a 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_center.cc
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_center.cc
@@ -100,7 +100,7 @@
     MediaStreamComponent* track) {
   DCHECK(track);
   if (private_) {
-    return MediaStreamWebAudioSource::Create(base::WrapUnique(
+    return std::make_unique<MediaStreamWebAudioSource>(base::WrapUnique(
         private_->CreateWebAudioSourceFromMediaStreamTrack(track)));
   }
 
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h b/third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h
index 3dea3f5..612d380 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h
@@ -45,16 +45,10 @@
 
 class MediaStreamWebAudioSource : public AudioSourceProvider {
  public:
-  static std::unique_ptr<MediaStreamWebAudioSource> Create(
-      std::unique_ptr<WebAudioSourceProvider> provider) {
-    return base::WrapUnique(new MediaStreamWebAudioSource(std::move(provider)));
-  }
-
+  explicit MediaStreamWebAudioSource(std::unique_ptr<WebAudioSourceProvider>);
   ~MediaStreamWebAudioSource() override;
 
  private:
-  explicit MediaStreamWebAudioSource(std::unique_ptr<WebAudioSourceProvider>);
-
   // blink::AudioSourceProvider implementation.
   void ProvideInput(AudioBus*, uint32_t frames_to_process) override;
 
diff --git a/third_party/blink/renderer/platform/testing/mock_web_crypto.h b/third_party/blink/renderer/platform/testing/mock_web_crypto.h
index 12c71c4..11f839df 100644
--- a/third_party/blink/renderer/platform/testing/mock_web_crypto.h
+++ b/third_party/blink/renderer/platform/testing/mock_web_crypto.h
@@ -16,13 +16,9 @@
 
 class MockWebCrypto : public WebCrypto {
  public:
+  MockWebCrypto() = default;
   ~MockWebCrypto() override = default;
 
-  static std::unique_ptr<MockWebCrypto> Create() {
-    return std::unique_ptr<MockWebCrypto>(
-        new testing::StrictMock<MockWebCrypto>());
-  }
-
   MOCK_METHOD5(Encrypt,
                void(const WebCryptoAlgorithm&,
                     const WebCryptoKey&,
@@ -117,8 +113,6 @@
                bool(const WebCryptoKey&, WebVector<unsigned char>&));
 
  protected:
-  MockWebCrypto() = default;
-
   std::unique_ptr<WebCryptoDigestor> CreateDigestor(
       WebCryptoAlgorithmId id) override {
     return std::unique_ptr<WebCryptoDigestor>(CreateDigestorProxy(id));
diff --git a/third_party/blink/renderer/platform/testing/url_test_helpers.cc b/third_party/blink/renderer/platform/testing/url_test_helpers.cc
index ba515d2e..a4e4ae8 100644
--- a/third_party/blink/renderer/platform/testing/url_test_helpers.cc
+++ b/third_party/blink/renderer/platform/testing/url_test_helpers.cc
@@ -70,7 +70,7 @@
 
   WebURLResponse response(full_url);
   response.SetMimeType(mime_type);
-  response.SetHTTPHeaderField(http_names::kContentType, mime_type);
+  response.SetHttpHeaderField(http_names::kContentType, mime_type);
   response.SetHttpStatusCode(200);
   response.SetLoadTiming(timing);
 
@@ -83,7 +83,7 @@
 
   WebURLResponse response;
   response.SetMimeType("image/png");
-  response.SetHTTPHeaderField(http_names::kContentType, "image/png");
+  response.SetHttpHeaderField(http_names::kContentType, "image/png");
   response.SetHttpStatusCode(404);
   response.SetLoadTiming(timing);
 
diff --git a/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc b/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc
index df41af0..67e2bfb 100644
--- a/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc
+++ b/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc
@@ -61,4 +61,8 @@
   return private_.host_is_ip_address();
 }
 
+String OriginAccessEntry::registrable_domain() const {
+  return String(private_.registrable_domain().c_str());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/weborigin/origin_access_entry.h b/third_party/blink/renderer/platform/weborigin/origin_access_entry.h
index 53e504d9..1624ee5 100644
--- a/third_party/blink/renderer/platform/weborigin/origin_access_entry.h
+++ b/third_party/blink/renderer/platform/weborigin/origin_access_entry.h
@@ -68,6 +68,8 @@
 
   bool HostIsIPAddress() const;
 
+  String registrable_domain() const;
+
  private:
   network::cors::OriginAccessEntry private_;
 
diff --git a/third_party/blink/renderer/platform/weborigin/reporting_service_proxy_ptr_holder.h b/third_party/blink/renderer/platform/weborigin/reporting_service_proxy_ptr_holder.h
index 5dfa8c8b..7bff0b2 100644
--- a/third_party/blink/renderer/platform/weborigin/reporting_service_proxy_ptr_holder.h
+++ b/third_party/blink/renderer/platform/weborigin/reporting_service_proxy_ptr_holder.h
@@ -23,32 +23,6 @@
   }
   ~ReportingServiceProxyPtrHolder() = default;
 
-  void QueueInterventionReport(const KURL& url,
-                               const String& message,
-                               const String& source_file,
-                               int line_number,
-                               int column_number) {
-    if (reporting_service_proxy) {
-      reporting_service_proxy->QueueInterventionReport(
-          url, message ? message : "", source_file ? source_file : "",
-          line_number, column_number);
-    }
-  }
-
-  void QueueDeprecationReport(const KURL& url,
-                              const String& id,
-                              WTF::Time anticipatedRemoval,
-                              const String& message,
-                              const String& source_file,
-                              int line_number,
-                              int column_number) {
-    if (reporting_service_proxy) {
-      reporting_service_proxy->QueueDeprecationReport(
-          url, id, anticipatedRemoval, message ? message : "",
-          source_file ? source_file : "", line_number, column_number);
-    }
-  }
-
   void QueueCspViolationReport(
       const KURL& url,
       const String& group,
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.cc b/third_party/blink/renderer/platform/weborigin/security_origin.cc
index afd8cd2..7add0f7 100644
--- a/third_party/blink/renderer/platform/weborigin/security_origin.cc
+++ b/third_party/blink/renderer/platform/weborigin/security_origin.cc
@@ -38,11 +38,11 @@
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/weborigin/known_ports.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h"
 #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
 #include "third_party/blink/renderer/platform/weborigin/security_policy.h"
 #include "third_party/blink/renderer/platform/weborigin/url_security_origin_map.h"
 #include "third_party/blink/renderer/platform/wtf/hex_number.h"
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -267,6 +267,17 @@
   domain_ = new_domain;
 }
 
+String SecurityOrigin::RegistrableDomain() const {
+  if (IsOpaque())
+    return String();
+
+  OriginAccessEntry entry(
+      Protocol(), Host(),
+      network::mojom::CorsOriginAccessMatchMode::kAllowRegistrableDomains);
+  String domain = entry.registrable_domain();
+  return domain.IsEmpty() ? String() : domain;
+}
+
 bool SecurityOrigin::IsSecure(const KURL& url) {
   if (SchemeRegistry::ShouldTreatURLSchemeAsSecure(url.Protocol()))
     return true;
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.h b/third_party/blink/renderer/platform/weborigin/security_origin.h
index f09c3e1..bb5d058 100644
--- a/third_party/blink/renderer/platform/weborigin/security_origin.h
+++ b/third_party/blink/renderer/platform/weborigin/security_origin.h
@@ -123,6 +123,11 @@
   String Host() const { return host_; }
   String Domain() const { return domain_; }
 
+  // Returns the registrable domain if available.
+  // For non-tuple origin, IP address URL, and public suffixes, this returns a
+  // null string. https://url.spec.whatwg.org/#host-registrable-domain
+  String RegistrableDomain() const;
+
   // Returns 0 if the effective port of this origin is the default for its
   // scheme.
   uint16_t Port() const { return port_; }
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
index d3b26d3..ec75ad8 100644
--- a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
+++ b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
@@ -832,4 +832,25 @@
   EXPECT_TRUE(local->IsSameSchemeHostPort(local.get()));
 }
 
+TEST_F(SecurityOriginTest, RegistrableDomain) {
+  scoped_refptr<SecurityOrigin> opaque = SecurityOrigin::CreateUniqueOpaque();
+  EXPECT_TRUE(opaque->RegistrableDomain().IsNull());
+
+  scoped_refptr<SecurityOrigin> ip_address =
+      SecurityOrigin::CreateFromString("http://0.0.0.0");
+  EXPECT_TRUE(ip_address->RegistrableDomain().IsNull());
+
+  scoped_refptr<SecurityOrigin> public_suffix =
+      SecurityOrigin::CreateFromString("http://com");
+  EXPECT_TRUE(public_suffix->RegistrableDomain().IsNull());
+
+  scoped_refptr<SecurityOrigin> registrable =
+      SecurityOrigin::CreateFromString("http://example.com");
+  EXPECT_EQ(String("example.com"), registrable->RegistrableDomain());
+
+  scoped_refptr<SecurityOrigin> subdomain =
+      SecurityOrigin::CreateFromString("http://foo.example.com");
+  EXPECT_EQ(String("example.com"), subdomain->RegistrableDomain());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/wtf/BUILD.gn b/third_party/blink/renderer/platform/wtf/BUILD.gn
index bbc7f1d..2c0a35d 100644
--- a/third_party/blink/renderer/platform/wtf/BUILD.gn
+++ b/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -99,7 +99,6 @@
     "list_hash_set.h",
     "locker.h",
     "math_extras.h",
-    "not_found.h",
     "pod_arena.h",
     "pod_free_list_arena.h",
     "pod_interval.h",
@@ -225,6 +224,7 @@
     "wtf.cc",
     "wtf.h",
     "wtf_export.h",
+    "wtf_size_t.h",
     "wtf_thread_data.cc",
     "wtf_thread_data.h",
   ]
diff --git a/third_party/blink/renderer/platform/wtf/not_found.h b/third_party/blink/renderer/platform/wtf/not_found.h
deleted file mode 100644
index 8a8926cc..0000000
--- a/third_party/blink/renderer/platform/wtf/not_found.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2008 Apple 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 INC. ``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 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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_NOT_FOUND_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_NOT_FOUND_H_
-
-#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
-
-namespace WTF {
-const wtf_size_t kNotFound = UINT_MAX;
-}
-
-using WTF::kNotFound;
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_NOT_FOUND_H_
diff --git a/third_party/blink/renderer/platform/wtf/pod_arena_test_helpers.h b/third_party/blink/renderer/platform/wtf/pod_arena_test_helpers.h
index abe5a09..4cbff6c 100644
--- a/third_party/blink/renderer/platform/wtf/pod_arena_test_helpers.h
+++ b/third_party/blink/renderer/platform/wtf/pod_arena_test_helpers.h
@@ -26,9 +26,9 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_POD_ARENA_TEST_HELPERS_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_POD_ARENA_TEST_HELPERS_H_
 
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
 #include "third_party/blink/renderer/platform/wtf/pod_arena.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
 
 #include <gtest/gtest.h>
 
diff --git a/third_party/blink/renderer/platform/wtf/vector.h b/third_party/blink/renderer/platform/wtf/vector.h
index 71d0196..1f920fd 100644
--- a/third_party/blink/renderer/platform/wtf/vector.h
+++ b/third_party/blink/renderer/platform/wtf/vector.h
@@ -35,7 +35,6 @@
 #include "third_party/blink/renderer/platform/wtf/container_annotations.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"  // For default Vector template parameters.
 #include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h"
-#include "third_party/blink/renderer/platform/wtf/not_found.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/vector_traits.h"
 #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
diff --git a/third_party/blink/renderer/platform/wtf/wtf_size_t.h b/third_party/blink/renderer/platform/wtf/wtf_size_t.h
index fb28364..a6f552c3 100644
--- a/third_party/blink/renderer/platform/wtf/wtf_size_t.h
+++ b/third_party/blink/renderer/platform/wtf/wtf_size_t.h
@@ -5,9 +5,11 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_WTF_SIZE_T_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_WTF_SIZE_T_H_
 
+#include <limits.h>
 #include <stdint.h>
 
 namespace WTF {
+
 // TLDR: size_t != wtf_size_t
 //
 // WTF defines wtf_size_t as an unsigned 32 bit integer. This is to align
@@ -29,8 +31,11 @@
 // based and this definition may not be necessary, so long as the internal
 // type matches the external type.
 using wtf_size_t = uint32_t;
+const wtf_size_t kNotFound = UINT_MAX;
+
 }  // namespace WTF
 
+using WTF::kNotFound;
 using WTF::wtf_size_t;
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_WTF_SIZE_T_H_
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 86349de..43d852f 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3025,6 +3025,17 @@
 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 [ Win10 ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow.html [ Timeout ]
+crbug.com/626703 external/wpt/css/css-backgrounds/background-clip/clip-text-dynamic-2.html [ Failure ]
+crbug.com/626703 [ Mac10.10 ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html [ Timeout ]
+crbug.com/626703 [ Mac10.12 ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html [ Timeout ]
+crbug.com/626703 [ Mac10.11 ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html [ Timeout ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html [ Timeout ]
+crbug.com/626703 [ Retina ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html [ Timeout ]
+crbug.com/626703 [ Win7 ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html [ Timeout ]
+crbug.com/626703 [ Mac10.10 ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow.html [ Timeout ]
+crbug.com/626703 [ Mac10.11 ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow.html [ Timeout ]
+crbug.com/626703 [ Retina ] external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow.html [ Timeout ]
 crbug.com/626703 external/wpt/media-source/mediasource-correct-frames-after-reappend.html [ Timeout ]
 crbug.com/626703 external/wpt/media-source/mediasource-correct-frames.html [ Timeout ]
 crbug.com/626703 external/wpt/payment-method-basic-card/steps_for_selecting_the_payment_handler.html [ Timeout ]
@@ -4168,13 +4179,13 @@
 crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht [ Failure ]
 crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht [ Failure ]
 
-crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.html [ Timeout ]
-crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.serviceworker.html [ Timeout ]
-crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.worker.html [ Timeout ]
-crbug.com/943487 external/wpt/wasm/webapi/origin.sub.any.serviceworker.html [ Timeout ]
-crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.sharedworker.html [ Timeout ]
-crbug.com/943487 external/wpt/wasm/webapi/abort.any.worker.html [ Timeout ]
-crbug.com/943487 external/wpt/wasm/webapi/abort.any.html [ Timeout ]
+crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.html [ Timeout Pass ]
+crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.serviceworker.html [ Timeout Pass ]
+crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.worker.html [ Timeout Pass ]
+crbug.com/943487 external/wpt/wasm/webapi/origin.sub.any.serviceworker.html [ Timeout Pass ]
+crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.sharedworker.html [ Timeout Pass ]
+crbug.com/943487 external/wpt/wasm/webapi/abort.any.worker.html [ Timeout Pass ]
+crbug.com/943487 external/wpt/wasm/webapi/abort.any.html [ Timeout Pass ]
 
 crbug.com/792435 external/wpt/css/css-multicol/multicol-rule-004.xht [ Failure ]
 crbug.com/792437 external/wpt/css/css-multicol/multicol-rule-inset-000.xht [ Failure ]
@@ -5817,6 +5828,8 @@
 # WebRTC codec tests - software H.264 not present on webkit bot family
 crbug.com/840659 external/wpt/webrtc/protocol/video-codecs.https.html [ Pass Failure ]
 crbug.com/840659 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/video-codecs.https.html [ Pass Failure ]
+# WebRTC IceTransport flaky test
+crbug.com/944105 external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html [ Pass Failure ]
 
 # Sheriff 2019-01-11
 crbug.com/921038 virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/legacy-performance-memory-counters-enabled.html [ Skip ]
diff --git a/third_party/blink/web_tests/accessibility/image-inside-link.html b/third_party/blink/web_tests/accessibility/image-inside-link.html
index 5d2e34a0..b778902 100644
--- a/third_party/blink/web_tests/accessibility/image-inside-link.html
+++ b/third_party/blink/web_tests/accessibility/image-inside-link.html
@@ -12,10 +12,8 @@
 {
     var axImg = accessibilityController.accessibleElementById("img1");
     axImg.addNotificationListener(function(notification) {
-        if (notification == 'Clicked') {
-            document.getElementById("wrapper1").style.display = "none";
+        if (notification == 'Clicked')
             t.done();
-        }
     });
 
     var img = document.getElementById("img1");
@@ -47,10 +45,8 @@
             domEvent = true;
         }
 
-        if (axEvent && domEvent) {
-            document.getElementById("wrapper2").style.display = "none";
+        if (axEvent && domEvent)
             t.done();
-        }
     };
 
     var axImg = accessibilityController.accessibleElementById("img2");
@@ -60,4 +56,3 @@
     axImg.press();
 }, "clicking an image via accessibility sends both an accessible and a DOM click event");
 </script>
-
diff --git a/third_party/blink/web_tests/accessibility/multiselect-list-reports-active-option.html b/third_party/blink/web_tests/accessibility/multiselect-list-reports-active-option.html
index 61e516d0..df0967f 100644
--- a/third_party/blink/web_tests/accessibility/multiselect-list-reports-active-option.html
+++ b/third_party/blink/web_tests/accessibility/multiselect-list-reports-active-option.html
@@ -7,6 +7,7 @@
 async_test_after_layout_and_paint((testCase) => {
     const expectedNotifications = [
         'ActiveDescendantChanged',
+        'Focus',
         'SelectedChildrenChanged',
         'SelectedChildrenChanged',
         'ActiveDescendantChanged',
diff --git a/third_party/blink/web_tests/accessibility/notification-listeners.html b/third_party/blink/web_tests/accessibility/notification-listeners.html
index c0c9b08d..390f61a 100644
--- a/third_party/blink/web_tests/accessibility/notification-listeners.html
+++ b/third_party/blink/web_tests/accessibility/notification-listeners.html
@@ -15,7 +15,16 @@
     window.select = accessibilityController.accessibleElementById("select");
     window.slider = accessibilityController.accessibleElementById("slider");
     let expected_notifications = [
+        [select, "Focus"],
+        ["global", "Focus", "AXRole: AXPopUpButton"],
         [select, "Blur"],
+        ["global", "Blur", "AXRole: AXPopUpButton"],
+        [slider, "Focus"],
+        ["global", "Focus", "AXRole: AXSlider"],
+        [select, "TextChanged"],
+        ["global", "TextChanged", "AXRole: AXPopUpButton"],
+        [select, "TextChanged"],
+        ["global", "TextChanged", "AXRole: AXPopUpButton"],
         [select, "InvalidStatusChanged"],
         ["global", "InvalidStatusChanged", "AXRole: AXPopUpButton"],
         [slider, "ValueChanged"],
@@ -51,9 +60,9 @@
             assert_equals(element.role, expected_notification[2]);
         }
         if (expected_notifications.length === 0) {
-            assert_equals(selectNotificationCount, 2);
-            assert_equals(sliderNotificationCount, 1);
-            assert_equals(globalNotificationCount, 2);
+            assert_equals(selectNotificationCount, 5);
+            assert_equals(sliderNotificationCount, 2);
+            assert_equals(globalNotificationCount, 7);
             accessibilityController.removeNotificationListener();
             select.removeNotificationListener();
             slider.removeNotificationListener();
diff --git a/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification-expected.txt b/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification-expected.txt
deleted file mode 100644
index 3e9953a..0000000
--- a/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-One Two Three
-
-This test ensures that scrolling the window sends a notification.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-Got notification on container div
-PASS container.scrollLeft is 500
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification.html b/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification.html
index a8added..144b5b2f 100644
--- a/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification.html
+++ b/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification.html
@@ -1,7 +1,9 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-<script src="../resources/js-test.js"></script>
+  <script src="../resources/testharness.js"></script>
+  <script src="../resources/testharnessreport.js"></script>
+  <script src="../resources/run-after-layout-and-paint.js"></script>
 <style>
 .container {
   padding: 100px;
@@ -30,30 +32,24 @@
     </div>
 </div>
 
-<div id="console"></div>
 <script>
 
-description("This test ensures that scrolling the window sends a notification.");
-window.jsTestIsAsync = true;
-
-if (window.testRunner && window.accessibilityController) {
-    testRunner.dumpAsText();
-
+async_test_after_layout_and_paint((t) => {
     var container = document.getElementById('container');
 
     accessibilityController.addNotificationListener(function (target, notification) {
         if (target.role == 'AXRole: AXGenericContainer') {
-            debug('Got notification on container div');
-            shouldBe("container.scrollLeft", "500");
-            accessibilityController.removeNotificationListener();
-            finishJSTest();
+            console.log('Got notification on container div');
+            assert_equals(container.scrollLeft, 500);
+            t.done();
         }
     });
 
     window.setTimeout(function() {
         container.scrollLeft = 500;
     }, 0);
-}
+}, "This test ensures that scrolling the window sends a notification.");
+
 
 </script>
 
diff --git a/third_party/blink/web_tests/accessibility/scroll-div-sends-notification-expected.txt b/third_party/blink/web_tests/accessibility/scroll-div-sends-notification-expected.txt
deleted file mode 100644
index e7a0c6e..0000000
--- a/third_party/blink/web_tests/accessibility/scroll-div-sends-notification-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-One
-Two
-Three
-
-This test ensures that scrolling the window sends a notification.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-Got notification on container div
-PASS container.scrollTop is 500
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/accessibility/scroll-div-sends-notification.html b/third_party/blink/web_tests/accessibility/scroll-div-sends-notification.html
index 37dee5a..30ed8c2 100644
--- a/third_party/blink/web_tests/accessibility/scroll-div-sends-notification.html
+++ b/third_party/blink/web_tests/accessibility/scroll-div-sends-notification.html
@@ -1,7 +1,9 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-<script src="../resources/js-test.js"></script>
+  <script src="../resources/testharness.js"></script>
+  <script src="../resources/testharnessreport.js"></script>
+  <script src="../resources/run-after-layout-and-paint.js"></script>
 <style>
 .container {
   padding: 100px;
@@ -25,30 +27,24 @@
     <button class="bigbutton">Three</button>
 </div>
 
-<div id="console"></div>
 <script>
 
-description("This test ensures that scrolling the window sends a notification.");
-window.jsTestIsAsync = true;
-
-if (window.testRunner && window.accessibilityController) {
-    testRunner.dumpAsText();
-
+async_test_after_layout_and_paint((t) => {
     var container = document.getElementById('container');
 
     accessibilityController.addNotificationListener(function (target, notification) {
         if (target.role == 'AXRole: AXGenericContainer') {
-            debug('Got notification on container div');
-            shouldBe("container.scrollTop", "500");
-            accessibilityController.removeNotificationListener();
-            finishJSTest();
+            console.log('Got notification on container div');
+            assert_equals(container.scrollTop, 500);
+            t.done();
         }
     });
 
     window.setTimeout(function() {
         container.scrollTop = 500;
     }, 0);
-}
+}, "This test ensures that scrolling the window sends a notification.");
+
 
 </script>
 
diff --git a/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification-expected.txt b/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification-expected.txt
deleted file mode 100644
index 0b84dc1e..0000000
--- a/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-One
-Two
-Three
-
-This test ensures that scrolling the window sends a notification.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS window.pageXOffset is 0
-Got notification on web area
-PASS window.pageXOffset is 500
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification.html b/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification.html
index 4b1e5c7a..6fd610d9 100644
--- a/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification.html
+++ b/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification.html
@@ -1,7 +1,9 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-<script src="../resources/js-test.js"></script>
+  <script src="../resources/testharness.js"></script>
+  <script src="../resources/testharnessreport.js"></script>
+  <script src="../resources/run-after-layout-and-paint.js"></script>
 <style>
 .bigbutton {
     display:block;
@@ -16,31 +18,25 @@
 <button class="bigbutton">Two</button>
 <button class="bigbutton">Three</button>
 
-<div id="console"></div>
 <script>
 
-description("This test ensures that scrolling the window sends a notification.");
-window.jsTestIsAsync = true;
-
-if (window.testRunner && window.accessibilityController) {
-    testRunner.dumpAsText();
+async_test_after_layout_and_paint((t) => {
 
     window.scrollTo(0, 0);
-    shouldBe("window.pageXOffset", "0");
+    assert_equals(window.pageXOffset, 0);
 
     accessibilityController.addNotificationListener(function (target, notification) {
         if (target.role == 'AXRole: AXWebArea' && notification == 'ScrollPositionChanged') {
-            debug('Got notification on web area');
-            accessibilityController.removeNotificationListener();
-            shouldBe("window.pageXOffset", "500");
-            finishJSTest();
+            console.log('Got notification on web area');
+            assert_equals(window.pageXOffset, 500);
+            t.done()();
         }
     });
 
     window.setTimeout(function() {
         window.scrollTo(500, 0);
     }, 0);
-}
+}, "This test ensures that scrolling the window sends a notification.");
 
 </script>
 
diff --git a/third_party/blink/web_tests/accessibility/scroll-window-sends-notification-expected.txt b/third_party/blink/web_tests/accessibility/scroll-window-sends-notification-expected.txt
deleted file mode 100644
index 2ab16ef..0000000
--- a/third_party/blink/web_tests/accessibility/scroll-window-sends-notification-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-One
-Two
-Three
-
-This test ensures that scrolling the window sends a notification.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS window.pageYOffset is 0
-Got notification on web area
-PASS window.pageYOffset is 500
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/accessibility/scroll-window-sends-notification.html b/third_party/blink/web_tests/accessibility/scroll-window-sends-notification.html
index 7ff4cf6..4a21da6 100644
--- a/third_party/blink/web_tests/accessibility/scroll-window-sends-notification.html
+++ b/third_party/blink/web_tests/accessibility/scroll-window-sends-notification.html
@@ -1,7 +1,9 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-<script src="../resources/js-test.js"></script>
+  <script src="../resources/testharness.js"></script>
+  <script src="../resources/testharnessreport.js"></script>
+  <script src="../resources/run-after-layout-and-paint.js"></script>
 <style>
 .bigbutton {
     display:block;
@@ -19,28 +21,23 @@
 <div id="console"></div>
 <script>
 
-description("This test ensures that scrolling the window sends a notification.");
-window.jsTestIsAsync = true;
-
-if (window.testRunner && window.accessibilityController) {
-    testRunner.dumpAsText();
-
+async_test_after_layout_and_paint((t) => {
     window.scrollTo(0, 0);
-    shouldBe("window.pageYOffset", "0");
+    assert_equals(window.pageYOffset, 0);
 
     accessibilityController.addNotificationListener(function (target, notification) {
         if (target.role == 'AXRole: AXWebArea' && notification == 'ScrollPositionChanged') {
-            debug('Got notification on web area');
-            accessibilityController.removeNotificationListener();
-            shouldBe("window.pageYOffset", "500");
-            finishJSTest();
+            console.log('Got notification on web area');
+            assert_equals(window.pageYOffset, 500);
+            t.done()
         }
     });
 
     window.setTimeout(function() {
         window.scrollTo(0, 500);
     }, 0);
-}
+}, "This test ensures that scrolling the window sends a notification.");
+
 
 </script>
 
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html b/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html
index d72fd8e1..89f26ded 100644
--- a/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html
+++ b/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html
@@ -21,10 +21,14 @@
     accessibilityController.accessibleElementById('dummy');
 
     var element = document.getElementById('ariaTextbox');
-    var axElement = accessibilityController.accessibleElementById('ariaTextbox');
     element.focus();
 
+    var axElement = accessibilityController.accessibleElementById('ariaTextbox');
     axElement.addNotificationListener(t.step_func((notification) => {
+        // Focus notification will come asynchronously after layout
+        if (notification == 'Focus')
+            return;
+
         if (notification == 'SelectedTextChanged') {
             axElement.removeNotificationListener();
             t.done();
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html b/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html
index 7701d4d..831ad710 100644
--- a/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html
+++ b/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html
@@ -16,10 +16,14 @@
 <script>
 async_test_after_layout_and_paint((t) => {
     var element = document.getElementById('contentEditable');
-    var axElement = accessibilityController.accessibleElementById('contentEditable');
     element.focus();
 
+    var axElement = accessibilityController.accessibleElementById('contentEditable');
     axElement.addNotificationListener(t.step_func((notification) => {
+        // Focus notification will come asynchronously after layout
+        if (notification == 'Focus')
+            return;
+
         if (notification == 'SelectedTextChanged') {
             axElement.removeNotificationListener();
             t.done();
diff --git a/third_party/blink/web_tests/animations/events/animation-end-event-short-iterations-expected.txt b/third_party/blink/web_tests/animations/events/animation-end-event-short-iterations-expected.txt
deleted file mode 100644
index 9446983..0000000
--- a/third_party/blink/web_tests/animations/events/animation-end-event-short-iterations-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Checks that we still end an animation properly (i.e. fire a animationend event) when using more than one iteration with very short durations.
-PASS: got animationend event
diff --git a/third_party/blink/web_tests/animations/events/animation-end-event-short-iterations.html b/third_party/blink/web_tests/animations/events/animation-end-event-short-iterations.html
index 9b48303..e7ba38c 100644
--- a/third_party/blink/web_tests/animations/events/animation-end-event-short-iterations.html
+++ b/third_party/blink/web_tests/animations/events/animation-end-event-short-iterations.html
@@ -1,48 +1,33 @@
 <!DOCTYPE html>
-<html>
-<head>
-  <title>Test animations with repeated iterations and short loops</title>
-  <style>
-    #box {
-      position: relative;
-      left: 100px;
-      top: 10px;
-      height: 100px;
-      width: 100px;
-      animation-duration: 0.001s;
-      animation-name: anim;
-      background-color: #999;
-      animation-iteration-count: 2;
-    }
-    @keyframes anim {
-        from { left: 200px; }
-        to   { left: 300px; }
-    }
-  </style>
-  <script>
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }
-  
-    onload = function()
-    {
-        document.addEventListener('animationend', function() {
-            document.getElementById('result').innerHTML = 'PASS: got animationend event';
-            if (window.testRunner)
-                testRunner.notifyDone();
-        }, false);
-        
-        // Animation begins once we append the DOM node to the document.
-        var boxNode = document.createElement('div');
-        boxNode.id = 'box';
-        document.body.appendChild(boxNode);
-    }
-  </script>
-</head>
-<body>
-Checks that we still end an animation properly (i.e. fire a animationend
-event) when using more than one iteration with very short durations.
-<pre id="result">FAIL: no animationend event received</pre>
-</body>
-</html>
+<title>Test animations with repeated iterations and short loops</title>
+<style>
+  #box {
+    position: relative;
+    left: 100px;
+    top: 10px;
+    height: 100px;
+    width: 100px;
+    animation-duration: 0.001s;
+    animation-name: anim;
+    background-color: #999;
+    animation-iteration-count: 2;
+  }
+  @keyframes anim {
+    from { left: 200px; }
+    to   { left: 300px; }
+  }
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+async_test(t => {
+  window.addEventListener("load", t.step_func(() => {
+    document.addEventListener('animationend', t.step_func_done(() => {}));
+
+    // Animation begins once we append the DOM node to the document.
+    var boxNode = document.createElement('div');
+    boxNode.id = 'box';
+    document.body.appendChild(boxNode);
+  }));
+}, "Checks that we still end an animation properly (i.e. fire a animationend event) when using more than one iteration with very short durations");
+</script>
diff --git a/third_party/blink/web_tests/animations/events/animation-events-create-expected.txt b/third_party/blink/web_tests/animations/events/animation-events-create-expected.txt
deleted file mode 100644
index e0c22f7..0000000
--- a/third_party/blink/web_tests/animations/events/animation-events-create-expected.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Test dynamic creation of AnimationEvent.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS document.createEvent exists
-
-
-Test creation of AnimationEvent
-PASS typeof(ev) is 'object'
-PASS ev.animationName is ''
-PASS ev.elapsedTime is 0.0
-
-
-Create a MouseEvent and make sure it doesn't have AnimationEvent properties
-PASS typeof(ev) is 'object'
-PASS ev.animationName is undefined
-PASS ev.elapsedTime is undefined
-
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/animations/events/animation-events-create.html b/third_party/blink/web_tests/animations/events/animation-events-create.html
index b94f7e5..9c3a678 100644
--- a/third_party/blink/web_tests/animations/events/animation-events-create.html
+++ b/third_party/blink/web_tests/animations/events/animation-events-create.html
@@ -1,39 +1,18 @@
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
 <script>
+test(() => {
+  var ev = document.createEvent('AnimationEvent');
+  assert_equals(typeof(ev), 'object');
+  assert_equals(ev.animationName, '');
+  assert_equals(ev.elapsedTime, 0.0);
+}, "Test creation of AnimationEvent");
 
-description("Test dynamic creation of AnimationEvent.");
-
-if (document.createEvent)
-    testPassed("document.createEvent exists");
-else
-    testFailed("document.createEvent missing");
-
-debug("");
-debug("Test creation of AnimationEvent");
-
-var ev = document.createEvent("AnimationEvent");
-
-shouldBe("typeof(ev)", "'object'");
-shouldBe("ev.animationName", "''");
-shouldBe("ev.elapsedTime", "0.0");
-
-debug("");
-debug("Create a MouseEvent and make sure it doesn't have AnimationEvent properties");
-
-ev = document.createEvent("MouseEvent");
-
-shouldBe("typeof(ev)", "'object'");
-shouldBe("ev.animationName", "undefined");
-shouldBe("ev.elapsedTime", "undefined");
-
-debug("");
-
+test(() => {
+  ev = document.createEvent('MouseEvent');
+  assert_equals(typeof(ev), 'object');
+  assert_equals(ev.animationName, undefined);
+  assert_equals(ev.elapsedTime, undefined);
+}, "Create a MouseEvent and make sure it doesn't have AnimationEvent properties");
 </script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/animations/events/animation-immediate-start-event-after-ondemand-update-expected.txt b/third_party/blink/web_tests/animations/events/animation-immediate-start-event-after-ondemand-update-expected.txt
deleted file mode 100644
index 7ef22e9..0000000
--- a/third_party/blink/web_tests/animations/events/animation-immediate-start-event-after-ondemand-update-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-PASS
diff --git a/third_party/blink/web_tests/animations/events/animation-immediate-start-event-after-ondemand-update.html b/third_party/blink/web_tests/animations/events/animation-immediate-start-event-after-ondemand-update.html
index c66fd7b1..4bb9c829 100644
--- a/third_party/blink/web_tests/animations/events/animation-immediate-start-event-after-ondemand-update.html
+++ b/third_party/blink/web_tests/animations/events/animation-immediate-start-event-after-ondemand-update.html
@@ -1,4 +1,4 @@
-<!doctype html>
+<!DOCTYPE html>
 <style>
 .animated {
   animation: test 10ms;
@@ -8,27 +8,23 @@
   0% {}
 }
 </style>
-<div id="test">FAIL</div>
+<div id="block"></div>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
 <script>
-if (window.testRunner) {
-  testRunner.dumpAsText();
-  testRunner.waitUntilDone();
-}
-onload = function() {
-  // This test covers a specific regression where an on-demand timing update
-  // that was triggered after an animation received a start time could cause
-  // CSS Animation and Transition events to not be fired on the subseuquent
-  // animation-frame timing update.
-  test.classList.add('animated');
-  test.addEventListener('animationstart', function() {
-    document.documentElement.textContent = 'PASS';
-    if (window.testRunner)
-      testRunner.notifyDone();
-  });
-  requestAnimationFrame(function() {
-    setTimeout(function() {
-      getComputedStyle(test).left;
-    });
-  });
-}
+async_test(t => {
+  window.addEventListener("load", t.step_func(() => {
+    // This test covers a specific regression where an on-demand timing update
+    // that was triggered after an animation received a start time could cause
+    // CSS Animation and Transition events to not be fired on the subseuquent
+    // animation-frame timing update.
+    block.classList.add('animated');
+    block.addEventListener('animationstart', t.step_func_done(() => {}));
+    requestAnimationFrame(t.step_func(() => {
+      t.step_timeout(() => {
+        getComputedStyle(block).left;
+      });
+    }));
+  }));
+}, "Should fire animation events after on-demand timing update");
 </script>
diff --git a/third_party/blink/web_tests/animations/events/animation-iteration-event-short-iterations-expected.txt b/third_party/blink/web_tests/animations/events/animation-iteration-event-short-iterations-expected.txt
deleted file mode 100644
index 8d0573d0..0000000
--- a/third_party/blink/web_tests/animations/events/animation-iteration-event-short-iterations-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Tests that iteration events are fired when the duration is very short.
-PASS: Got a reasonable number of animationCount events
diff --git a/third_party/blink/web_tests/animations/events/animation-iteration-event-short-iterations.html b/third_party/blink/web_tests/animations/events/animation-iteration-event-short-iterations.html
index 08c8350..c1687a8 100644
--- a/third_party/blink/web_tests/animations/events/animation-iteration-event-short-iterations.html
+++ b/third_party/blink/web_tests/animations/events/animation-iteration-event-short-iterations.html
@@ -1,61 +1,42 @@
 <!DOCTYPE html>
-<html>
-<head>
-  <title>Tests that iteration events are fired when the duration is very short.</title>
-  <style>
-    #box {
-      position: relative;
-      left: 100px;
-      top: 10px;
-      height: 100px;
-      width: 100px;
-      animation-duration: 0.001s;
-      animation-name: anim;
-      background-color: #999;
-      animation-iteration-count: 10;
-    }
-    @keyframes anim {
-        from { left: 200px; }
-        to   { left: 300px; }
-    }
-  </style>
-  <script>
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }
+<title>Tests that iteration events are fired when the duration is very short.</title>
+<style>
+  #box {
+    position: relative;
+    left: 100px;
+    top: 10px;
+    height: 100px;
+    width: 100px;
+    animation-duration: 0.001s;
+    animation-name: anim;
+    background-color: #999;
+    animation-iteration-count: 10;
+  }
+  @keyframes anim {
+      from { left: 200px; }
+      to   { left: 300px; }
+  }
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+var count = 0;
+async_test(t => {
+  window.addEventListener("load", t.step_func(() => {
+    document.addEventListener('animationIteration', t.step_func(() => {
+      ++count;
+    }));
 
-    function fail() {
-      document.getElementById('result').innerHTML = 'FAIL: Got ' + count + ' animationCount events';
-    }  
+    document.addEventListener('animationend', t.step_func_done(() => {
+      // We collapse all iteration events that occur within a single
+      // frame into a single event. See http://crbug.com/275263.
+      assert_less_than(count, 10, 'Got a reasonable number of animationCount events');
+    }));
 
-    var count = 0;
-    onload = function()
-    {
-        document.addEventListener('animationIteration', function() {
-          ++count;
-        }, false);
-
-        document.addEventListener('animationend', function() {
-            // We collapse all iteration events that occur within a single
-            // frame into a single event. See http://crbug.com/275263.
-            if (count < 10)
-                document.getElementById('result').innerHTML = 'PASS: Got a reasonable number of animationCount events';
-            else
-                fail();
-            if (window.testRunner)
-                testRunner.notifyDone();
-        }, false);
-
-        // Animation begins once we append the DOM node to the document.
-        var boxNode = document.createElement('div');
-        boxNode.id = 'box';
-        document.body.appendChild(boxNode);
-    }
-  </script>
-</head>
-<body>
-Tests that iteration events are fired when the duration is very short.
-<pre id="result">FAIL: No animationend event received</pre>
-</body>
-</html>
+    // Animation begins once we append the DOM node to the document.
+    var boxNode = document.createElement('div');
+    boxNode.id = 'box';
+    document.body.appendChild(boxNode);
+  }));
+}, "Tests that iteration events are fired when the duration is very short");
+</script>
diff --git a/third_party/blink/web_tests/animations/events/delay-start-event-expected.txt b/third_party/blink/web_tests/animations/events/delay-start-event-expected.txt
deleted file mode 100644
index fed2d6434..0000000
--- a/third_party/blink/web_tests/animations/events/delay-start-event-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Tests that the start event is fired at the correct time with different start delays.
-
-PASS: negative-delay: Start event fired immediately
-PASS: zero-delay: Start event fired immediately
-PASS: positive-delay: Start event did not fire immediately
diff --git a/third_party/blink/web_tests/animations/events/delay-start-event.html b/third_party/blink/web_tests/animations/events/delay-start-event.html
index 835f885e..32da662 100644
--- a/third_party/blink/web_tests/animations/events/delay-start-event.html
+++ b/third_party/blink/web_tests/animations/events/delay-start-event.html
@@ -1,58 +1,53 @@
 <!DOCTYPE html>
-<html>
-<head>
-  <style type="text/css">
-    .target {
-      position: relative;
-      height: 100px;
-      width: 100px;
-      background-color: red;
-      margin-bottom: 10px;
-    }
-    .animated {
-      animation: test 1s linear;
-      animation: test 1s linear;
-    }
-    #negative-delay {
-      animation-delay: -500ms;
-      animation-delay: -500ms;
-    }
-    #zero-delay {
-      animation-delay: 0ms;
-      animation-delay: 0ms;
-    }
-    #positive-delay {
-      animation-delay: 500ms;
-      animation-delay: 500ms;
-    }
-    @keyframes test {
-        from { left: 100px; }
-        to   { left: 300px; }
-    }
-    @keyframes test {
-        from { left: 100px; }
-        to   { left: 300px; }
-    }
-  </style>
-  <script type="text/javascript">
-    if (window.testRunner) {
-      testRunner.dumpAsText();
-      testRunner.waitUntilDone();
-    }
-
-    var immediate = true;
-    onload = function() {
-      requestAnimationFrame(function(t) {
-        ['negative-delay', 'zero-delay', 'positive-delay'].forEach(function(id) {
-          var target = document.getElementById(id);
-          target.addEventListener('animationstart', onStartEventFired);
-          target.classList.add('animated');
-        });
-        requestAnimationFrame(function() {
-          immediate = false;
-        });
+<style type="text/css">
+  .target {
+    position: relative;
+    height: 100px;
+    width: 100px;
+    background-color: red;
+    margin-bottom: 10px;
+  }
+  .animated {
+    animation: test 1s linear;
+    animation: test 1s linear;
+  }
+  #negative-delay {
+    animation-delay: -500ms;
+    animation-delay: -500ms;
+  }
+  #zero-delay {
+    animation-delay: 0ms;
+    animation-delay: 0ms;
+  }
+  #positive-delay {
+    animation-delay: 500ms;
+    animation-delay: 500ms;
+  }
+  @keyframes test {
+    from { left: 100px; }
+    to   { left: 300px; }
+  }
+  @keyframes test {
+    from { left: 100px; }
+    to   { left: 300px; }
+  }
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script type="text/javascript">
+async_test(t => {
+  var immediate = true;
+  window.addEventListener("load", t.step_func(() => {
+    requestAnimationFrame(t.step_func(() => {
+      ['negative-delay', 'zero-delay', 'positive-delay'].forEach((id) => {
+        var target = document.getElementById(id);
+        target.addEventListener('animationstart', onStartEventFired);
+        target.classList.add('animated');
       });
-    };
+      requestAnimationFrame(t.step_func(() => {
+        immediate = false;
+      }));
+    }));
 
     function log(message) {
       var div = document.createElement('div');
@@ -64,17 +59,14 @@
       var id = e.target.id;
       var pass = immediate || id == 'positive-delay';
       log((pass ? 'PASS' : 'FAIL') + ': ' + id + ': Start event ' + (immediate ? 'fired' : 'did not fire') + ' immediately');
-      if (id === 'positive-delay' && window.testRunner) {
-        testRunner.notifyDone();
+      assert_true(pass, 'Start event should be fired');
+      if (id === 'positive-delay') {
+        t.done();
       }
     }
-  </script>
-</head>
-<body>
-  <p>Tests that the start event is fired at the correct time with different start delays.</p>
-  <div class="target" id="negative-delay"></div>
-  <div class="target" id="zero-delay"></div>
-  <div class="target" id="positive-delay"></div>
-  <div id="result"></div>
-</body>
-</html>
+  }));
+}, "Tests that the start event is fired at the correct time with different start delays");
+</script>
+<div class="target" id="negative-delay"></div>
+<div class="target" id="zero-delay"></div>
+<div class="target" id="positive-delay"></div>
diff --git a/third_party/blink/web_tests/animations/events/events-with-short-duration-and-delay-expected.txt b/third_party/blink/web_tests/animations/events/events-with-short-duration-and-delay-expected.txt
deleted file mode 100644
index 5b012b8..0000000
--- a/third_party/blink/web_tests/animations/events/events-with-short-duration-and-delay-expected.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Test events when the animation has a short duration and is delayed.
-PASS: got animationstart event
-PASS: got animationend event
diff --git a/third_party/blink/web_tests/animations/events/events-with-short-duration-and-delay.html b/third_party/blink/web_tests/animations/events/events-with-short-duration-and-delay.html
index d3b8e7a..43ff436 100644
--- a/third_party/blink/web_tests/animations/events/events-with-short-duration-and-delay.html
+++ b/third_party/blink/web_tests/animations/events/events-with-short-duration-and-delay.html
@@ -1,51 +1,40 @@
 <!DOCTYPE html>
-<html>
-<head>
-  <title>Test events when the animation has a short duration and is delayed</title>
-  <style>
-    #box {
-      position: relative;
-      left: 100px;
-      top: 10px;
-      height: 100px;
-      width: 100px;
-      animation-duration: 0.001s;
-      animation-delay: 0.001s;
-      animation-name: anim;
-      background-color: #999;
-      animation-iteration-count: 2;
-    }
-    @keyframes anim {
-        from { left: 200px; }
-        to   { left: 300px; }
-    }
-  </style>
-  <script>
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }
-  
-    onload = function()
-    {
-        document.addEventListener('animationstart', function() {
-            document.getElementById('result').innerHTML = 'PASS: got animationstart event';
-        }, false);
-        document.addEventListener('animationend', function() {
-            document.getElementById('result').innerHTML += '<br>PASS: got animationend event';
-            if (window.testRunner)
-                testRunner.notifyDone();
-        }, false);
-        
-        // Animation begins once we append the DOM node to the document.
-        var boxNode = document.createElement('div');
-        boxNode.id = 'box';
-        document.body.appendChild(boxNode);
-    }
-  </script>
-</head>
-<body>
-Test events when the animation has a short duration and is delayed.
-<pre id="result">FAIL: No events received</pre>
-</body>
-</html>
+<title>Test events when the animation has a short duration and is delayed</title>
+<style>
+#box {
+  position: relative;
+  left: 100px;
+  top: 10px;
+  height: 100px;
+  width: 100px;
+  animation-duration: 0.001s;
+  animation-delay: 0.001s;
+  animation-name: anim;
+  background-color: #999;
+  animation-iteration-count: 2;
+}
+@keyframes anim {
+  from { left: 200px; }
+  to   { left: 300px; }
+}
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+async_test(t => {
+  window.addEventListener("load", t.step_func(() => {
+    var animationStarted = false;
+    document.addEventListener('animationstart', t.step_func(() => {
+      animationStarted = true;
+    }));
+    document.addEventListener('animationend', t.step_func_done(() => {
+      assert_true(animationStarted);
+    }));
+
+    // Animation begins once we append the DOM node to the document.
+    var boxNode = document.createElement('div');
+    boxNode.id = 'box';
+    document.body.appendChild(boxNode);
+  }));
+}, "Test events when the animation has a short duration and is delayed");
+</script>
diff --git a/third_party/blink/web_tests/animations/events/negative-delay-events-expected.txt b/third_party/blink/web_tests/animations/events/negative-delay-events-expected.txt
deleted file mode 100644
index d5a9053..0000000
--- a/third_party/blink/web_tests/animations/events/negative-delay-events-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Tests animation events with a negative delay.
-
-PASS: animation1: Start event: elapsedTime=0
-PASS: animation1: End event: elapsedTime=0.1
-PASS: animation2: Start event: elapsedTime=0.05
-PASS: animation2: End event: elapsedTime=0.1
-PASS: animation3: Start event: elapsedTime=0.15
-PASS: animation3: End event: elapsedTime=0.1
diff --git a/third_party/blink/web_tests/animations/events/negative-delay-events.html b/third_party/blink/web_tests/animations/events/negative-delay-events.html
index c09a3ff..5f5ff5b 100644
--- a/third_party/blink/web_tests/animations/events/negative-delay-events.html
+++ b/third_party/blink/web_tests/animations/events/negative-delay-events.html
@@ -1,72 +1,56 @@
 <!DOCTYPE html>
+<style type="text/css">
+.box {
+  position: relative;
+  height: 25px;
+  width: 25px;
+  background-color: blue;
+  margin: 10px;
+}
+.animation {
+  animation-duration: 0.1s;
+  animation-name: animation;
+}
+#animation1 {
+  animation-delay: 0.05s;
+}
+#animation2 {
+  animation-delay: -0.05s;
+}
+#animation3 {
+  animation-delay: -0.15s;
+}
+@keyframes animation {
+  from { left: 0; }
+  to   { left: 500px; }
+}
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script type="text/javascript">
+async_test(t => {
+  var count = 0;
+  document.addEventListener('animationstart', t.step_func((event) => {
+      var pass = event.elapsedTime === [0, 0.05, 0.15][count++];
+      assert_true(pass, event.target.id + ': Start event: elapsedTime=' + event.elapsedTime);
+  }));
 
-<html>
-<head>
-  <style type="text/css">
-    .box {
-      position: relative;
-      height: 25px;
-      width: 25px;
-      background-color: blue;
-      margin: 10px;
-    }
-    .animation {
-      animation-duration: 0.1s;
-      animation-name: animation;
-    }
-    #animation1 {
-      animation-delay: 0.05s;
-    }
-    #animation2 {
-      animation-delay: -0.05s;
-    }
-    #animation3 {
-      animation-delay: -0.15s;
-    }
-    @keyframes animation {
-        from { left: 0; }
-        to   { left: 500px; }
-    }
-  </style>
-  <script type="text/javascript">
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }
-    function log(text) {
-        var div = document.createElement('div');
-        div.innerText = text;
-        document.getElementById('log').appendChild(div);
-    }
-
-    var count = 0;
-    document.addEventListener('animationstart', function(event) {
-        var pass = event.elapsedTime === [0, 0.05, 0.15][count++];
-        log((pass ? 'PASS' : 'FAIL') + ': ' + event.target.id + ': Start event: elapsedTime=' + event.elapsedTime);
-    }, false);
-
-    document.addEventListener('animationend', function(event) {
-        var pass = event.elapsedTime === 0.1;
-        log((pass ? 'PASS' : 'FAIL') + ': ' + event.target.id + ': End event: elapsedTime=' + event.elapsedTime);
-        switch (count) {
-        case 1:
-            document.getElementById('animation2').classList.add('animation');
-            break;
-        case 2:
-            document.getElementById('animation3').classList.add('animation');
-            break;
-        case 3:
-            if (window.testRunner)
-                testRunner.notifyDone();
-        }
-    }, false);
-  </script>
-</head>
-<body>
-  <p>Tests animation events with a negative delay.
-  <div id="animation1" class="box animation"></div>
-  <div id="animation2" class="box"></div>
-  <div id="animation3" class="box"></div>
-  <div id="log"></div>
-</body>
-</html>
+  document.addEventListener('animationend', t.step_func((event) => {
+      var pass = event.elapsedTime === 0.1;
+      assert_true(pass, event.target.id + ': End event: elapsedTime=' + event.elapsedTime);
+      switch (count) {
+      case 1:
+          document.getElementById('animation2').classList.add('animation');
+          break;
+      case 2:
+          document.getElementById('animation3').classList.add('animation');
+          break;
+      case 3:
+          t.done();
+      }
+  }));
+}, "Tests animation events with a negative delay");
+</script>
+<div id="animation1" class="box animation"></div>
+<div id="animation2" class="box"></div>
+<div id="animation3" class="box"></div>
diff --git a/third_party/blink/web_tests/animations/events/play-state-initially-paused-start-event-expected.txt b/third_party/blink/web_tests/animations/events/play-state-initially-paused-start-event-expected.txt
deleted file mode 100644
index 6d14091..0000000
--- a/third_party/blink/web_tests/animations/events/play-state-initially-paused-start-event-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Tests that an animation which is initially paused fires its start event as soon as its delay expires, not when it transitions to the running state.
-
-PASS: animation1: Start event fired without setting play state to running
-PASS: animation2: Start event fired without setting play state to running
-PASS: animation3: Start event fired after play state was set to running
diff --git a/third_party/blink/web_tests/animations/events/play-state-initially-paused-start-event.html b/third_party/blink/web_tests/animations/events/play-state-initially-paused-start-event.html
index 34986b2..3eb52bd 100644
--- a/third_party/blink/web_tests/animations/events/play-state-initially-paused-start-event.html
+++ b/third_party/blink/web_tests/animations/events/play-state-initially-paused-start-event.html
@@ -1,105 +1,87 @@
 <!DOCTYPE html>
-<html>
-<head>
-  <style type="text/css">
-    .target {
-      position: relative;
-      height: 100px;
-      width: 100px;
-      background-color: red;
-      margin-bottom: 10px;
+<style type="text/css">
+  .target {
+    position: relative;
+    height: 100px;
+    width: 100px;
+    background-color: red;
+    margin-bottom: 10px;
+  }
+  .animated {
+    animation: test 10ms linear forwards;
+    animation-play-state: paused;
+    animation: test 10ms linear forwards;
+    animation-play-state: paused;
+  }
+  .running {
+    animation-play-state: running;
+    animation-play-state: running;
+  }
+  #animation1 {
+    animation-delay: -10ms;
+    animation-delay: -10ms;
+  }
+  #animation2 {
+    animation-delay: 0ms;
+    animation-delay: 0ms;
+  }
+  #animation3 {
+    animation-delay: 10ms;
+    animation-delay: 10ms;
+  }
+  @keyframes test {
+      from { left: 100px; }
+      to   { left: 300px; }
+  }
+  @keyframes test {
+      from { left: 100px; }
+      to   { left: 300px; }
+  }
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script type="text/javascript">
+async_test(t => {
+  function startNextAnimation(currentId) {
+    // Running animations serially avoids flakiness due to overlap.
+    if (currentId === 'animation1') {
+      start(document.getElementById('animation2'), true);
+    } else if (currentId === 'animation2') {
+      start(document.getElementById('animation3'), false);
+    } else if (currentId === 'animation3') {
+      t.done();
     }
-    .animated {
-      animation: test 10ms linear forwards;
-      animation-play-state: paused;
-      animation: test 10ms linear forwards;
-      animation-play-state: paused;
-    }
-    .running {
-      animation-play-state: running;
-      animation-play-state: running;
-    }
-    #animation1 {
-      animation-delay: -10ms;
-      animation-delay: -10ms;
-    }
-    #animation2 {
-      animation-delay: 0ms;
-      animation-delay: 0ms;
-    }
-    #animation3 {
-      animation-delay: 10ms;
-      animation-delay: 10ms;
-    }
-    @keyframes test {
-        from { left: 100px; }
-        to   { left: 300px; }
-    }
-    @keyframes test {
-        from { left: 100px; }
-        to   { left: 300px; }
-    }
-  </style>
-  <script type="text/javascript">
-    if (window.testRunner) {
-      testRunner.dumpAsText();
-      testRunner.waitUntilDone();
-    }
+  }
 
-    function log(message) {
-      var div = document.createElement('div');
-      div.textContent = message;
-      document.body.appendChild(div);
-    }
+  var isRunning;
+  function run(element) {
+    element.classList.add('running');
+    isRunning = true;
+  }
 
-    function startNextAnimation(currentId) {
-      // Running animations serially avoids flakiness due to overlap.
-      if (currentId === 'animation1') {
-        start(document.getElementById('animation2'), true);
-      } else if (currentId === 'animation2') {
-        start(document.getElementById('animation3'), false);
-      } else if (currentId === 'animation3' && window.testRunner) {
-        testRunner.notifyDone();
-      }
-    }
-
-    function onStartEventFired(expectStartEventFirst, e) {
+  function start(target, expectImmediateStartEvent) {
+    isRunning = false;
+    target.addEventListener('animationstart', t.step_func((e) => {
       var id = e.target.id;
-      if (expectStartEventFirst) {
-        log('PASS: ' + id + ': Start event fired without setting play state to running');
+
+      if (expectImmediateStartEvent) {
+        assert_false(isRunning, 'Start event should be fired without setting play state to running');
       } else {
-        log((isRunning ? 'PASS' : 'FAIL') + ': ' + id + ': Start event fired ' + (isRunning ? 'after' : 'before') + ' play state was set to running');
+        assert_true(isRunning, 'Start event should be fired after play state was set to running');
       }
       startNextAnimation(id);
+    }));
+    target.classList.add('animated');
+    if (!expectImmediateStartEvent) {
+      t.step_timeout(run.bind(null, target), 100);
     }
+  }
 
-    var isRunning;
-    function run(element) {
-      element.classList.add('running');
-      isRunning = true;
-    }
-
-    function start(target, expectImmediateStartEvent) {
-      isRunning = false;
-      var startEventHandler = onStartEventFired.bind(null, expectImmediateStartEvent);
-      target.addEventListener('animationstart', startEventHandler);
-      target.addEventListener('animationstart', startEventHandler);
-      target.classList.add('animated');
-      if (!expectImmediateStartEvent) {
-        setTimeout(run.bind(null, target), 100);
-      }
-    }
-
-    function go() {
-      start(document.getElementById('animation1'), true);
-    }
-  </script>
-</head>
-<body onload="go()">
-  <p>Tests that an animation which is initially paused fires its start event as soon as its delay expires, not when it transitions to the running state.</p>
-  <div class="target" id="animation1"></div>
-  <div class="target" id="animation2"></div>
-  <div class="target" id="animation3"></div>
-  <div id="result"></div>
-</body>
-</html>
+  window.addEventListener("load", t.step_func(() => {
+    start(document.getElementById('animation1'), true);
+  }));
+}, "Tests that an animation which is initially paused fires its start event as soon as its delay expires, not when it transitions to the running state");
+</script>
+<div class="target" id="animation1"></div>
+<div class="target" id="animation2"></div>
+<div class="target" id="animation3"></div>
diff --git a/third_party/blink/web_tests/editing/pasteboard/drag-drop-to-data-url.html b/third_party/blink/web_tests/editing/pasteboard/drag-drop-to-data-url.html
index 6ccd70f..33a2527 100644
--- a/third_party/blink/web_tests/editing/pasteboard/drag-drop-to-data-url.html
+++ b/third_party/blink/web_tests/editing/pasteboard/drag-drop-to-data-url.html
@@ -3,7 +3,7 @@
 <script src="../../resources/testharnessreport.js"></script>
 <p>Check you can't drag into a data URL</p>
 <div><span id="dragme">hello</span></div>
-<iframe id="target" src="data:text/html;charset=utf-8,%3Cbody%20contentEditable%3Dtrue%3E%0D%0A"></iframe>
+<iframe id="target" srcdoc='<body contenteditable="true"></body>'></iframe>
 <script>
 var target = document.getElementById("target");
 var t = async_test('Drag-And-Drop to Data URL');
@@ -34,7 +34,7 @@
 function dropIt() {
     // Drop it off to the frame
     eventSender.mouseUp();
-    assert_equals(target.contentDocument.body.outerHTML, '<body contenteditable="true">\n</body>');
+    assert_equals(target.contentDocument.body.outerHTML, '<body contenteditable="true"></body>');
     t.done();
 }
 </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 0ff024c..8ac0b5c6 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
@@ -30847,6 +30847,18 @@
      {}
     ]
    ],
+   "css/css-backgrounds/background-clip/clip-text-dynamic-2.html": [
+    [
+     "/css/css-backgrounds/background-clip/clip-text-dynamic-2.html",
+     [
+      [
+       "/css/css-backgrounds/background-clip/clip-text-dynamic-2-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-backgrounds/background-clip_padding-box.html": [
     [
      "/css/css-backgrounds/background-clip_padding-box.html",
@@ -127940,6 +127952,11 @@
      {}
     ]
    ],
+   "css/css-backgrounds/background-clip/clip-text-dynamic-2-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-backgrounds/background-clip/list.txt": [
     [
      {}
@@ -219892,12 +219909,6 @@
      {}
     ]
    ],
-   "css/css-flexbox/intrinsic-width-overflow-auto.tentative.html": [
-    [
-     "/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html",
-     {}
-    ]
-   ],
    "css/css-flexbox/order_value.html": [
     [
      "/css/css-flexbox/order_value.html",
@@ -343053,6 +343064,14 @@
    "3453c5bc8f5e45667ba20a1e6276a08e4b1be714",
    "reftest"
   ],
+  "css/css-backgrounds/background-clip/clip-text-dynamic-2-ref.html": [
+   "6a4ef234b0bbd74ad6d43984c53eed24dc60b852",
+   "support"
+  ],
+  "css/css-backgrounds/background-clip/clip-text-dynamic-2.html": [
+   "57a31266bec7953da32bb92654afcfd26bd43e65",
+   "reftest"
+  ],
   "css/css-backgrounds/background-clip/list.txt": [
    "52c47ebba998b264b0218b84bacf2cf9784371ea",
    "support"
@@ -351753,10 +351772,6 @@
    "0220d79d901cca14324ea331d0ddfd9c086a08ee",
    "manual"
   ],
-  "css/css-flexbox/intrinsic-width-overflow-auto.tentative.html": [
-   "8310e66cc4a2ef680d15f5c3ea56feb6edf4252e",
-   "testharness"
-  ],
   "css/css-flexbox/item-with-table-with-infinite-max-intrinsic-width.html": [
    "f475db5bcffd1449be231da943cd1511b15e20b1",
    "reftest"
@@ -435342,7 +435357,7 @@
    "support"
   ],
   "interfaces/secure-contexts.idl": [
-   "c4a3eca231573d3c9116f55568bf5544b9a4e449",
+   "c177b27a012889a49ac034172bf3ddcfda95fde0",
    "support"
   ],
   "interfaces/selection-api.idl": [
@@ -435458,7 +435473,7 @@
    "support"
   ],
   "interfaces/webrtc.idl": [
-   "413a96ac56052a72e51ce55055286562e2e7673a",
+   "c40266388cba1558348b1d556efa53243dac7d47",
    "support"
   ],
   "interfaces/webusb.idl": [
@@ -447962,7 +447977,7 @@
    "support"
   ],
   "payment-method-basic-card/META.yml": [
-   "b1d851431cb2ce519bf8df956d9c623db24cf33d",
+   "30994b67caf6ba8b0486876333352ba655f5f768",
    "support"
   ],
   "payment-method-basic-card/OWNERS": [
@@ -477986,11 +478001,11 @@
    "testharness"
   ],
   "webrtc/RTCPeerConnection-addIceCandidate-expected.txt": [
-   "beb97c56fa587abf78454f9fba930ed61c48a7b0",
+   "9d7cf8b11965a4efd93c495101fa5421f5d79719",
    "support"
   ],
   "webrtc/RTCPeerConnection-addIceCandidate.html": [
-   "2283c6835e1401f3416d79a6281f25c09f1b3022",
+   "51a5677699fd635335ede3f7e41ec48b17d3e60c",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-addTrack.https.html": [
@@ -478362,11 +478377,11 @@
    "testharness"
   ],
   "webrtc/RTCRtpTransceiver-stop-expected.txt": [
-   "aac18318f65f60bbd3a9033385918eec423a176e",
+   "80df50319c86b8e9da60893db6ea82dbacf2b02c",
    "support"
   ],
   "webrtc/RTCRtpTransceiver-stop.html": [
-   "b45e03bd019015947b03df8c8bfbb1aa736bd3fe",
+   "4f57dc7b6d348486e2715aff1e7d7e773c29d0e3",
    "testharness"
   ],
   "webrtc/RTCRtpTransceiver.https.html": [
@@ -478438,7 +478453,7 @@
    "testharness"
   ],
   "webrtc/idlharness.https.window-expected.txt": [
-   "be57dd0e60da78b3e3a2890fbea745d0eb590435",
+   "4c6d5fc5c45aedee301b880f773667f6d7537b95",
    "support"
   ],
   "webrtc/idlharness.https.window.js": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-dynamic-2-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-dynamic-2-ref.html
new file mode 100644
index 0000000..6a4ef234
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-dynamic-2-ref.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<style>
+  .text {
+    background-color: blue;
+    color: transparent;
+    font: 50px/1 monospace;
+    -webkit-background-clip: text;
+    background-clip: text;
+    height: 200px;
+  }
+  .prev {
+    height: 100px;
+  }
+  p {
+    color: transparent;
+  }
+</style>
+<div class="text">
+  <div class="prev"></div>
+  <div class="inner">
+    <p>XxX</p>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-dynamic-2.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-dynamic-2.html
new file mode 100644
index 0000000..57a3126
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-dynamic-2.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>CSS Test: background-clip: text is invalidated properly on text position changes</title>
+<link rel="help" href="https://drafts.csswg.org/css-backgrounds-4/#valdef-background-clip-text">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1525372">
+<link rel="author" href="mailto:mwoodrow@mozilla.com" title="Matt Woodrow">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="match" href="clip-text-dynamic-2-ref.html">
+<style>
+  .text {
+    background-color: blue;
+    color: transparent;
+    font: 50px/1 monospace;
+    -webkit-background-clip: text;
+    background-clip: text;
+    height: 200px;
+  }
+  .prev {
+    height: 10px;
+  }
+  p {
+    color: transparent;
+  }
+</style>
+<div class="text">
+  <div class="prev"></div>
+  <div class="inner">
+    <p>XxX</p>
+  </div>
+</div>
+<script>
+onload = () => {
+  requestAnimationFrame(() => {
+    requestAnimationFrame(() => {
+      document.querySelector(".prev").style.height = "100px";
+      document.documentElement.className = "";
+    })
+  })
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/secure-contexts.idl b/third_party/blink/web_tests/external/wpt/interfaces/secure-contexts.idl
index c4a3eca..c177b27 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/secure-contexts.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/secure-contexts.idl
@@ -3,6 +3,6 @@
 // (https://github.com/tidoust/reffy-reports)
 // Source: Secure Contexts (https://w3c.github.io/webappsec-secure-contexts/)
 
-partial interface WindowOrWorkerGlobalScope {
+partial interface mixin WindowOrWorkerGlobalScope {
   readonly attribute boolean isSecureContext;
 };
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 413a96a..c402663 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
@@ -183,7 +183,7 @@
              DOMString candidate = "";
              DOMString? sdpMid = null;
              unsigned short? sdpMLineIndex = null;
-             DOMString usernameFragment;
+             DOMString? usernameFragment = null;
 };
 
 enum RTCIceProtocol {
@@ -496,7 +496,7 @@
                     attribute EventHandler ondatachannel;
 };
 
-[Exposed=Window] interface RTCSctpTransport {
+[Exposed=Window] interface RTCSctpTransport : EventTarget {
     readonly        attribute RTCDtlsTransport transport;
     readonly        attribute RTCSctpTransportState state;
     readonly        attribute unrestricted double maxMessageSize;
diff --git a/third_party/blink/web_tests/external/wpt/payment-method-basic-card/META.yml b/third_party/blink/web_tests/external/wpt/payment-method-basic-card/META.yml
index b1d8514..30994b6 100644
--- a/third_party/blink/web_tests/external/wpt/payment-method-basic-card/META.yml
+++ b/third_party/blink/web_tests/external/wpt/payment-method-basic-card/META.yml
@@ -1,5 +1,5 @@
 spec: https://w3c.github.io/payment-method-basic-card/
 suggested_reviewers:
-  - mnoorenberghe
+  - danyao
   - marcoscaceres
   - rsolomakhin
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-expected.txt
index beb97c5..9d7cf8b 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-expected.txt
@@ -1,6 +1,12 @@
 This is a testharness.js-based test.
-PASS Add null candidate should reject with TypeError
 FAIL Add ICE candidate before setting remote description should reject with InvalidStateError assert_throws: function "function() { throw e }" threw object "OperationError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Error processing ICE candidate" that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
+FAIL addIceCandidate({"candidate":"","sdpMid":null,"sdpMLineIndex":null}) should work, and add a=end-of-candidates to both m-sections promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': 1 argument required, but only 0 present."
+FAIL addIceCandidate(undefined) should work, and add a=end-of-candidates to both m-sections promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': 1 argument required, but only 0 present."
+FAIL addIceCandidate(null) should work, and add a=end-of-candidates to both m-sections promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': 1 argument required, but only 0 present."
+FAIL addIceCandidate({}) should work, and add a=end-of-candidates to both m-sections promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': 1 argument required, but only 0 present."
+FAIL addIceCandidate({usernameFragment: usernameFragment1}) should work, and add a=end-of-candidates to the first m-section promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Candidate missing values for both sdpMid and sdpMLineIndex"
+FAIL addIceCandidate({usernameFragment: usernameFragment2}) should work, and add a=end-of-candidates to the first m-section promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Candidate missing values for both sdpMid and sdpMLineIndex"
+FAIL addIceCandidate({usernameFragment: "no such ufrag"}) should work, but not add a=end-of-candidates promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Candidate missing values for both sdpMid and sdpMLineIndex"
 PASS Add ICE candidate after setting remote description should succeed
 PASS Add ICE candidate with RTCIceCandidate should succeed
 PASS Add candidate with only valid sdpMid should succeed
@@ -13,8 +19,6 @@
 PASS Add candidate with both sdpMid and sdpMLineIndex manually set to null should reject with TypeError
 PASS Add candidate with only valid candidate string should reject with TypeError
 PASS Add candidate with invalid candidate string and both sdpMid and sdpMLineIndex null should reject with TypeError
-PASS Add candidate with empty dict should reject with TypeError
-PASS Add candidate with manually filled default values should reject with TypeError
 PASS Add candidate with invalid sdpMid should reject with OperationError
 PASS Add candidate with invalid sdpMLineIndex should reject with OperationError
 FAIL Invalid sdpMLineIndex should be ignored if valid sdpMid is provided promise_test: Unhandled rejection with value: object "OperationError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Error processing ICE candidate"
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html
index 2283c68..51a5677 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html
@@ -85,44 +85,37 @@
     return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
   }
 
-  // Check that a candidate line is found after the first media line
-  // but before the second, i.e. it belongs to the first media stream
-  function assert_candidate_line_between(sdp, beforeMediaLine, candidateLine, afterMediaLine) {
+  function is_candidate_line_between(sdp, beforeMediaLine, candidateLine, afterMediaLine) {
     const line1 = escapeRegExp(beforeMediaLine);
     const line2 = escapeRegExp(candidateLine);
     const line3 = escapeRegExp(afterMediaLine);
 
     const regex = new RegExp(`${line1}[^]+${line2}[^]+${line3}`);
+    return regex.test(sdp);
+  }
 
-    assert_true(regex.test(sdp),
+  // Check that a candidate line is found after the first media line
+  // but before the second, i.e. it belongs to the first media stream
+  function assert_candidate_line_between(sdp, beforeMediaLine, candidateLine, afterMediaLine) {
+    assert_true(is_candidate_line_between(sdp, beforeMediaLine, candidateLine, afterMediaLine),
       `Expect candidate line to be found between media lines ${beforeMediaLine} and ${afterMediaLine}`);
   }
 
   // Check that a candidate line is found after the second media line
   // i.e. it belongs to the second media stream
-  function assert_candidate_line_after(sdp, beforeMediaLine, candidateLine) {
+  function is_candidate_line_after(sdp, beforeMediaLine, candidateLine) {
     const line1 = escapeRegExp(beforeMediaLine);
     const line2 = escapeRegExp(candidateLine);
 
     const regex = new RegExp(`${line1}[^]+${line2}`);
 
-    assert_true(regex.test(sdp),
-      `Expect candidate line to be found after media line ${beforeMediaLine}`);
+    return regex.test(sdp);
   }
 
-  // Reject because WebIDL for addIceCandidate does not allow null argument
-  // null can be accidentally passed from onicecandidate event handler
-  // when null is used to indicate end of candidate
-  promise_test(t => {
-    const pc = new RTCPeerConnection();
-
-    t.add_cleanup(() => pc.close());
-
-    return pc.setRemoteDescription(sessionDesc)
-    .then(() =>
-      promise_rejects(t, new TypeError(),
-        pc.addIceCandidate(null)));
-  }, 'Add null candidate should reject with TypeError');
+  function assert_candidate_line_after(sdp, beforeMediaLine, candidateLine) {
+    assert_true(is_candidate_line_after(sdp, beforeMediaLine, candidateLine),
+      `Expect candidate line to be found after media line ${beforeMediaLine}`);
+  }
 
   /*
     4.4.2.  addIceCandidate
@@ -147,6 +140,75 @@
   /*
     Success cases
    */
+
+  // All of these should work, because all of these end up being equivalent to the
+  // same thing; an end-of-candidates signal for all levels/mids/ufrags.
+  [
+    // This is just the default. Everything else here is equivalent to this.
+    {
+      candidate: '',
+      sdpMid: null,
+      sdpMLineIndex: null,
+      usernameFragment: undefined
+    },
+    // The arg is optional, so when passing undefined we'll just get the default
+    undefined,
+    // The arg is optional, but not nullable, so we get the default again
+    null,
+    // Members in the dictionary take their default values
+    {}
+  ].forEach(init => promise_test(async t => {
+    const pc = new RTCPeerConnection();
+
+    t.add_cleanup(() => pc.close());
+
+    await pc.setRemoteDescription(sessionDesc);
+    await pc.addIceCandidate();
+    assert_candidate_line_between(pc.remoteDescription.sdp,
+      mediaLine1, endOfCandidateLine, mediaLine2);
+    assert_candidate_line_after(pc.remoteDescription.sdp,
+      mediaLine2, endOfCandidateLine);
+  }, `addIceCandidate(${JSON.stringify(init)}) should work, and add a=end-of-candidates to both m-sections`));
+
+  promise_test(async t => {
+    const pc = new RTCPeerConnection();
+
+    t.add_cleanup(() => pc.close());
+
+    await pc.setRemoteDescription(sessionDesc);
+    await pc.addIceCandidate({usernameFragment: usernameFragment1});
+    assert_candidate_line_between(pc.remoteDescription.sdp,
+      mediaLine1, endOfCandidateLine, mediaLine2);
+    assert_false(is_candidate_line_after(pc.remoteDescription.sdp,
+      mediaLine2, endOfCandidateLine));
+  }, 'addIceCandidate({usernameFragment: usernameFragment1}) should work, and add a=end-of-candidates to the first m-section');
+
+  promise_test(async t => {
+    const pc = new RTCPeerConnection();
+
+    t.add_cleanup(() => pc.close());
+
+    await pc.setRemoteDescription(sessionDesc);
+    await pc.addIceCandidate({usernameFragment: usernameFragment2});
+    assert_false(is_candidate_line_between(pc.remoteDescription.sdp,
+      mediaLine1, endOfCandidateLine, mediaLine2));
+    assert_true(is_candidate_line_after(pc.remoteDescription.sdp,
+      mediaLine2, endOfCandidateLine));
+  }, 'addIceCandidate({usernameFragment: usernameFragment2}) should work, and add a=end-of-candidates to the first m-section');
+
+  promise_test(async t => {
+    const pc = new RTCPeerConnection();
+
+    t.add_cleanup(() => pc.close());
+
+    await pc.setRemoteDescription(sessionDesc);
+    await pc.addIceCandidate({usernameFragment: "no such ufrag"});
+    assert_false(is_candidate_line_between(pc.remoteDescription.sdp,
+      mediaLine1, endOfCandidateLine, mediaLine2));
+    assert_false(is_candidate_line_after(pc.remoteDescription.sdp,
+      mediaLine2, endOfCandidateLine));
+  }, 'addIceCandidate({usernameFragment: "no such ufrag"}) should work, but not add a=end-of-candidates');
+
   promise_test(t => {
     const pc = new RTCPeerConnection();
 
@@ -378,33 +440,6 @@
         })));
   }, 'Add candidate with invalid candidate string and both sdpMid and sdpMLineIndex null should reject with TypeError');
 
-  promise_test(t => {
-    const pc = new RTCPeerConnection();
-
-    t.add_cleanup(() => pc.close());
-
-    return pc.setRemoteDescription(sessionDesc)
-    .then(() =>
-      promise_rejects(t, new TypeError(),
-        pc.addIceCandidate({})));
-  }, 'Add candidate with empty dict should reject with TypeError');
-
-  promise_test(t => {
-    const pc = new RTCPeerConnection();
-
-    t.add_cleanup(() => pc.close());
-
-    return pc.setRemoteDescription(sessionDesc)
-    .then(() =>
-      promise_rejects(t, new TypeError(),
-        pc.addIceCandidate({
-          candidate: '',
-          sdpMid: null,
-          sdpMLineIndex: null,
-          usernameFragment: undefined
-        })));
-  }, 'Add candidate with manually filled default values should reject with TypeError');
-
   /*
     4.4.2.  addIceCandidate
       4.3.  If candidate.sdpMid is not null, run the following steps:
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt
index 96e7bba..8958c51 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt
@@ -2,7 +2,7 @@
 PASS Initial iceConnectionState should be new
 PASS Closing the connection should set iceConnectionState to closed
 PASS connection with one data channel should eventually have connected or completed connection state
-FAIL connection with one data channel should eventually have connected connection state Cannot read property 'state' of undefined
+FAIL connection with one data channel should eventually have connected connection state assert_equals: Expect ICE transport to be in checking state when iceConnectionState is checking expected "checking" but got "closed"
 PASS ICE can connect in a recvonly usecase
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html
index 8acabf4..768da23 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html
@@ -148,21 +148,21 @@
       const { iceConnectionState } = pc1;
 
       if(iceConnectionState === 'checking') {
-        const iceTransport = pc1.sctp.transport.transport;
+        const iceTransport = pc1.sctp.transport.iceTransport;
 
         assert_equals(iceTransport.state, 'checking',
           'Expect ICE transport to be in checking state when' +
           ' iceConnectionState is checking');
 
       } else if(iceConnectionState === 'connected') {
-        const iceTransport = pc1.sctp.transport.transport;
+        const iceTransport = pc1.sctp.transport.iceTransport;
 
         assert_equals(iceTransport.state, 'connected',
           'Expect ICE transport to be in connected state when' +
           ' iceConnectionState is connected');
 
       } else if(iceConnectionState === 'completed') {
-        const iceTransport = pc1.sctp.transport.transport;
+        const iceTransport = pc1.sctp.transport.iceTransport;
 
         assert_equals(iceTransport.state, 'completed',
           'Expect ICE transport to be in connected state when' +
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceGatheringState-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceGatheringState-expected.txt
index 91d147a..8011e7e 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceGatheringState-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceGatheringState-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 PASS Initial iceGatheringState should be new
 PASS iceGatheringState should eventually become complete after setLocalDescription
-FAIL connection with one data channel should eventually have connected connection state Cannot read property 'gatheringState' of undefined
+FAIL connection with one data channel should eventually have connected connection state assert_equals: Expect ICE transport to be in checking gatheringState when iceGatheringState is checking expected (string) "gathering" but got (undefined) undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceGatheringState.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceGatheringState.html
index e6d8d06..e170e4a 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceGatheringState.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceGatheringState.html
@@ -108,13 +108,13 @@
       const { iceGatheringState } = pc2;
 
       if(iceGatheringState === 'gathering') {
-        const iceTransport = pc2.sctp.transport.transport;
+        const iceTransport = pc2.sctp.transport.iceTransport;
 
         assert_equals(iceTransport.gatheringState, 'gathering',
           'Expect ICE transport to be in checking gatheringState when iceGatheringState is checking');
 
       } else if(iceGatheringState === 'complete') {
-        const iceTransport = pc2.sctp.transport.transport;
+        const iceTransport = pc2.sctp.transport.iceTransport;
 
         assert_equals(iceTransport.gatheringState, 'complete',
           'Expect ICE transport to be in complete gatheringState when iceGatheringState is complete');
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver-stop-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver-stop-expected.txt
index aac18318..80df5031 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver-stop-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver-stop-expected.txt
@@ -1,7 +1,7 @@
 This is a testharness.js-based test.
 FAIL A transceiver added and stopped before the initial offer generation should not trigger an offer m-section generation promise_test: Unhandled rejection with value: object "TypeError: pc1.getTransceivers(...)[0].stop is not a function"
 FAIL During renegotiation, adding and stopping a transceiver should not trigger a renegotiated offer m-section generation promise_test: Unhandled rejection with value: object "TypeError: pc1.getTransceivers(...)[0].stop is not a function"
-FAIL A stopped sendonly transceiver should generate an inactive m-section in the offer promise_test: Unhandled rejection with value: object "TypeError: pc1.getTransceivers(...)[0].stop is not a function"
+FAIL A stopped sendonly transceiver should generate a sendonly m-section in the offer promise_test: Unhandled rejection with value: object "TypeError: pc1.getTransceivers(...)[0].stop is not a function"
 FAIL A stopped inactive transceiver should generate an inactive m-section in the offer promise_test: Unhandled rejection with value: object "TypeError: pc1.getTransceivers(...)[0].stop is not a function"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver-stop.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver-stop.html
index b45e03bd..4f57dc7b 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver-stop.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver-stop.html
@@ -60,7 +60,7 @@
     const offer = await pc1.createOffer();
 
     assert_true(offer.sdp.includes("a=sendonly"), "The audio m-section should be sendonly");
-}, "A stopped sendonly transceiver should generate an inactive m-section in the offer");
+}, "A stopped sendonly transceiver should generate a sendonly m-section in the offer");
 
 promise_test(async (t)=> {
     const pc1 = new RTCPeerConnection();
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 be57dd0e..4c6d5fc 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 506 tests; 421 PASS, 85 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 506 tests; 419 PASS, 87 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS Test driver for asyncInitCertificate
 PASS Test driver for asyncInitTransports
@@ -372,10 +372,10 @@
 PASS RTCTrackEvent interface: initTrackEvent() must inherit property "track" with the proper type
 PASS RTCTrackEvent interface: initTrackEvent() must inherit property "streams" with the proper type
 PASS RTCTrackEvent interface: initTrackEvent() must inherit property "transceiver" with the proper type
-PASS RTCSctpTransport interface: existence and properties of interface object
+FAIL RTCSctpTransport interface: existence and properties of interface object assert_equals: prototype of RTCSctpTransport is not EventTarget expected function "function EventTarget() { [native code] }" but got function "function () { [native code] }"
 PASS RTCSctpTransport interface object length
 PASS RTCSctpTransport interface object name
-PASS RTCSctpTransport interface: existence and properties of interface prototype object
+FAIL RTCSctpTransport interface: existence and properties of interface prototype object assert_equals: prototype of RTCSctpTransport.prototype is not EventTarget.prototype expected object "[object EventTarget]" but got object "[object Object]"
 PASS RTCSctpTransport interface: existence and properties of interface prototype object's "constructor" property
 PASS RTCSctpTransport interface: existence and properties of interface prototype object's @@unscopables property
 PASS RTCSctpTransport interface: attribute transport
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/date-picker-ax.html b/third_party/blink/web_tests/fast/forms/calendar-picker/date-picker-ax.html
index 7063a0a..8df3af5 100644
--- a/third_party/blink/web_tests/fast/forms/calendar-picker/date-picker-ax.html
+++ b/third_party/blink/web_tests/fast/forms/calendar-picker/date-picker-ax.html
@@ -7,8 +7,7 @@
   <script src="resources/calendar-picker-common.js"></script>
 </head>
 <body>
-<p id="description"></p>
-<div id="console"></div>
+
 <input type="date" id="date1" value="2000-01-02">
 
 <script>
@@ -18,10 +17,10 @@
 
     accessibilityController.setNotificationListener(function(axnode, type) {
         if (type == 'Focus') {
-            console.log('Focused: ' + escapeHTML(accessibilityController.focusedElement.name.replace(/,/g, '')));
+            console.log('Focused: ' + accessibilityController.focusedElement.name.replace(/,/g, ''));
         } else if (type == 'MarkDirty') {
             if (++markDirtyCounter == 2) {
-                testButtonDescription();
+                setTimeout(testButtonDescription, 0);
             } else if (markDirtyCounter == 3) {
                 // Highlight 2000-02 in the month popup.
                 setTimeout(function() { eventSender.keyDown('ArrowRight'); }, 0);
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-ax-expected.txt b/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-ax-expected.txt
deleted file mode 100644
index c462e39..0000000
--- a/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-ax-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Tests if typing an arrow key dispatches |Focus| and |MarkDirty| a11y events.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-Focused
-Focused
-PASS Received MarkDirty
-PASS Received MarkDirty
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-ax.html b/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-ax.html
index 13a8921..e2f9fbad 100644
--- a/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-ax.html
+++ b/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-ax.html
@@ -1,32 +1,39 @@
 <!DOCTYPE html>
 <html>
+<head>
+  <script src="../../../resources/testharness.js"></script>
+  <script src="../../../resources/testharnessreport.js"></script>
+  <script src="../../forms/resources/picker-common.js"></script>
+  <script src="resources/calendar-picker-common.js"></script>
+</head>
+
 <body>
-<script src="../../../resources/js-test.js"></script>
-<script src="../../forms/resources/picker-common.js"></script>
-<script src="resources/calendar-picker-common.js"></script>
-<p id="description"></p>
-<div id="console"></div>
 <input type="month" id="month1" value="2000-01">
 
 <script>
-description('Tests if typing an arrow key dispatches |Focus| and |MarkDirty| a11y events.');
+async_test((t) => {
+    var markDirtyCounter = 0;
+    var focusCounter = 0;
+    accessibilityController.setNotificationListener(function(axnode, type) {
+        if (type == 'Focus') {
+            console.log('Focused: ' + accessibilityController.focusedElement.name.replace(/,/g, ''));
+            focusCounter++;
+        } else if (type == 'MarkDirty') {
+            console.log('Received MarkDirty');
+            markDirtyCounter++;
+            if (focusCounter == 2 && markDirtyCounter == 2) {
+                t.done();
+            }
+        }
+    });
 
-accessibilityController.setNotificationListener(function(axnode, type) {
-    if (type == 'Focus') {
-        debug('Focused');
-    } else if (type == 'MarkDirty') {
-        testPassed('Received MarkDirty');
-        if (++markDirtyCounter == 2)
-            finishJSTest();
+    var month1 = document.getElementById('month1');
+    function test1() {
+        eventSender.keyDown('ArrowDown');
     }
-});
-var markDirtyCounter = 0;
-var month1 = document.getElementById('month1');
-openPicker(month1, test1);
 
-function test1() {
-    eventSender.keyDown('ArrowRight');
-}
+    openPicker(month1, test1);
+}, 'Tests if typing an arrow key dispatches |Focus| and |MarkDirty| a11y events.');
 
 </script>
 </body>
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax-expected.txt b/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax-expected.txt
deleted file mode 100644
index c462e39..0000000
--- a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Tests if typing an arrow key dispatches |Focus| and |MarkDirty| a11y events.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-Focused
-Focused
-PASS Received MarkDirty
-PASS Received MarkDirty
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax.html b/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax.html
index aeef1f7..1b3172f 100644
--- a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax.html
+++ b/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax.html
@@ -1,32 +1,41 @@
 <!DOCTYPE html>
 <html>
+<head>
+  <script src="../../../resources/testharness.js"></script>
+  <script src="../../../resources/testharnessreport.js"></script>
+  <script src="../../forms/resources/picker-common.js"></script>
+  <script src="resources/calendar-picker-common.js"></script>
+</head>
+
 <body>
-<script src="../../../resources/js-test.js"></script>
-<script src="../../forms/resources/picker-common.js"></script>
-<script src="resources/calendar-picker-common.js"></script>
-<p id="description"></p>
-<div id="console"></div>
 <input type="week" id="week1" value="2000-W13">
 
 <script>
-description('Tests if typing an arrow key dispatches |Focus| and |MarkDirty| a11y events.');
+async_test((t) => {
+    var markDirtyCounter = 0;
+    var focusCounter = 0;
+    accessibilityController.setNotificationListener(function(axnode, type) {
+        if (type == 'Focus') {
+            console.log('Focused: ' + accessibilityController.focusedElement.name.replace(/,/g, ''));
+            focusCounter++;
+        } else if (type == 'MarkDirty') {
+            console.log('Received MarkDirty');
+            markDirtyCounter++;
+            if (focusCounter == 2 && markDirtyCounter == 2) {
+                t.done();
+            }
+        }
+    });
 
-accessibilityController.setNotificationListener(function(axnode, type) {
-    if (type == 'Focus') {
-        debug('Focused');
-    } else if (type == 'MarkDirty') {
-        testPassed('Received MarkDirty');
-        if (++markDirtyCounter == 2)
-            finishJSTest();
+    var week1 = document.getElementById('week1');
+    function test1() {
+        eventSender.keyDown('ArrowDown');
     }
-});
-var markDirtyCounter = 0;
-var week1 = document.getElementById('week1');
-openPicker(week1, test1);
 
-function test1() {
-    eventSender.keyDown('ArrowDown');
-}
+    openPicker(week1, test1);
+}, 'Tests if typing an arrow key dispatches |Focus| and |MarkDirty| a11y events.');
+
+
 
 </script>
 </body>
diff --git a/third_party/blink/web_tests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification.html b/third_party/blink/web_tests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification.html
index 7026b596..255b11e 100644
--- a/third_party/blink/web_tests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/blink/web_tests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification.html
@@ -13,12 +13,12 @@
         [ "Focus", "Month", "10" ],
         [ "Focus", "Day", "09" ],
         [ "Focus", "Year", "2012" ],
+        [ "ValueChanged", "Day", "04" ],
+        [ "ValueChanged", "Day", "04" ],
+        [ "ValueChanged", "Year", "2013" ],
+        [ "ValueChanged", "Year", "2013" ],
         [ "Focus", "Hours", "12" ],
         [ "Focus", "Minutes", "34" ],
-        [ "ValueChanged", "Day", "04" ],
-        [ "ValueChanged", "Day", "04" ],
-        [ "ValueChanged", "Year", "2013" ],
-        [ "ValueChanged", "Year", "2013" ],
         [ "ValueChanged", "Hours", "02" ],
         [ "ValueChanged", "Hours", "02" ],
         [ "ValueChanged", "Minutes", "33" ],
@@ -29,8 +29,6 @@
         t.step_func((element, notification) => {
             if (notification == 'Focus' || notification == 'ValueChanged') {
                 var next_expectation = expected.shift();
-                console.log('next_expectation: ' + JSON.stringify(next_expectation));
-                console.log('actual: [' + notification + ', ' + element.name.trim() + ', ' + element.valueDescription.substr(20) + ']');
                 assert_equals(notification, next_expectation[0]);
                 assert_equals(element.name.trim(), next_expectation[1]);
                 assert_equals(element.valueDescription.substr(20), next_expectation[2]);
diff --git a/third_party/blink/web_tests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification.html b/third_party/blink/web_tests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification.html
index 9d99741..4849cb3 100644
--- a/third_party/blink/web_tests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/blink/web_tests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification.html
@@ -12,6 +12,8 @@
     var expected = [
         [ "Focus", "Month", "October" ],
         [ "Focus", "Year", "2012" ],
+        [ "ValueChanged", "Year", "0004" ],
+        [ "ValueChanged", "Year", "0004" ],
         [ "ValueChanged", "Year", "0005" ],
         [ "ValueChanged", "Year", "0005" ] ];
 
@@ -20,8 +22,6 @@
         t.step_func((element, notification) => {
             if (notification == 'Focus' || notification == 'ValueChanged') {
                 var next_expectation = expected.shift();
-                console.log('next_expectation: ' + JSON.stringify(next_expectation));
-                console.log('actual: [' + notification + ', ' + element.name.trim() + ', ' + element.valueDescription.substr(20) + ']');
                 assert_equals(notification, next_expectation[0]);
                 assert_equals(element.name.trim(), next_expectation[1]);
                 assert_equals(element.valueDescription.substr(20), next_expectation[2]);
diff --git a/third_party/blink/web_tests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html b/third_party/blink/web_tests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html
index 7ac02605..59b833e8 100644
--- a/third_party/blink/web_tests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/blink/web_tests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html
@@ -12,6 +12,8 @@
     var expected = [
         [ "Focus", "Hours", "12" ],
         [ "Focus", "Minutes", "34" ],
+        [ "ValueChanged", "Minutes", "04" ],
+        [ "ValueChanged", "Minutes", "04" ],
         [ "ValueChanged", "Minutes", "05" ],
         [ "ValueChanged", "Minutes", "05" ] ];
 
@@ -19,8 +21,6 @@
         t.step_func((element, notification) => {
             if (notification == 'Focus' || notification == 'ValueChanged') {
                 var next_expectation = expected.shift();
-                console.log('next_expectation: ' + JSON.stringify(next_expectation));
-                console.log('actual: [' + notification + ', ' + element.name.trim() + ', ' + element.valueDescription.substr(20) + ']');
                 assert_equals(notification, next_expectation[0]);
                 assert_equals(element.name.trim(), next_expectation[1]);
                 assert_equals(element.valueDescription.substr(20), next_expectation[2]);
diff --git a/third_party/blink/web_tests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html b/third_party/blink/web_tests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html
index 9b8280d..a72e6da 100644
--- a/third_party/blink/web_tests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/blink/web_tests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html
@@ -12,6 +12,8 @@
     var expected = [
         [ "Focus", "Week", "10" ],
         [ "Focus", "Year", "2012" ],
+        [ "ValueChanged", "Year", "0004" ],
+        [ "ValueChanged", "Year", "0004" ],
         [ "ValueChanged", "Year", "0005" ],
         [ "ValueChanged", "Year", "0005" ] ];
 
@@ -19,8 +21,6 @@
         t.step_func((element, notification) => {
             if (notification == 'Focus' || notification == 'ValueChanged') {
                 var next_expectation = expected.shift();
-                console.log('next_expectation: ' + JSON.stringify(next_expectation));
-                console.log('actual: [' + notification + ', ' + element.name.trim() + ', ' + element.valueDescription.substr(20) + ']');
                 assert_equals(notification, next_expectation[0]);
                 assert_equals(element.name.trim(), next_expectation[1]);
                 assert_equals(element.valueDescription.substr(20), next_expectation[2]);
diff --git a/third_party/blink/web_tests/html5lib/resources/runner.js b/third_party/blink/web_tests/html5lib/resources/runner.js
index dc35e4e..3052187 100644
--- a/third_party/blink/web_tests/html5lib/resources/runner.js
+++ b/third_party/blink/web_tests/html5lib/resources/runner.js
@@ -190,7 +190,7 @@
             }
             process_result(input, iframe.contentWindow.document, expected);
         }
-        iframe.src = "data:text/html," + encodeURIComponent(input);
+        iframe.srcdoc = input;
     }
 }
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/accessibility/edit-aria-attributes.js b/third_party/blink/web_tests/http/tests/devtools/elements/accessibility/edit-aria-attributes.js
index ec999f70c..41bc4b7 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/accessibility/edit-aria-attributes.js
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/accessibility/edit-aria-attributes.js
@@ -34,9 +34,14 @@
     treeElement._startEditing();
     treeElement._prompt._element.textContent = 'radio';
     treeElement._prompt._element.dispatchEvent(TestRunner.createKeyEvent('Enter'));
-    self.runtime.sharedInstance(Accessibility.AccessibilitySidebarView).doUpdate().then(() => {
-      postRoleChange();
-    });
+    // Give the document lifecycle a chance to run before updating the view.
+    window.setTimeout(() => {
+      self.runtime.sharedInstance(Accessibility.AccessibilitySidebarView)
+          .doUpdate()
+          .then(() => {
+            postRoleChange();
+          });
+    }, 0);
   }
 
   function postRoleChange() {
diff --git a/third_party/blink/web_tests/platform/android/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification-expected.txt b/third_party/blink/web_tests/platform/android/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification-expected.txt
deleted file mode 100644
index b13f6d6b..0000000
--- a/third_party/blink/web_tests/platform/android/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This test checks value changed accessibility notifications.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-Focus =AXValueDescription: 
-
-PASS successfullyParsed is true
-
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver-stop-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver-stop-expected.txt
index 908d6c15..6fff943 100644
--- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver-stop-expected.txt
+++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver-stop-expected.txt
@@ -1,7 +1,7 @@
 This is a testharness.js-based test.
 FAIL A transceiver added and stopped before the initial offer generation should not trigger an offer m-section generation promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
 FAIL During renegotiation, adding and stopping a transceiver should not trigger a renegotiated offer m-section generation promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
-FAIL A stopped sendonly transceiver should generate an inactive m-section in the offer promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
+FAIL A stopped sendonly transceiver should generate a sendonly m-section in the offer promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
 FAIL A stopped inactive transceiver should generate an inactive m-section in the offer promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
 Harness: the test ran to completion.
 
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 3ecee00..cd9d0e3c 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 506 tests; 363 PASS, 143 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 506 tests; 361 PASS, 145 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
@@ -372,10 +372,10 @@
 FAIL RTCTrackEvent interface: initTrackEvent() must inherit property "track" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
 FAIL RTCTrackEvent interface: initTrackEvent() must inherit property "streams" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
 FAIL RTCTrackEvent interface: initTrackEvent() must inherit property "transceiver" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
-PASS RTCSctpTransport interface: existence and properties of interface object
+FAIL RTCSctpTransport interface: existence and properties of interface object assert_equals: prototype of RTCSctpTransport is not EventTarget expected function "function EventTarget() { [native code] }" but got function "function () { [native code] }"
 PASS RTCSctpTransport interface object length
 PASS RTCSctpTransport interface object name
-PASS RTCSctpTransport interface: existence and properties of interface prototype object
+FAIL RTCSctpTransport interface: existence and properties of interface prototype object assert_equals: prototype of RTCSctpTransport.prototype is not EventTarget.prototype expected object "[object EventTarget]" but got object "[object Object]"
 PASS RTCSctpTransport interface: existence and properties of interface prototype object's "constructor" property
 PASS RTCSctpTransport interface: existence and properties of interface prototype object's @@unscopables property
 PASS RTCSctpTransport interface: attribute transport
diff --git a/third_party/crc32c/OWNERS b/third_party/crc32c/OWNERS
index c3a7b7a..a3f1724 100644
--- a/third_party/crc32c/OWNERS
+++ b/third_party/crc32c/OWNERS
@@ -2,7 +2,7 @@
 pwnall@chromium.org
 
 # Secondary:
-cmumford@chromium.org
+cmumford@google.com
 jsbell@chromium.org
 
 # TEAM: storage-dev@chromium.org
diff --git a/third_party/leveldatabase/OWNERS b/third_party/leveldatabase/OWNERS
index c3a7b7a..a3f1724 100644
--- a/third_party/leveldatabase/OWNERS
+++ b/third_party/leveldatabase/OWNERS
@@ -2,7 +2,7 @@
 pwnall@chromium.org
 
 # Secondary:
-cmumford@chromium.org
+cmumford@google.com
 jsbell@chromium.org
 
 # TEAM: storage-dev@chromium.org
diff --git a/third_party/snappy/OWNERS b/third_party/snappy/OWNERS
index fdee416..59701a12 100644
--- a/third_party/snappy/OWNERS
+++ b/third_party/snappy/OWNERS
@@ -2,7 +2,7 @@
 pwnall@chromium.org
 
 # Secondary
-cmumford@chromium.org
+cmumford@google.com
 jsbell@chromium.org
 
 # TEAM: storage-dev@chromium.org
diff --git a/third_party/sqlite/OWNERS b/third_party/sqlite/OWNERS
index b542429..279a3cf4 100644
--- a/third_party/sqlite/OWNERS
+++ b/third_party/sqlite/OWNERS
@@ -2,7 +2,7 @@
 pwnall@chromium.org
 
 # Secondary:
-cmumford@chromium.org
+cmumford@google.com
 
 # TEAM: storage-dev@chromium.org
 # COMPONENT: Internals>Storage
diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c
index 62273a1..39e0cd70 100644
--- a/third_party/sqlite/amalgamation/sqlite3.c
+++ b/third_party/sqlite/amalgamation/sqlite3.c
@@ -107980,7 +107980,8 @@
    && sortOrder!=SQLITE_SO_DESC
   ){
     if( IN_RENAME_OBJECT && pList ){
-      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr);
+      Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr);
+      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr);
     }
     pTab->iPKey = iCol;
     pTab->keyConf = (u8)onError;
@@ -221438,7 +221439,7 @@
 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
 
 /************** End of stmt.c ************************************************/
-#if __LINE__!=221441
+#if __LINE__!=221442
 #undef SQLITE_SOURCE_ID
 #define SQLITE_SOURCE_ID      "2019-02-25 16:06:06 bd49a8271d650fa89e446b42e513b595a717b9212c91dd384aab871fc1d0alt2"
 #endif
diff --git a/third_party/sqlite/patches/0001-Virtual-table-supporting-recovery-of-corrupted-datab.patch b/third_party/sqlite/patches/0001-Virtual-table-supporting-recovery-of-corrupted-datab.patch
index fb110f8..776fb3a 100644
--- a/third_party/sqlite/patches/0001-Virtual-table-supporting-recovery-of-corrupted-datab.patch
+++ b/third_party/sqlite/patches/0001-Virtual-table-supporting-recovery-of-corrupted-datab.patch
@@ -1,7 +1,8 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Scott Hess <shess@chromium.org>
 Date: Sat, 20 Jul 2013 11:42:21 -0700
-Subject: [PATCH 1/9] Virtual table supporting recovery of corrupted databases.
+Subject: [PATCH 01/10] Virtual table supporting recovery of corrupted
+ databases.
 
 "recover" implements a virtual table which uses the SQLite pager layer
 to read table pages and pull out the data which is structurally sound
@@ -3900,5 +3901,5 @@
 +
 +finish_test
 -- 
-2.20.1
+2.21.0.225.g810b269d1ac-goog
 
diff --git a/third_party/sqlite/patches/0002-Custom-shell.c-helpers-to-load-Chromium-s-ICU-data.patch b/third_party/sqlite/patches/0002-Custom-shell.c-helpers-to-load-Chromium-s-ICU-data.patch
index 748b596..74d0dcb 100644
--- a/third_party/sqlite/patches/0002-Custom-shell.c-helpers-to-load-Chromium-s-ICU-data.patch
+++ b/third_party/sqlite/patches/0002-Custom-shell.c-helpers-to-load-Chromium-s-ICU-data.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: "tc@google.com" <tc@google.com>
 Date: Tue, 6 Jan 2009 22:39:41 +0000
-Subject: [PATCH 2/9] Custom shell.c helpers to load Chromium's ICU data.
+Subject: [PATCH 02/10] Custom shell.c helpers to load Chromium's ICU data.
 
 History uses fts3 with an icu-based segmenter.  These changes allow building a
 sqlite3 binary for Linux or Windows which can read those files.
@@ -141,5 +141,5 @@
 +  return 1;
 +}
 -- 
-2.20.1
+2.21.0.225.g810b269d1ac-goog
 
diff --git a/third_party/sqlite/patches/0003-fts3-Disable-fts3_tokenizer-and-fts4.patch b/third_party/sqlite/patches/0003-fts3-Disable-fts3_tokenizer-and-fts4.patch
index 7b59fb07..b34e334c 100644
--- a/third_party/sqlite/patches/0003-fts3-Disable-fts3_tokenizer-and-fts4.patch
+++ b/third_party/sqlite/patches/0003-fts3-Disable-fts3_tokenizer-and-fts4.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Scott Hess <shess@chromium.org>
 Date: Tue, 16 Dec 2014 13:02:27 -0800
-Subject: [PATCH 3/9] [fts3] Disable fts3_tokenizer and fts4.
+Subject: [PATCH 03/10] [fts3] Disable fts3_tokenizer and fts4.
 
 fts3_tokenizer allows a SQLite user to specify a pointer to call as a
 function, which has obvious sercurity implications.  Disable fts4 until
@@ -56,5 +56,5 @@
    }
  
 -- 
-2.20.1
+2.21.0.225.g810b269d1ac-goog
 
diff --git a/third_party/sqlite/patches/0004-Fix-compilation-with-SQLITE_OMIT_WINDOWFUNC.patch b/third_party/sqlite/patches/0004-Fix-compilation-with-SQLITE_OMIT_WINDOWFUNC.patch
index e1b0940..e5dcd3d 100644
--- a/third_party/sqlite/patches/0004-Fix-compilation-with-SQLITE_OMIT_WINDOWFUNC.patch
+++ b/third_party/sqlite/patches/0004-Fix-compilation-with-SQLITE_OMIT_WINDOWFUNC.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Victor Costan <pwnall@chromium.org>
 Date: Sun, 10 Feb 2019 13:12:57 -0800
-Subject: [PATCH 4/9] Fix compilation with SQLITE_OMIT_WINDOWFUNC.
+Subject: [PATCH 04/10] Fix compilation with SQLITE_OMIT_WINDOWFUNC.
 
 ---
  third_party/sqlite/src/src/resolve.c | 2 ++
@@ -28,5 +28,5 @@
      /* If this is part of a compound SELECT, check that it has the right
      ** number of expressions in the select list. */
 -- 
-2.20.1
+2.21.0.225.g810b269d1ac-goog
 
diff --git a/third_party/sqlite/patches/0005-Fix-dbfuzz2.c-compilation-errors-on-Windows.patch b/third_party/sqlite/patches/0005-Fix-dbfuzz2.c-compilation-errors-on-Windows.patch
index dd8c0a16..5b9029f 100644
--- a/third_party/sqlite/patches/0005-Fix-dbfuzz2.c-compilation-errors-on-Windows.patch
+++ b/third_party/sqlite/patches/0005-Fix-dbfuzz2.c-compilation-errors-on-Windows.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Victor Costan <pwnall@chromium.org>
 Date: Sun, 10 Feb 2019 15:18:43 -0800
-Subject: [PATCH 5/9] Fix dbfuzz2.c compilation errors on Windows.
+Subject: [PATCH 05/10] Fix dbfuzz2.c compilation errors on Windows.
 
 ---
  third_party/sqlite/src/test/dbfuzz2.c | 4 ++++
@@ -39,5 +39,5 @@
      argv[j++] = argv[i];
    }
 -- 
-2.20.1
+2.21.0.225.g810b269d1ac-goog
 
diff --git a/third_party/sqlite/patches/0006-Fix-Heap-buffer-overflow-in-vdbeRecordCompareInt.patch b/third_party/sqlite/patches/0006-Fix-Heap-buffer-overflow-in-vdbeRecordCompareInt.patch
index 422e603..ba8505c 100644
--- a/third_party/sqlite/patches/0006-Fix-Heap-buffer-overflow-in-vdbeRecordCompareInt.patch
+++ b/third_party/sqlite/patches/0006-Fix-Heap-buffer-overflow-in-vdbeRecordCompareInt.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Darwin Huang <huangdarwin@chromium.org>
 Date: Tue, 5 Mar 2019 13:49:51 -0800
-Subject: [PATCH 6/9] Fix Heap-buffer-overflow in vdbeRecordCompareInt
+Subject: [PATCH 06/10] Fix Heap-buffer-overflow in vdbeRecordCompareInt
 
 This backports https://www.sqlite.org/src/info/c1ac00706bae45fe
 
@@ -24,5 +24,5 @@
          }
          assert(
 -- 
-2.20.1
+2.21.0.225.g810b269d1ac-goog
 
diff --git a/third_party/sqlite/patches/0007-fix-heap-buffer-overflow-in-cellsizeptr.patch b/third_party/sqlite/patches/0007-fix-heap-buffer-overflow-in-cellsizeptr.patch
index f80f372..e571d36 100644
--- a/third_party/sqlite/patches/0007-fix-heap-buffer-overflow-in-cellsizeptr.patch
+++ b/third_party/sqlite/patches/0007-fix-heap-buffer-overflow-in-cellsizeptr.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Darwin Huang <huangdarwin@chromium.org>
 Date: Tue, 5 Mar 2019 14:13:19 -0800
-Subject: [PATCH 7/9] fix heap-buffer-overflow in cellsizeptr
+Subject: [PATCH 07/10] fix heap-buffer-overflow in cellsizeptr
 
 This backports https://www.sqlite.org/src/info/e7aca0714bc475e0
 
@@ -32,5 +32,5 @@
  
      if( rc==SQLITE_OK ){
 -- 
-2.20.1
+2.21.0.225.g810b269d1ac-goog
 
diff --git a/third_party/sqlite/patches/0008-fix-integer-overflow-in-checkList.patch b/third_party/sqlite/patches/0008-fix-integer-overflow-in-checkList.patch
index 3ed874b..baa9610 100644
--- a/third_party/sqlite/patches/0008-fix-integer-overflow-in-checkList.patch
+++ b/third_party/sqlite/patches/0008-fix-integer-overflow-in-checkList.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Darwin Huang <huangdarwin@chromium.org>
 Date: Tue, 5 Mar 2019 14:17:05 -0800
-Subject: [PATCH 8/9] fix integer overflow in checkList
+Subject: [PATCH 08/10] fix integer overflow in checkList
 
 This backports https://www.sqlite.org/src/info/05b87e0755638d31
 
@@ -37,5 +37,5 @@
        assert( pc + info.nSize - 4 <= usableSize );
        nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4);
 -- 
-2.20.1
+2.21.0.225.g810b269d1ac-goog
 
diff --git a/third_party/sqlite/patches/0009-Fix-Heap-use-after-free-in-releasePageNotNull.patch b/third_party/sqlite/patches/0009-Fix-Heap-use-after-free-in-releasePageNotNull.patch
index 998d3864..818524e 100644
--- a/third_party/sqlite/patches/0009-Fix-Heap-use-after-free-in-releasePageNotNull.patch
+++ b/third_party/sqlite/patches/0009-Fix-Heap-use-after-free-in-releasePageNotNull.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Darwin Huang <huangdarwin@chromium.org>
 Date: Tue, 12 Mar 2019 17:30:33 -0700
-Subject: [PATCH 9/9] Fix Heap-use-after-free in releasePageNotNull
+Subject: [PATCH 09/10] Fix Heap-use-after-free in releasePageNotNull
 
 This backports https://www.sqlite.org/src/info/b0d5cf40bba34e45
 
@@ -29,5 +29,5 @@
      if( pPager->tempFile ){
        /* Do not discard pages from an in-memory database since we might
 -- 
-2.20.1
+2.21.0.225.g810b269d1ac-goog
 
diff --git a/third_party/sqlite/patches/0010-Fix-dangling-pointer-dereference.patch b/third_party/sqlite/patches/0010-Fix-dangling-pointer-dereference.patch
new file mode 100644
index 0000000..9ff8dc9
--- /dev/null
+++ b/third_party/sqlite/patches/0010-Fix-dangling-pointer-dereference.patch
@@ -0,0 +1,66 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Darwin Huang <huangdarwin@chromium.org>
+Date: Thu, 21 Mar 2019 13:19:11 -0700
+Subject: [PATCH 10/10] Fix dangling pointer dereference
+
+This backports https://www.sqlite.org/src/info/b9e2393cf201e3fc
+
+Bug: 940205
+---
+ third_party/sqlite/src/src/build.c         |  3 ++-
+ third_party/sqlite/src/test/altertab3.test | 24 ++++++++++++++++++++++
+ 2 files changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/third_party/sqlite/src/src/build.c b/third_party/sqlite/src/src/build.c
+index e9371afd2b7d..3bf037258ce9 100644
+--- a/third_party/sqlite/src/src/build.c
++++ b/third_party/sqlite/src/src/build.c
+@@ -1400,7 +1400,8 @@ void sqlite3AddPrimaryKey(
+    && sortOrder!=SQLITE_SO_DESC
+   ){
+     if( IN_RENAME_OBJECT && pList ){
+-      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr);
++      Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr);
++      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr);
+     }
+     pTab->iPKey = iCol;
+     pTab->keyConf = (u8)onError;
+diff --git a/third_party/sqlite/src/test/altertab3.test b/third_party/sqlite/src/test/altertab3.test
+index de41637a9ec7..5db7bf843382 100644
+--- a/third_party/sqlite/src/test/altertab3.test
++++ b/third_party/sqlite/src/test/altertab3.test
+@@ -79,7 +79,31 @@ do_execsql_test 3.2 {
+   SELECT sql FROM sqlite_master WHERE name = 'v1'
+ } {{CREATE VIEW v1 AS SELECT * FROM t1 WHERE a=1 OR (bbb IN ())}}
+
++#-------------------------------------------------------------------------
++reset_db
++do_execsql_test 5.0 {
++  CREATE TABLE t1 (
++      c1 integer, c2, PRIMARY KEY(c1 collate rtrim),
++      UNIQUE(c2)
++  )
++}
++do_execsql_test 5.1 {
++  ALTER TABLE t1 RENAME c1 TO c3;
++}
+
++#-------------------------------------------------------------------------
++reset_db
++do_execsql_test 6.0 {
++  CREATE TEMPORARY TABLE Table0 (
++    Col0 INTEGER,
++    PRIMARY KEY(Col0 COLLATE RTRIM),
++    FOREIGN KEY (Col0) REFERENCES Table0
++  );
++}
++
++do_execsql_test 6.1 {
++  ALTER TABLE Table0 RENAME Col0 TO Col0;
++}
+
+ finish_test
+
+--
+2.21.0.225.g810b269d1ac-goog
+
diff --git a/third_party/sqlite/src/src/build.c b/third_party/sqlite/src/src/build.c
index e9371af..3bf03725 100644
--- a/third_party/sqlite/src/src/build.c
+++ b/third_party/sqlite/src/src/build.c
@@ -1400,7 +1400,8 @@
    && sortOrder!=SQLITE_SO_DESC
   ){
     if( IN_RENAME_OBJECT && pList ){
-      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr);
+      Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr);
+      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr);
     }
     pTab->iPKey = iCol;
     pTab->keyConf = (u8)onError;
diff --git a/third_party/sqlite/src/test/altertab3.test b/third_party/sqlite/src/test/altertab3.test
index de41637..5db7bf8 100644
--- a/third_party/sqlite/src/test/altertab3.test
+++ b/third_party/sqlite/src/test/altertab3.test
@@ -79,7 +79,31 @@
   SELECT sql FROM sqlite_master WHERE name = 'v1'
 } {{CREATE VIEW v1 AS SELECT * FROM t1 WHERE a=1 OR (bbb IN ())}}
 
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 5.0 {
+  CREATE TABLE t1 (
+      c1 integer, c2, PRIMARY KEY(c1 collate rtrim),
+      UNIQUE(c2)
+  )
+}
+do_execsql_test 5.1 {
+  ALTER TABLE t1 RENAME c1 TO c3;
+}
 
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 6.0 {
+  CREATE TEMPORARY TABLE Table0 (
+    Col0 INTEGER,
+    PRIMARY KEY(Col0 COLLATE RTRIM),
+    FOREIGN KEY (Col0) REFERENCES Table0
+  );
+}
+
+do_execsql_test 6.1 {
+  ALTER TABLE Table0 RENAME Col0 TO Col0;
+}
 
 finish_test
 
diff --git a/tools/perf/benchmarks/startup_mobile.py b/tools/perf/benchmarks/startup_mobile.py
index 5a232e9..76e017a0 100644
--- a/tools/perf/benchmarks/startup_mobile.py
+++ b/tools/perf/benchmarks/startup_mobile.py
@@ -8,6 +8,7 @@
 from core import perf_benchmark
 
 from telemetry.core import android_platform
+from telemetry.core import util as core_util
 from telemetry.internal.browser import browser_finder
 from telemetry.timeline import chrome_trace_category_filter
 from telemetry.util import wpr_modes
@@ -32,9 +33,12 @@
 #    shell> gn gen --args='use_goma=true target_os="android" target_cpu="arm" \
 #           is_debug=false is_official_build=true' gn_android/ReleaseOfficial
 #
-# 2. Build Monochrome:
+# 2.1. Build Monochrome:
 #    shell> autoninja -C gn_android/ReleaseOfficial monochrome_apk
 #
+# 2.2. Build the (pseudo) Maps PWA launcher (it will be auto-installed later):
+#    shell> autoninja -C gn_android/Release/ maps_go_webapk
+#
 # 3. Invoke Telemetry:
 #    shell> CHROMIUM_OUTPUT_DIR=gn_android/ReleaseOfficial \
 #               tools/perf/run_benchmark -v startup.mobile \
@@ -46,6 +50,13 @@
 # in expectations.config to avoid failures on Android versions below M. This
 # override is also used on internal bots. See: http://crbug.com/894744 and
 # http://crbug.com/849907.
+#
+# Recording a WPR archive and uploading it:
+# shell> CHROMIUM_OUTPUT_DIR=gn_android/Release tools/perf/record_wpr \
+#            mobile_startup_benchmark --browser=android-chrome \
+#            --also-run-disabled-tests --story-filter=maps_pwa:with_http_cache \
+#            --output-dir=/tmp/maps_pwa_output --upload
+# Note: "startup_mobile_benchmark" instead of "startup.mobile".
 
 _NUMBER_OF_ITERATIONS = 10
 _MAX_BATTERY_TEMP = 32
@@ -68,17 +79,28 @@
     # Allow using this shared state only on Android.
     assert isinstance(self.platform, android_platform.AndroidPlatform)
     self._finder_options.browser_options.browser_user_agent_type = 'mobile'
+    self._finder_options.browser_options.AppendExtraBrowserArgs(
+        '--skip-webapk-verification')
     self.platform.Initialize()
-    assert finder_options.browser_options.wpr_mode != wpr_modes.WPR_RECORD, (
-        'Recording WPR archives is not supported for this benchmark.')
+    self.platform.SetFullPerformanceModeEnabled(True)
+    self.platform.InstallApplication(core_util.FindLatestApkOnHost(
+        finder_options.chrome_root, 'MapsWebApk.apk'))
     wpr_mode = wpr_modes.WPR_REPLAY
+    self._number_of_iterations = _NUMBER_OF_ITERATIONS
     if finder_options.use_live_sites:
       wpr_mode = wpr_modes.WPR_OFF
-    self.platform.SetFullPerformanceModeEnabled(True)
+    elif finder_options.browser_options.wpr_mode == wpr_modes.WPR_RECORD:
+      wpr_mode = wpr_modes.WPR_RECORD
+      # When recording a WPR archive only load the story page once.
+      self._number_of_iterations = 1
     self.platform.network_controller.Open(wpr_mode)
     self._story_set = story_set
 
   @property
+  def number_of_iterations(self):
+    return self._number_of_iterations
+
+  @property
   def platform(self):
     return self._possible_browser.platform
 
@@ -108,9 +130,20 @@
         intent.Intent(package=self._possible_browser.settings.package,
                       activity=self._possible_browser.settings.activity,
                       action=None, data=url, extras=cct_extras),
-
         blocking=True)
 
+  def LaunchMapsPwa(self):
+    # Launches a bound webapk. The APK should be installed by the shared state
+    # constructor. Upon launch, Chrome extracts the icon and the URL from the
+    # APK.
+    self.platform.StartActivity(
+        intent.Intent(package='org.chromium.maps_go_webapk',
+                      activity='org.chromium.webapk.shell_apk.MainActivity',
+                      category='android.intent.category.LAUNCHER',
+                      action='android.intent.action.MAIN'),
+        blocking=True)
+    self.platform.WaitForBatteryTemperature(_MAX_BATTERY_TEMP)
+
   @contextlib.contextmanager
   def FindBrowser(self):
     """Find and manage the lifetime of a browser.
@@ -157,7 +190,7 @@
 
 
 def _DriveMobileStartupWithIntent(state, flush_caches):
-  for _ in xrange(_NUMBER_OF_ITERATIONS):
+  for _ in xrange(state.number_of_iterations):
     # TODO(pasko): Find a way to fail the benchmark when WPR is set up
     # incorrectly and error pages get loaded.
     state.LaunchBrowser('http://bbc.co.uk', flush_caches)
@@ -190,13 +223,27 @@
         _MobileStartupSharedState, name='cct:coldish:bbc')
 
   def Run(self, state):
-    for _ in xrange(_NUMBER_OF_ITERATIONS):
+    for _ in xrange(state.number_of_iterations):
       state.LaunchCCT('http://bbc.co.uk')
       with state.FindBrowser() as browser:
         action_runner = browser.foreground_tab.action_runner
         action_runner.tab.WaitForDocumentReadyStateToBeComplete()
 
 
+class _MapsPwaStartupStory(story_module.Story):
+  def __init__(self):
+    super(_MapsPwaStartupStory, self).__init__(
+        _MobileStartupSharedState, name='maps_pwa:with_http_cache')
+
+  def Run(self, state):
+    for _ in xrange(state.number_of_iterations):
+      # TODO(pasko): Flush HTTP cache for 'maps_pwa:no_http_cache'.
+      state.LaunchMapsPwa()
+      with state.FindBrowser() as browser:
+        action_runner = browser.foreground_tab.action_runner
+        action_runner.tab.WaitForDocumentReadyStateToBeComplete()
+
+
 class _MobileStartupStorySet(story_module.StorySet):
   def __init__(self):
     super(_MobileStartupStorySet, self).__init__(
@@ -205,12 +252,15 @@
     self.AddStory(_MobileStartupWithIntentStory())
     self.AddStory(_MobileStartupWithIntentStoryWarm())
     self.AddStory(_MobileStartupWithCctIntentStory())
+    self.AddStory(_MapsPwaStartupStory())
 
 
 @benchmark.Info(emails=['pasko@chromium.org',
                         'chrome-android-perf-status@chromium.org'],
                 component='Speed>Metrics>SystemHealthRegressions')
 class MobileStartupBenchmark(perf_benchmark.PerfBenchmark):
+  """Startup benchmark for Chrome on Android."""
+
   SUPPORTED_PLATFORMS = [story_module.expectations.ANDROID_NOT_WEBVIEW]
 
   def CreateCoreTimelineBasedMeasurementOptions(self):
diff --git a/tools/perf/chrome_telemetry_build/BUILD.gn b/tools/perf/chrome_telemetry_build/BUILD.gn
index ba8dcda3..cb3f07f 100644
--- a/tools/perf/chrome_telemetry_build/BUILD.gn
+++ b/tools/perf/chrome_telemetry_build/BUILD.gn
@@ -94,6 +94,7 @@
   if (is_android) {
     data += [ "//build/android/stacktrace/" ]
     data_deps += [
+      "//chrome/android/webapk/shell_apk:maps_go_webapk",
       "//build/android:devil_chromium_py",
       "//third_party/breakpad:dump_syms",
       "//third_party/breakpad:minidump_dump",
diff --git a/tools/perf/page_sets/data/startup_pages.json b/tools/perf/page_sets/data/startup_pages.json
index f7084dc..4538a50 100644
--- a/tools/perf/page_sets/data/startup_pages.json
+++ b/tools/perf/page_sets/data/startup_pages.json
@@ -1,11 +1,5 @@
 {
     "archives": {
-        "intent:coldish:bbc": {
-            "DEFAULT": "startup_pages_000.wprgo"
-        },
-        "intent:warm:bbc": {
-            "DEFAULT": "startup_pages_000.wprgo"
-        },
         "cct:coldish:bbc": {
             "DEFAULT": "startup_pages_000.wprgo"
         },
@@ -14,8 +8,17 @@
         },
         "http://kapook.com": {
             "DEFAULT": "startup_pages_000.wprgo"
+        },
+        "intent:coldish:bbc": {
+            "DEFAULT": "startup_pages_000.wprgo"
+        },
+        "intent:warm:bbc": {
+            "DEFAULT": "startup_pages_000.wprgo"
+        },
+        "maps_pwa:with_http_cache": {
+            "DEFAULT": "startup_pages_b689e9a47f.wprgo"
         }
     },
-    "description": "Describes the Web Page Replay archives for a story set. Normally record_wpr is used to produce this file. Since record_wpr does not work for startup.mobile benchmarks, we allow adding new stories to this file by hand.",
+    "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
     "platform_specific": true
-}
+}
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/startup_pages_b689e9a47f.wprgo.sha1 b/tools/perf/page_sets/data/startup_pages_b689e9a47f.wprgo.sha1
new file mode 100644
index 0000000..e09371f
--- /dev/null
+++ b/tools/perf/page_sets/data/startup_pages_b689e9a47f.wprgo.sha1
@@ -0,0 +1 @@
+b689e9a47f369a17dce79e95b607cf3ca438b324
\ No newline at end of file
diff --git a/ui/accessibility/platform/ax_platform_node.cc b/ui/accessibility/platform/ax_platform_node.cc
index 1c6b1f177..2b18ace 100644
--- a/ui/accessibility/platform/ax_platform_node.cc
+++ b/ui/accessibility/platform/ax_platform_node.cc
@@ -77,7 +77,13 @@
 
 // static
 void AXPlatformNode::NotifyAddAXModeFlags(AXMode mode_flags) {
-  ax_mode_ |= mode_flags;
+  AXMode new_ax_mode(ax_mode_);
+  new_ax_mode |= mode_flags;
+
+  if (new_ax_mode == ax_mode_)
+    return;  // No change.
+
+  ax_mode_ = new_ax_mode;
   for (auto& observer : ax_mode_observers_.Get())
     observer.OnAXModeAdded(mode_flags);
 
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 8c27462..afccd82 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -1210,6 +1210,45 @@
                                              end_offset);
 }
 
+int AXPlatformNodeAuraLinux::GetCaretOffset() {
+  if (!HasCaret())
+    return -1;
+
+  int selection_start, selection_end;
+  GetSelectionOffsets(&selection_start, &selection_end);
+  return UTF16ToUnicodeOffsetInText(selection_end);
+}
+
+bool AXPlatformNodeAuraLinux::SetCaretOffset(int offset) {
+  int character_count = atk_text_get_character_count(ATK_TEXT(atk_object_));
+  if (offset < 0 || offset > character_count)
+    offset = character_count;
+
+  offset = UnicodeToUTF16OffsetInText(offset);
+  if (!SetTextSelection(offset, offset))
+    return false;
+
+  OnTextSelectionChanged();
+  return true;
+}
+
+static gint AXPlatformNodeAuraLinuxGetCaretOffset(AtkText* atk_text) {
+  AXPlatformNodeAuraLinux* obj =
+      AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(atk_text));
+  if (!obj)
+    return -1;
+  return obj->GetCaretOffset();
+}
+
+static gboolean AXPlatformNodeAuraLinuxSetCaretOffset(AtkText* atk_text,
+                                                      gint offset) {
+  AXPlatformNodeAuraLinux* obj =
+      AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(atk_text));
+  if (!obj)
+    return FALSE;
+  return obj->SetCaretOffset(offset);
+}
+
 #if ATK_CHECK_VERSION(2, 10, 0)
 static char* AXPlatformNodeAuraLinuxGetStringAtOffset(
     AtkText* atk_text,
@@ -1297,6 +1336,8 @@
   iface->get_text_after_offset = AXPlatformNodeAuraLinuxGetTextAfterOffset;
   iface->get_text_before_offset = AXPlatformNodeAuraLinuxGetTextBeforeOffset;
   iface->get_text_at_offset = AXPlatformNodeAuraLinuxGetTextAtOffset;
+  iface->get_caret_offset = AXPlatformNodeAuraLinuxGetCaretOffset;
+  iface->set_caret_offset = AXPlatformNodeAuraLinuxSetCaretOffset;
   iface->get_character_extents = AXPlatformNodeAuraLinuxGetCharacterExtents;
   iface->get_range_extents = AXPlatformNodeAuraLinuxGetRangeExtents;
 
@@ -3065,6 +3106,13 @@
   return false;
 }
 
+void AXPlatformNodeAuraLinux::OnTextSelectionChanged() {
+  if (HasCaret()) {
+    g_signal_emit_by_name(atk_object_, "text-caret-moved",
+                          atk_text_get_caret_offset(ATK_TEXT(atk_object_)));
+  }
+}
+
 bool AXPlatformNodeAuraLinux::SupportsSelectionWithAtkSelection() {
   return SupportsToggle(GetData().role) ||
          GetData().role == ax::mojom::Role::kListBoxOption;
@@ -3162,6 +3210,9 @@
     case ax::mojom::Event::kSelectedChildrenChanged:
       OnSelectedChildrenChanged();
       break;
+    case ax::mojom::Event::kTextSelectionChanged:
+      OnTextSelectionChanged();
+      break;
     case ax::mojom::Event::kValueChanged:
       OnValueChanged();
       break;
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h
index b67dfbe3..81bef19 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.h
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -88,6 +88,7 @@
   void OnMenuPopupEnd();
   void OnSelected();
   void OnSelectedChildrenChanged();
+  void OnTextSelectionChanged();
   void OnValueChanged();
   void OnNameChanged();
   void OnDescriptionChanged();
@@ -114,6 +115,9 @@
   void SetEmbeddedDocument(AtkObject* new_document);
   void SetEmbeddingWindow(AtkObject* new_embedding_window);
 
+  int GetCaretOffset();
+  bool SetCaretOffset(int offset);
+
  protected:
   // Offsets for the AtkText API are calculated in UTF-16 code point offsets,
   // but the ATK APIs want all offsets to be in "characters," which we
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
index 6ddbe51..e2bd0212 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -1198,6 +1198,52 @@
   g_object_unref(root_obj);
 }
 
+TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextCaretMoved) {
+  Init(BuildTextField());
+
+  AtkObject* root_atk_object(GetRootAtkObject());
+  EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
+  g_object_ref(root_atk_object);
+
+  ASSERT_TRUE(ATK_IS_TEXT(root_atk_object));
+  AtkText* atk_text = ATK_TEXT(root_atk_object);
+
+  int caret_position_from_event = -1;
+  g_signal_connect(atk_text, "text-caret-moved",
+                   G_CALLBACK(+[](AtkText*, int new_position, gpointer data) {
+                     int* caret_position_from_event = static_cast<int*>(data);
+                     *caret_position_from_event = new_position;
+                   }),
+                   &caret_position_from_event);
+
+  atk_text_set_caret_offset(atk_text, 4);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), 4);
+  ASSERT_EQ(caret_position_from_event, 4);
+
+  caret_position_from_event = -1;
+  int character_count = atk_text_get_character_count(atk_text);
+  atk_text_set_caret_offset(atk_text, -1);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count);
+  ASSERT_EQ(caret_position_from_event, character_count);
+
+  caret_position_from_event = -1;
+  atk_text_set_caret_offset(atk_text, -1000);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count);
+  ASSERT_EQ(caret_position_from_event, character_count);
+
+  caret_position_from_event = -1;
+  atk_text_set_caret_offset(atk_text, 1000);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count);
+  ASSERT_EQ(caret_position_from_event, character_count);
+
+  caret_position_from_event = -1;
+  atk_text_set_caret_offset(atk_text, character_count - 1);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count - 1);
+  ASSERT_EQ(caret_position_from_event, character_count - 1);
+
+  g_object_unref(root_atk_object);
+}
+
 class ActivationTester {
  public:
   explicit ActivationTester(AtkObject* target) : target_(target) {
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index 17b9be0c..5eaf229 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -244,7 +244,7 @@
     "java/src/org/chromium/ui/base/ActivityWindowAndroid.java",
     "java/src/org/chromium/ui/base/AndroidPermissionDelegate.java",
     "java/src/org/chromium/ui/base/Clipboard.java",
-    "java/src/org/chromium/ui/base/CursorVisibilityObserver.java",
+    "java/src/org/chromium/ui/base/CursorObserver.java",
     "java/src/org/chromium/ui/base/DeviceFormFactor.java",
     "java/src/org/chromium/ui/base/EventForwarder.java",
     "java/src/org/chromium/ui/base/TouchlessEventHandler.java",
diff --git a/ui/android/java/src/org/chromium/ui/base/CursorObserver.java b/ui/android/java/src/org/chromium/ui/base/CursorObserver.java
new file mode 100644
index 0000000..ac8d58e
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/base/CursorObserver.java
@@ -0,0 +1,13 @@
+// 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.
+
+package org.chromium.ui.base;
+
+/**
+ * Observer Android cursor state.
+ */
+public interface CursorObserver {
+    void onCursorVisibilityChanged(boolean visible);
+    void onFallbackCursorModeToggled(boolean isOn);
+}
\ No newline at end of file
diff --git a/ui/android/java/src/org/chromium/ui/base/CursorVisibilityObserver.java b/ui/android/java/src/org/chromium/ui/base/CursorVisibilityObserver.java
deleted file mode 100644
index f176a22c..0000000
--- a/ui/android/java/src/org/chromium/ui/base/CursorVisibilityObserver.java
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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.
-
-package org.chromium.ui.base;
-
-/**
- * Observer Android cursor visibility.
- */
-public interface CursorVisibilityObserver { void onCursorVisibilityChanged(boolean visible); }
\ No newline at end of file
diff --git a/ui/android/java/src/org/chromium/ui/base/TouchlessEventHandler.java b/ui/android/java/src/org/chromium/ui/base/TouchlessEventHandler.java
index 1ec84fb3..b3983e1 100644
--- a/ui/android/java/src/org/chromium/ui/base/TouchlessEventHandler.java
+++ b/ui/android/java/src/org/chromium/ui/base/TouchlessEventHandler.java
@@ -31,15 +31,15 @@
         return sInstance.onUnconsumedKeyboardEventAckInternal(nativeCode);
     }
 
-    public static void addCursorVisibilityObserver(CursorVisibilityObserver observer) {
+    public static void addCursorObserver(CursorObserver observer) {
         if (sInstance != null) {
-            sInstance.addCursorVisibilityObserverInternal(observer);
+            sInstance.addCursorObserverInternal(observer);
         }
     }
 
-    public static void removeCursorVisibilityObserver(CursorVisibilityObserver observer) {
+    public static void removeCursorObserver(CursorObserver observer) {
         if (sInstance != null) {
-            sInstance.removeCursorVisibilityObserverInternal(observer);
+            sInstance.removeCursorObserverInternal(observer);
         }
     }
 
@@ -70,9 +70,9 @@
         return false;
     }
 
-    protected void addCursorVisibilityObserverInternal(CursorVisibilityObserver observer) {}
+    protected void addCursorObserverInternal(CursorObserver observer) {}
 
-    protected void removeCursorVisibilityObserverInternal(CursorVisibilityObserver observer) {}
+    protected void removeCursorObserverInternal(CursorObserver observer) {}
 
     protected void onDidFinishNavigationInternal() {}
 
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
index 9e5732d..74cb1b6 100644
--- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -183,14 +183,21 @@
         }
     };
 
-    private final CursorVisibilityObserver mCursorVisibilityObserver =
-            new CursorVisibilityObserver() {
+    private final CursorObserver mCursorObserver =
+            new CursorObserver() {
                 @Override
                 public void onCursorVisibilityChanged(boolean visible) {
                     if (mNativeWindowAndroid != 0) {
                         nativeOnCursorVisibilityChanged(mNativeWindowAndroid, visible);
                     }
                 }
+
+                @Override
+                public void onFallbackCursorModeToggled(boolean isOn) {
+                    if (mNativeWindowAndroid != 0) {
+                        nativeOnFallbackCursorModeToggled(mNativeWindowAndroid, isOn);
+                    }
+                }
             };
 
     /**
@@ -270,7 +277,7 @@
             display.updateIsDisplayServerWideColorGamut(isScreenWideColorGamut);
         }
 
-        TouchlessEventHandler.addCursorVisibilityObserver(mCursorVisibilityObserver);
+        TouchlessEventHandler.addCursorObserver(mCursorObserver);
     }
 
     @CalledByNative
@@ -663,7 +670,7 @@
             if (mTouchExplorationMonitor != null) mTouchExplorationMonitor.destroy();
         }
 
-        TouchlessEventHandler.removeCursorVisibilityObserver(mCursorVisibilityObserver);
+        TouchlessEventHandler.removeCursorObserver(mCursorObserver);
     }
 
     /**
@@ -968,6 +975,7 @@
     private native void nativeOnUpdateRefreshRate(long nativeWindowAndroid, float refreshRate);
     private native void nativeDestroy(long nativeWindowAndroid);
     private native void nativeOnCursorVisibilityChanged(long nativeWindowAndroid, boolean visible);
+    private native void nativeOnFallbackCursorModeToggled(long nativeWindowAndroid, boolean isOn);
     private native void nativeOnSupportedRefreshRatesUpdated(
             long nativeWindowAndroid, float[] supportedRefreshRates);
 }
diff --git a/ui/android/window_android.cc b/ui/android/window_android.cc
index 777965a9..ecc1ac3 100644
--- a/ui/android/window_android.cc
+++ b/ui/android/window_android.cc
@@ -366,6 +366,14 @@
     observer.OnCursorVisibilityChanged(visible);
 }
 
+void WindowAndroid::OnFallbackCursorModeToggled(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& obj,
+    bool is_on) {
+  for (WindowAndroidObserver& observer : observer_list_)
+    observer.OnFallbackCursorModeToggled(is_on);
+}
+
 void WindowAndroid::OnUpdateRefreshRate(
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& obj,
diff --git a/ui/android/window_android.h b/ui/android/window_android.h
index 5bc0a48c..21644ba 100644
--- a/ui/android/window_android.h
+++ b/ui/android/window_android.h
@@ -84,6 +84,10 @@
   void OnVisibilityChanged(JNIEnv* env,
                            const base::android::JavaParamRef<jobject>& obj,
                            bool visible);
+  void OnFallbackCursorModeToggled(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& obj,
+      bool is_on);
   void OnActivityStopped(JNIEnv* env,
                          const base::android::JavaParamRef<jobject>& obj);
   void OnActivityStarted(JNIEnv* env,
diff --git a/ui/android/window_android_observer.h b/ui/android/window_android_observer.h
index 549ba29..065b455 100644
--- a/ui/android/window_android_observer.h
+++ b/ui/android/window_android_observer.h
@@ -23,6 +23,7 @@
   virtual void OnActivityStopped() = 0;
   virtual void OnActivityStarted() = 0;
   virtual void OnCursorVisibilityChanged(bool visible) {}
+  virtual void OnFallbackCursorModeToggled(bool is_on) {}
 
  protected:
   virtual ~WindowAndroidObserver() {}
diff --git a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js
index 1580615..6cf94ae 100644
--- a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js
@@ -179,43 +179,47 @@
 
   resolveGetLatestCallback([entry2]);
 
-  reportPromise(waitUntil(() => {
-    // Assert that thumbnailLoaded event is fired for Test2.jpg.
-    return thumbnailLoadedEvents.length === 1;
-  }).then(() => {
-    const event = thumbnailLoadedEvents.shift();
-    assertEquals('filesystem:volume-id/Test2.jpg', event.fileUrl);
-    assertTrue(event.dataUrl.length > 0);
-    assertEquals(160, event.width);
-    assertEquals(160, event.height);
+  reportPromise(
+      waitUntil(() => {
+        // Assert that thumbnailLoaded event is fired for Test2.jpg.
+        return thumbnailLoadedEvents.length === 1;
+      })
+          .then(() => {
+            const event = thumbnailLoadedEvents.shift();
+            assertEquals('filesystem:volume-id/Test2.jpg', event.fileUrl);
+            assertTrue(event.dataUrl.length > 0);
+            assertEquals(160, event.width);
+            assertEquals(160, event.height);
 
-    // Since thumbnail of Test2.jpg is loaded into the cache,
-    // getThumbnailFromCache returns thumbnail for the image.
-    const thumbnail = listThumbnailLoader.getThumbnailFromCache(entry2);
-    assertEquals('filesystem:volume-id/Test2.jpg', thumbnail.fileUrl);
-    assertTrue(thumbnail.dataUrl.length > 0);
-    assertEquals(160, thumbnail.width);
-    assertEquals(160, thumbnail.height);
+            // Since thumbnail of Test2.jpg is loaded into the cache,
+            // getThumbnailFromCache returns thumbnail for the image.
+            const thumbnail = listThumbnailLoader.getThumbnailFromCache(entry2);
+            assertEquals('filesystem:volume-id/Test2.jpg', thumbnail.fileUrl);
+            assertTrue(thumbnail.dataUrl.length > 0);
+            assertEquals(160, thumbnail.width);
+            assertEquals(160, thumbnail.height);
 
-    // Assert that new task is enqueued.
-    return waitUntil(() => {
-      return hasPendingGetLatestCallback([entry1]) &&
-          hasPendingGetLatestCallback([entry4]) &&
-          Object.keys(getCallbacks).length === 2;
-    });
-  }).then(() => {
-    // Set high priority range to 2 - 4.
-    listThumbnailLoader.setHighPriorityRange(2, 4);
+            // Assert that new task is enqueued.
+            return waitUntil(() => {
+              return hasPendingGetLatestCallback([entry1]) &&
+                  hasPendingGetLatestCallback([entry4]) &&
+                  Object.keys(getCallbacks).length === 2;
+            });
+          })
+          .then(() => {
+            // Set high priority range to 2 - 4.
+            listThumbnailLoader.setHighPriorityRange(2, 4);
 
-    resolveGetLatestCallback([entry1]);
+            resolveGetLatestCallback([entry1]);
 
-    // Assert that task for (Test3.jpg) is enqueued.
-    return waitUntil(() => {
-      return hasPendingGetLatestCallback([entry3]) &&
-          hasPendingGetLatestCallback([entry4]) &&
-          Object.keys(getCallbacks).length === 2;
-    });
-  }), callback);
+            // Assert that task for (Test3.jpg) is enqueued.
+            return waitUntil(() => {
+              return hasPendingGetLatestCallback([entry3]) &&
+                  hasPendingGetLatestCallback([entry4]) &&
+                  Object.keys(getCallbacks).length === 2;
+            });
+          }),
+      callback);
 }
 
 /**
@@ -245,42 +249,50 @@
   resolveGetLatestCallback([entry2]);
   assertEquals(0, Object.keys(getCallbacks).length);
 
-  reportPromise(waitUntil(() => {
-    return areEntriesInCache([entry3, entry2, entry1]);
-  }).then(() => {
-    // Move high priority range to 1 - 3.
-    listThumbnailLoader.setHighPriorityRange(1, 3);
-    resolveGetLatestCallback([entry4]);
-    assertEquals(0, Object.keys(getCallbacks).length);
+  reportPromise(
+      waitUntil(() => {
+        return areEntriesInCache([entry3, entry2, entry1]);
+      })
+          .then(() => {
+            // Move high priority range to 1 - 3.
+            listThumbnailLoader.setHighPriorityRange(1, 3);
+            resolveGetLatestCallback([entry4]);
+            assertEquals(0, Object.keys(getCallbacks).length);
 
-    return waitUntil(() => {
-      return areEntriesInCache([entry4, entry3, entry2, entry1]);
-    });
-  }).then(() => {
-    // Move high priority range to 4 - 6.
-    listThumbnailLoader.setHighPriorityRange(4, 6);
-    resolveGetLatestCallback([entry5]);
-    resolveGetLatestCallback([entry6]);
-    assertEquals(0, Object.keys(getCallbacks).length);
+            return waitUntil(() => {
+              return areEntriesInCache([entry4, entry3, entry2, entry1]);
+            });
+          })
+          .then(() => {
+            // Move high priority range to 4 - 6.
+            listThumbnailLoader.setHighPriorityRange(4, 6);
+            resolveGetLatestCallback([entry5]);
+            resolveGetLatestCallback([entry6]);
+            assertEquals(0, Object.keys(getCallbacks).length);
 
-    return waitUntil(() => {
-      return areEntriesInCache([entry6, entry5, entry4, entry3, entry2]);
-    });
-  }).then(() => {
-    // Move high priority range to 3 - 5.
-    listThumbnailLoader.setHighPriorityRange(3, 5);
-    assertEquals(0, Object.keys(getCallbacks).length);
-    assertTrue(areEntriesInCache([entry6, entry5, entry4, entry3, entry2]));
+            return waitUntil(() => {
+              return areEntriesInCache(
+                  [entry6, entry5, entry4, entry3, entry2]);
+            });
+          })
+          .then(() => {
+            // Move high priority range to 3 - 5.
+            listThumbnailLoader.setHighPriorityRange(3, 5);
+            assertEquals(0, Object.keys(getCallbacks).length);
+            assertTrue(
+                areEntriesInCache([entry6, entry5, entry4, entry3, entry2]));
 
-    // Move high priority range to 0 - 2.
-    listThumbnailLoader.setHighPriorityRange(0, 2);
-    resolveGetLatestCallback([entry1]);
-    assertEquals(0, Object.keys(getCallbacks).length);
+            // Move high priority range to 0 - 2.
+            listThumbnailLoader.setHighPriorityRange(0, 2);
+            resolveGetLatestCallback([entry1]);
+            assertEquals(0, Object.keys(getCallbacks).length);
 
-    return waitUntil(() => {
-      return areEntriesInCache([entry3, entry2, entry1, entry6, entry5]);
-    });
-  }), callback);
+            return waitUntil(() => {
+              return areEntriesInCache(
+                  [entry3, entry2, entry1, entry6, entry5]);
+            });
+          }),
+      callback);
 }
 
 /**
@@ -296,9 +308,11 @@
   resolveGetLatestCallback([entry2]);
 
   // Assert that new task is enqueued for entry3.
-  reportPromise(waitUntil(() => {
-    return hasPendingGetLatestCallback([entry3]);
-  }), callback);
+  reportPromise(
+      waitUntil(() => {
+        return hasPendingGetLatestCallback([entry3]);
+      }),
+      callback);
 }
 
 /**
@@ -314,18 +328,20 @@
 
   // In order to assert that following task enqueues are fired by sorted event,
   // wait until all thumbnail loads are completed.
-  reportPromise(waitUntil(() => {
-    return thumbnailLoadedEvents.length === 2;
-  }).then(() => {
-    // After the sort, list should be
-    // directory1, entry5, entry4, entry3, entry2, entry1.
-    fileListModel.sort('name', 'desc');
+  reportPromise(
+      waitUntil(() => {
+        return thumbnailLoadedEvents.length === 2;
+      }).then(() => {
+        // After the sort, list should be
+        // directory1, entry5, entry4, entry3, entry2, entry1.
+        fileListModel.sort('name', 'desc');
 
-    return waitUntil(() => {
-      return hasPendingGetLatestCallback([entry5]) &&
-          hasPendingGetLatestCallback([entry4]);
-    });
-  }), callback);
+        return waitUntil(() => {
+          return hasPendingGetLatestCallback([entry5]) &&
+              hasPendingGetLatestCallback([entry4]);
+        });
+      }),
+      callback);
 }
 
 /**
@@ -339,25 +355,27 @@
   resolveGetLatestCallback([entry2]);
   assertEquals(0, Object.keys(getCallbacks).length);
 
-  reportPromise(waitUntil(() => {
-    return thumbnailLoadedEvents.length === 2;
-  }).then(() => {
-    // entry1 is changed.
-    const changeEvent = new Event('change');
-    changeEvent.index = 1;
-    fileListModel.dispatchEvent(changeEvent);
+  reportPromise(
+      waitUntil(() => {
+        return thumbnailLoadedEvents.length === 2;
+      }).then(() => {
+        // entry1 is changed.
+        const changeEvent = new Event('change');
+        changeEvent.index = 1;
+        fileListModel.dispatchEvent(changeEvent);
 
-    // cache of entry1 should become invalid.
-    const thumbnail = listThumbnailLoader.getThumbnailFromCache(entry1);
-    assertTrue(thumbnail.outdated);
+        // cache of entry1 should become invalid.
+        const thumbnail = listThumbnailLoader.getThumbnailFromCache(entry1);
+        assertTrue(thumbnail.outdated);
 
-    resolveGetLatestCallback([entry1]);
+        resolveGetLatestCallback([entry1]);
 
-    // Wait until thumbnailLoaded event is fired again for the change.
-    return waitUntil(() => {
-      return thumbnailLoadedEvents.length === 3;
-    });
-  }), callback);
+        // Wait until thumbnailLoaded event is fired again for the change.
+        return waitUntil(() => {
+          return thumbnailLoadedEvents.length === 3;
+        });
+      }),
+      callback);
 }
 
 /**
@@ -380,7 +398,7 @@
   // Items are added during directory scan.
   isScanningForTest = true;
 
-  listThumbnailLoader.setHighPriorityRange(0,2);
+  listThumbnailLoader.setHighPriorityRange(0, 2);
   fileListModel.push(directory1, entry1, entry2);
   assertEquals(0, Object.keys(getCallbacks).length);
 
@@ -401,7 +419,7 @@
       /** @type {!VolumeManager} */ ({
         getVolumeInfo: function(entry) {
           return {
-            volumeType: currentVolumeType
+            volumeType: currentVolumeType,
           };
         },
       }),
@@ -410,7 +428,7 @@
           return Promise.resolve([{
             thumbnail: {
               urlError: {
-                errorDescription: 'Error: Unexpected EOF @0'
+                errorDescription: 'Error: Unexpected EOF @0',
               },
             },
           }]);
@@ -421,11 +439,13 @@
         assertTrue(false);
       });
 
-  return reportPromise(task.fetch().then(thumbnailData => {
-    assertEquals(null, thumbnailData.dataUrl);
-    assertFalse(thumbnailData.outdated);
-    return waitUntil(() => {
-      return thumbnailData.outdated;
-    });
-  }), callback);
+  return reportPromise(
+      task.fetch().then(thumbnailData => {
+        assertEquals(null, thumbnailData.dataUrl);
+        assertFalse(thumbnailData.outdated);
+        return waitUntil(() => {
+          return thumbnailData.outdated;
+        });
+      }),
+      callback);
 }
diff --git a/ui/file_manager/file_manager/foreground/js/main_window_component.js b/ui/file_manager/file_manager/foreground/js/main_window_component.js
index 7238c5a..a2b45d9b 100644
--- a/ui/file_manager/file_manager/foreground/js/main_window_component.js
+++ b/ui/file_manager/file_manager/foreground/js/main_window_component.js
@@ -132,8 +132,7 @@
   directoryModel.addEventListener(
       'directory-changed', this.onDirectoryChanged_.bind(this));
   volumeManager.addEventListener(
-      'drive-connection-changed',
-      this.onDriveConnectionChanged_.bind(this));
+      'drive-connection-changed', this.onDriveConnectionChanged_.bind(this));
   this.onDriveConnectionChanged_();
   document.addEventListener('keydown', this.onKeyDown_.bind(this));
   document.addEventListener('keyup', this.onKeyUp_.bind(this));
@@ -378,8 +377,7 @@
 
     case 'Enter':  // Enter => Change directory or perform default action.
       const selection = this.selectionHandler_.selection;
-      if (selection.totalCount === 1 &&
-          selection.entries[0].isDirectory &&
+      if (selection.totalCount === 1 && selection.entries[0].isDirectory &&
           !DialogType.isFolderDialog(this.dialogType_)) {
         const item = this.ui_.listContainer.currentList.getListItemByIndex(
             selection.indexes[0]);
@@ -427,7 +425,8 @@
   event = /** @type {DirectoryChangeEvent} */ (event);
 
   const newVolumeInfo = event.newDirEntry ?
-      this.volumeManager_.getVolumeInfo(event.newDirEntry) : null;
+      this.volumeManager_.getVolumeInfo(event.newDirEntry) :
+      null;
 
   // Update unformatted volume status.
   if (newVolumeInfo && newVolumeInfo.error) {
@@ -448,13 +447,15 @@
     this.ui_.locationLine.show(event.newDirEntry);
     // Updates UI.
     if (this.dialogType_ === DialogType.FULL_PAGE) {
-      const locationInfo = this.volumeManager_.getLocationInfo(event.newDirEntry);
+      const locationInfo =
+          this.volumeManager_.getLocationInfo(event.newDirEntry);
       if (locationInfo) {
         const label = util.getEntryLabel(locationInfo, event.newDirEntry);
         document.title = `${str('FILEMANAGER_APP_NAME')} - ${label}`;
       } else {
-        console.error('Could not find location info for entry: '
-                      + event.newDirEntry.fullPath);
+        console.error(
+            'Could not find location info for entry: ' +
+            event.newDirEntry.fullPath);
       }
     }
   } else {
diff --git a/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js b/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js
index b19c7297..39d7e3e7 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js
@@ -26,10 +26,10 @@
    */
   this.quickViewModel_ = quickViewModel;
 
- /**
-  * @type {FilesMetadataBox} metadataBox
-  * @private
-  */
+  /**
+   * @type {FilesMetadataBox} metadataBox
+   * @private
+   */
   this.metadataBox_ = null;
 
   /**
diff --git a/ui/file_manager/file_manager/foreground/js/metadata_update_controller.js b/ui/file_manager/file_manager/foreground/js/metadata_update_controller.js
index f4c66ea..fd621cc 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata_update_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata_update_controller.js
@@ -11,10 +11,8 @@
  * @constructor
  * @struct
  */
-function MetadataUpdateController(listContainer,
-                                  directoryModel,
-                                  metadataModel,
-                                  fileMetadataFormatter) {
+function MetadataUpdateController(
+    listContainer, directoryModel, metadataModel, fileMetadataFormatter) {
   /**
    * @private {!DirectoryModel}
    * @const
@@ -51,9 +49,10 @@
   today.setMinutes(0);
   today.setSeconds(0);
   today.setMilliseconds(0);
-  setTimeout(this.dailyUpdateModificationTime_.bind(this),
-             today.getTime() + MetadataUpdateController.MILLISECONDS_IN_DAY_ -
-             Date.now() + 1000);
+  setTimeout(
+      this.dailyUpdateModificationTime_.bind(this),
+      today.getTime() + MetadataUpdateController.MILLISECONDS_IN_DAY_ -
+          Date.now() + 1000);
 }
 
 /**
@@ -102,14 +101,15 @@
  * @private
  */
 MetadataUpdateController.prototype.dailyUpdateModificationTime_ = function() {
-  const entries = /** @type {!Array<!Entry>} */(
+  const entries = /** @type {!Array<!Entry>} */ (
       this.directoryModel_.getFileList().slice());
   this.metadataModel_.get(entries, ['modificationTime']).then(() => {
     this.listContainer_.currentView.updateListItemsMetadata(
         'filesystem', entries);
   });
-  setTimeout(this.dailyUpdateModificationTime_.bind(this),
-             MetadataUpdateController.MILLISECONDS_IN_DAY_);
+  setTimeout(
+      this.dailyUpdateModificationTime_.bind(this),
+      MetadataUpdateController.MILLISECONDS_IN_DAY_);
 };
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/mock_actions_model.js b/ui/file_manager/file_manager/foreground/js/mock_actions_model.js
index fcc04f7..8d4c8ee 100644
--- a/ui/file_manager/file_manager/foreground/js/mock_actions_model.js
+++ b/ui/file_manager/file_manager/foreground/js/mock_actions_model.js
@@ -18,8 +18,7 @@
   return this.title;
 };
 
-MockActionModel.prototype.onCanExecute = () => {
-};
+MockActionModel.prototype.onCanExecute = () => {};
 
 MockActionModel.prototype.onExecute = function() {
   cr.dispatchSimpleEvent('invalidated', this.actionsModel);
diff --git a/ui/file_manager/file_manager/foreground/js/mock_thumbnail_loader.js b/ui/file_manager/file_manager/foreground/js/mock_thumbnail_loader.js
index 498dd0e..288acfd 100644
--- a/ui/file_manager/file_manager/foreground/js/mock_thumbnail_loader.js
+++ b/ui/file_manager/file_manager/foreground/js/mock_thumbnail_loader.js
@@ -13,8 +13,9 @@
  * @param {number=} opt_priority Priority.
  * @constructor
  */
-function MockThumbnailLoader(entry, opt_loaderType, opt_metadata, opt_mediaType,
-    opt_loadTargets, opt_priority) {
+function MockThumbnailLoader(
+    entry, opt_loaderType, opt_metadata, opt_mediaType, opt_loadTargets,
+    opt_priority) {
   this.entry_ = entry;
 }
 
diff --git a/ui/file_manager/file_manager/foreground/js/naming_controller.js b/ui/file_manager/file_manager/foreground/js/naming_controller.js
index de1a8157..d534e4b 100644
--- a/ui/file_manager/file_manager/foreground/js/naming_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/naming_controller.js
@@ -31,7 +31,7 @@
    */
   this.alertDialog_ = alertDialog;
 
- /**
+  /**
    * @type {!cr.ui.dialogs.ConfirmDialog}
    * @const
    * @private
@@ -97,8 +97,8 @@
  * @return {Promise<string>}
  */
 NamingController.prototype.validateFileNameForSaving = function(filename) {
-  const directory = /** @type {DirectoryEntry} */ (
-      this.directoryModel_.getCurrentDirEntry());
+  const directory =
+      /** @type {DirectoryEntry} */ (this.directoryModel_.getCurrentDirEntry());
   const currentDirUrl = directory.toURL().replace(/\/?$/, '/');
   const fileUrl = currentDirUrl + encodeURIComponent(filename);
 
@@ -209,8 +209,8 @@
     return;
   }
 
-  const leadListItem = this.listContainer_.findListItemForNode(
-      this.listContainer_.renameInput);
+  const leadListItem =
+      this.listContainer_.findListItemForNode(this.listContainer_.renameInput);
   if (this.listContainer_.currentListType == ListContainer.ListType.DETAIL) {
     this.listContainer_.table.updateFileMetadata(leadListItem, leadEntry);
   }
@@ -274,8 +274,8 @@
     return;
   }
 
-  const renamedItemElement = this.listContainer_.findListItemForNode(
-      this.listContainer_.renameInput);
+  const renamedItemElement =
+      this.listContainer_.findListItemForNode(this.listContainer_.renameInput);
   const nameNode = renamedItemElement.querySelector('.filename-label');
 
   input.validation_ = true;
@@ -336,9 +336,9 @@
   // parent if the directory content is a search result. Fix it to do proper
   // validation.
   this.validateFileName(
-      /** @type {!DirectoryEntry} */ (this.directoryModel_.getCurrentDirEntry()),
-      newName,
-      validationDone.bind(this));
+      /** @type {!DirectoryEntry} */ (
+          this.directoryModel_.getCurrentDirEntry()),
+      newName, validationDone.bind(this));
 };
 
 /**
@@ -347,8 +347,8 @@
 NamingController.prototype.cancelRename_ = function() {
   this.listContainer_.renameInput.currentEntry = null;
 
-  const item = this.listContainer_.findListItemForNode(
-      this.listContainer_.renameInput);
+  const item =
+      this.listContainer_.findListItemForNode(this.listContainer_.renameInput);
   if (item) {
     item.removeAttribute('renaming');
   }
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
index 2de9579..b7dce68 100644
--- a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
+++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
@@ -689,8 +689,7 @@
       // Add partitions as entries.
       for (const partition of removableGroup) {
         // Only add partition if it doesn't exist as a child already.
-        if (removableEntry.findIndexByVolumeInfo(partition.volumeInfo) ===
-            -1) {
+        if (removableEntry.findIndexByVolumeInfo(partition.volumeInfo) === -1) {
           removableEntry.addEntry(new VolumeEntry(partition.volumeInfo));
         }
       }
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
index 7cdc5ff..8bccb994 100644
--- a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
@@ -237,8 +237,7 @@
       (model.item(4)).volumeInfo.volumeId);
 
   // Create a shortcut on the 'hoge' volume.
-  shortcutListModel.splice(
-      1, 0, new MockFileEntry(hoge, '/shortcut2'));
+  shortcutListModel.splice(1, 0, new MockFileEntry(hoge, '/shortcut2'));
 
   assertEquals(6, model.length);
   assertEquals(
diff --git a/ui/file_manager/file_manager/foreground/js/progress_center_item_group.js b/ui/file_manager/file_manager/foreground/js/progress_center_item_group.js
index d62f941..fddf093 100644
--- a/ui/file_manager/file_manager/foreground/js/progress_center_item_group.js
+++ b/ui/file_manager/file_manager/foreground/js/progress_center_item_group.js
@@ -126,8 +126,7 @@
 
   const item = new ProgressCenterItem();
   item.state = ProgressItemState.ERROR;
-  item.message = strf('ERROR_PROGRESS_SUMMARY_PLURAL',
-                      errorItems.length);
+  item.message = strf('ERROR_PROGRESS_SUMMARY_PLURAL', errorItems.length);
   item.single = false;
   return item;
 };
@@ -142,26 +141,25 @@
  * @return {boolean} Whether the item should be animated or not.
  * @private
  */
-ProgressCenterItemGroup.shouldAnimate_ = (previousAnimated, previousItem, item, summarized) => {
-  // Check visibility of previous and current progress bar.
-  const previousShow =
-      previousItem && (!summarized || !previousItem.quiet);
-  const currentShow =
-      item && (!summarized || !item.quiet);
-  // If previous or current item does not show progress bar, we should not
-  // animate.
-  if (!previousShow || !currentShow) {
-    return false;
-  }
-  if (previousItem.progressRateInPercent < item.progressRateInPercent) {
-    return true;
-  }
-  if (previousAnimated &&
-      previousItem.progressRateInPercent === item.progressRateInPercent) {
-    return true;
-  }
-  return false;
-};
+ProgressCenterItemGroup.shouldAnimate_ =
+    (previousAnimated, previousItem, item, summarized) => {
+      // Check visibility of previous and current progress bar.
+      const previousShow = previousItem && (!summarized || !previousItem.quiet);
+      const currentShow = item && (!summarized || !item.quiet);
+      // If previous or current item does not show progress bar, we should not
+      // animate.
+      if (!previousShow || !currentShow) {
+        return false;
+      }
+      if (previousItem.progressRateInPercent < item.progressRateInPercent) {
+        return true;
+      }
+      if (previousAnimated &&
+          previousItem.progressRateInPercent === item.progressRateInPercent) {
+        return true;
+      }
+      return false;
+    };
 
 ProgressCenterItemGroup.prototype = /** @struct */ {
   /**
@@ -264,9 +262,7 @@
       }
       this.items_[item.id] = item.clone();
       this.animated_[item.id] = ProgressCenterItemGroup.shouldAnimate_(
-          !!this.animated_[item.id],
-          previousItem,
-          item,
+          !!this.animated_[item.id], previousItem, item,
           /* summarized */ false);
       if (!this.animated_[item.id]) {
         this.completeItemAnimation(item.id);
@@ -287,8 +283,7 @@
   const previousSummarizedItem = this.summarizedItem_;
   this.summarizedItem_ = this.getSummarizedItem(0);
   this.summarizedItemAnimated_ = ProgressCenterItemGroup.shouldAnimate_(
-      !!this.summarizedItemAnimated_,
-      previousSummarizedItem,
+      !!this.summarizedItemAnimated_, previousSummarizedItem,
       this.summarizedItem_,
       /* summarized */ true);
   if (!this.summarizedItemAnimated_) {
diff --git a/ui/file_manager/file_manager/foreground/js/progress_center_item_group_unittest.js b/ui/file_manager/file_manager/foreground/js/progress_center_item_group_unittest.js
index cbe7940..62d331f 100644
--- a/ui/file_manager/file_manager/foreground/js/progress_center_item_group_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/progress_center_item_group_unittest.js
@@ -15,7 +15,8 @@
 };
 
 function testSimpleProgress() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   assertEquals(ProgressCenterItemGroup.State.EMPTY, group.state);
 
   const item = new ProgressCenterItem();
@@ -65,7 +66,8 @@
 }
 
 function testCompleteAnimationDuringProgress() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item = new ProgressCenterItem();
   item.id = 'test-item-1';
   item.message = 'TestItemMessage1';
@@ -127,7 +129,8 @@
 }
 
 function testAddMaxProgressItem() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item = new ProgressCenterItem();
   item.id = 'test-item-1';
   item.message = 'TestItemMessage1';
@@ -154,7 +157,8 @@
 }
 
 function testCompleteDuringAnimation() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item = new ProgressCenterItem();
   item.id = 'test-item-1';
   item.message = 'TestItemMessage1';
@@ -190,7 +194,8 @@
 }
 
 function testTwoItems() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item1 = new ProgressCenterItem();
   item1.id = 'test-item-1';
   item1.message = 'TestItemMessage1';
@@ -280,7 +285,8 @@
 }
 
 function testOneError() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item1 = new ProgressCenterItem();
   item1.id = 'test-item-1';
   item1.message = 'TestItemMessage1';
@@ -293,7 +299,7 @@
   group.update(item1);
 
   // Item 1 becomes error.
-  item1.message = "Error.";
+  item1.message = 'Error.';
   item1.state = ProgressItemState.ERROR;
   group.update(item1);
 
@@ -334,7 +340,8 @@
 }
 
 function testOneItemWithError() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item1 = new ProgressCenterItem();
   item1.id = 'test-item-1';
   item1.message = 'TestItemMessage1';
@@ -390,16 +397,18 @@
   assertFalse(group.isAnimated(item1.id));
   assertFalse(group.isSummarizedAnimated());
   assertFalse(!!group.getSummarizedItem(0));
-  assertEquals('Error message.',
-               ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
-  assertEquals('2 Errors.',
-               ProgressCenterItemGroup.getSummarizedErrorItem(
-                   group, group).message);
+  assertEquals(
+      'Error message.',
+      ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
+  assertEquals(
+      '2 Errors.',
+      ProgressCenterItemGroup.getSummarizedErrorItem(group, group).message);
   assertFalse(!!group.getItem(item1.id));
   assertTrue(!!group.getItem(item2.id));
 
-  assertEquals('Error message.',
-               ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
+  assertEquals(
+      'Error message.',
+      ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
   assertFalse(group.isSummarizedAnimated());
   assertEquals(ProgressCenterItemGroup.State.INACTIVE, group.state);
 
@@ -410,7 +419,8 @@
 }
 
 function testOneItemWithErrorDuringAnimation() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item1 = new ProgressCenterItem();
   item1.id = 'test-item-1';
   item1.message = 'TestItemMessage1';
@@ -453,7 +463,8 @@
 }
 
 function testTwoErrors() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item1 = new ProgressCenterItem();
   item1.id = 'test-item-1';
   item1.message = 'Error message 1';
@@ -470,8 +481,9 @@
   group.update(item1);
   assertFalse(group.isAnimated(item1.id));
   assertFalse(group.isSummarizedAnimated());
-  assertEquals('Error message 1',
-               ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
+  assertEquals(
+      'Error message 1',
+      ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
   assertEquals(ProgressCenterItemGroup.State.INACTIVE, group.state);
 
   // Add another error item.
@@ -480,8 +492,9 @@
   assertTrue(!!group.getItem(item2.id));
   assertFalse(group.isAnimated(item2.id));
   assertFalse(group.isSummarizedAnimated());
-  assertEquals('2 Errors.',
-               ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
+  assertEquals(
+      '2 Errors.',
+      ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
   assertEquals(ProgressCenterItemGroup.State.INACTIVE, group.state);
 
   // Dismiss Error message 1.
@@ -489,13 +502,15 @@
 
   assertFalse(!!group.getItem(item1.id));
   assertTrue(!!group.getItem(item2.id));
-  assertEquals('Error message 2',
+  assertEquals(
+      'Error message 2',
       ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
   assertEquals(ProgressCenterItemGroup.State.INACTIVE, group.state);
 }
 
 function testCancel() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item = new ProgressCenterItem();
   item.id = 'test-item-1';
   item.message = 'TestItemMessage1';
@@ -522,7 +537,8 @@
 }
 
 function testCancelWithError() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ false);
   const item1 = new ProgressCenterItem();
   item1.id = 'test-item-1';
   item1.message = 'TestItemMessage1';
@@ -556,13 +572,15 @@
   assertEquals(null, group.getItem(item1.id));
   assertTrue(!!group.getItem(item2.id));
   assertEquals(null, group.getSummarizedItem(0));
-  assertEquals('Error message 2',
-               ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
+  assertEquals(
+      'Error message 2',
+      ProgressCenterItemGroup.getSummarizedErrorItem(group).message);
   assertEquals(ProgressCenterItemGroup.State.INACTIVE, group.state);
 }
 
 function testQuietItem() {
-  const group = new ProgressCenterItemGroup(/* name */ 'test', /* quite */ true);
+  const group =
+      new ProgressCenterItemGroup(/* name */ 'test', /* quite */ true);
   const item = new ProgressCenterItem();
   item.id = 'test-item-1';
   item.message = 'TestItemMessage1';
diff --git a/ui/file_manager/file_manager/foreground/js/providers_model.js b/ui/file_manager/file_manager/foreground/js/providers_model.js
index 99fb89c0..42f3b8c 100644
--- a/ui/file_manager/file_manager/foreground/js/providers_model.js
+++ b/ui/file_manager/file_manager/foreground/js/providers_model.js
@@ -178,10 +178,9 @@
  * @param {string} providerId
  */
 ProvidersModel.prototype.requestMount = providerId => {
-  chrome.fileManagerPrivate.addProvidedFileSystem(
-      assert(providerId), () => {
-        if (chrome.runtime.lastError) {
-          console.error(chrome.runtime.lastError.message);
-        }
-      });
+  chrome.fileManagerPrivate.addProvidedFileSystem(assert(providerId), () => {
+    if (chrome.runtime.lastError) {
+      console.error(chrome.runtime.lastError.message);
+    }
+  });
 };
diff --git a/ui/file_manager/file_manager/foreground/js/quick_view_controller.js b/ui/file_manager/file_manager/foreground/js/quick_view_controller.js
index 8246a341..2382eeb9 100644
--- a/ui/file_manager/file_manager/foreground/js/quick_view_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/quick_view_controller.js
@@ -166,7 +166,8 @@
   quickView.onOpenInNewButtonTap = this.onOpenInNewButtonTap_.bind(this);
 
   const toolTip = this.quickView_.$$('files-tooltip');
-  const elems = this.quickView_.$$('#toolbar').querySelectorAll('[has-tooltip]');
+  const elems =
+      this.quickView_.$$('#toolbar').querySelectorAll('[has-tooltip]');
   toolTip.addTargets(elems);
 };
 
@@ -318,7 +319,7 @@
   this.quickViewUma_.onEntryChanged(entry);
   return Promise
       .all([
-        this.metadataModel_.get([entry], ['thumbnailUrl']),
+        this.metadataModel_.get([entry], ['thumbnailUrl', 'mediaMimeType']),
         this.getAvailableTasks_(entry)
       ])
       .then(values => {
@@ -340,18 +341,17 @@
  */
 QuickViewController.prototype.onMetadataLoaded_ = function(
     entry, items, tasks) {
-  return this.getQuickViewParameters_(entry, items, tasks)
-      .then(params => {
-        this.quickView_.type = params.type || '';
-        this.quickView_.subtype = params.subtype || '';
-        this.quickView_.filePath = params.filePath || '';
-        this.quickView_.hasTask = params.hasTask || false;
-        this.quickView_.contentUrl = params.contentUrl || '';
-        this.quickView_.videoPoster = params.videoPoster || '';
-        this.quickView_.audioArtwork = params.audioArtwork || '';
-        this.quickView_.autoplay = params.autoplay || false;
-        this.quickView_.browsable = params.browsable || false;
-      });
+  return this.getQuickViewParameters_(entry, items, tasks).then(params => {
+    this.quickView_.type = params.type || '';
+    this.quickView_.subtype = params.subtype || '';
+    this.quickView_.filePath = params.filePath || '';
+    this.quickView_.hasTask = params.hasTask || false;
+    this.quickView_.contentUrl = params.contentUrl || '';
+    this.quickView_.videoPoster = params.videoPoster || '';
+    this.quickView_.audioArtwork = params.audioArtwork || '';
+    this.quickView_.autoplay = params.autoplay || false;
+    this.quickView_.browsable = params.browsable || false;
+  });
 };
 
 /**
@@ -379,7 +379,7 @@
 QuickViewController.prototype.getQuickViewParameters_ = function(
     entry, items, tasks) {
   const item = items[0];
-  const typeInfo = FileType.getType(entry);
+  const typeInfo = FileType.getType(entry, item.mediaMimeType);
   const type = typeInfo.type;
 
   /** @type {!QuickViewParams} */
@@ -391,30 +391,28 @@
   };
 
   const volumeInfo = this.volumeManager_.getVolumeInfo(entry);
-  const localFile =
-      volumeInfo &&
-      QuickViewController.LOCAL_VOLUME_TYPES_.indexOf(
-          volumeInfo.volumeType) >= 0;
+  const localFile = volumeInfo &&
+      QuickViewController.LOCAL_VOLUME_TYPES_.indexOf(volumeInfo.volumeType) >=
+          0;
 
   if (!localFile) {
     // For Drive files, display a thumbnail if there is one.
     if (item.thumbnailUrl) {
-      return this.loadThumbnailFromDrive_(item.thumbnailUrl)
-          .then(result => {
-            if (result.status === 'success') {
-              if (params.type == 'video') {
-                params.videoPoster = result.data;
-              } else if (params.type == 'image') {
-                params.contentUrl = result.data;
-              } else {
-                // TODO(sashab): Rather than re-use 'image', create a new type
-                // here, e.g. 'thumbnail'.
-                params.type = 'image';
-                params.contentUrl = result.data;
-              }
-            }
-            return params;
-          });
+      return this.loadThumbnailFromDrive_(item.thumbnailUrl).then(result => {
+        if (result.status === 'success') {
+          if (params.type == 'video') {
+            params.videoPoster = result.data;
+          } else if (params.type == 'image') {
+            params.contentUrl = result.data;
+          } else {
+            // TODO(sashab): Rather than re-use 'image', create a new type
+            // here, e.g. 'thumbnail'.
+            params.type = 'image';
+            params.contentUrl = result.data;
+          }
+        }
+        return params;
+      });
     }
 
     // We ask user to open it with external app.
@@ -462,6 +460,14 @@
             } else {
               break;
             }
+          case 'text':
+            if (typeInfo.subtype === 'TXT') {
+              params.contentUrl = URL.createObjectURL(file);
+              params.browsable = true;
+              return params;
+            } else {
+              break;
+            }
         }
         const browsable = tasks.some(task => {
           return ['view-in-browser', 'view-pdf'].includes(
diff --git a/ui/file_manager/file_manager/foreground/js/quick_view_uma.js b/ui/file_manager/file_manager/foreground/js/quick_view_uma.js
index 70e16f9..3571d75 100644
--- a/ui/file_manager/file_manager/foreground/js/quick_view_uma.js
+++ b/ui/file_manager/file_manager/foreground/js/quick_view_uma.js
@@ -115,11 +115,12 @@
   }
   // Record stats of dialog types. It must be in sync with
   // FileDialogType enum in tools/metrics/histograms/histogram.xml.
-  metrics.recordEnum('QuickView.DialogType', this.dialogType_,
-      [DialogType.SELECT_FOLDER,
-       DialogType.SELECT_UPLOAD_FOLDER,
-       DialogType.SELECT_SAVEAS_FILE,
-       DialogType.SELECT_OPEN_FILE,
-       DialogType.SELECT_OPEN_MULTI_FILE,
-       DialogType.FULL_PAGE]);
+  metrics.recordEnum('QuickView.DialogType', this.dialogType_, [
+    DialogType.SELECT_FOLDER,
+    DialogType.SELECT_UPLOAD_FOLDER,
+    DialogType.SELECT_SAVEAS_FILE,
+    DialogType.SELECT_OPEN_FILE,
+    DialogType.SELECT_OPEN_MULTI_FILE,
+    DialogType.FULL_PAGE,
+  ]);
 };
diff --git a/ui/file_manager/file_manager/foreground/js/scan_controller.js b/ui/file_manager/file_manager/foreground/js/scan_controller.js
index b8b31d8bc..d6f8a357 100644
--- a/ui/file_manager/file_manager/foreground/js/scan_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/scan_controller.js
@@ -14,10 +14,7 @@
  * @struct
  */
 function ScanController(
-    directoryModel,
-    listContainer,
-    spinnerController,
-    commandHandler,
+    directoryModel, listContainer, spinnerController, commandHandler,
     selectionHandler) {
   /**
    * @type {!DirectoryModel}
diff --git a/ui/file_manager/file_manager/foreground/js/search_controller.js b/ui/file_manager/file_manager/foreground/js/search_controller.js
index c2a49668..17965a4 100644
--- a/ui/file_manager/file_manager/foreground/js/search_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/search_controller.js
@@ -154,7 +154,7 @@
       {
         query: searchString,
         types: 'ALL',
-        maxResults: 4
+        maxResults: 4,
       },
       suggestions => {
         this.autocompleteSuggestionsBusy_ = false;
@@ -186,8 +186,8 @@
   // If the entry is the search item or no entry is selected, just change to
   // the search result.
   if (!selectedItem || selectedItem.isHeaderItem) {
-    const query = selectedItem ?
-        selectedItem.searchQuery : this.searchBox_.inputElement.value;
+    const query = selectedItem ? selectedItem.searchQuery :
+                                 this.searchBox_.inputElement.value;
     this.search_(query);
     return;
   }
@@ -223,12 +223,10 @@
       return;
     }
     // If the parent entry can be /drive/other.
-    this.directoryModel_.changeDirectoryEntry(
-        parentEntry,
-        () => {
-          this.directoryModel_.selectEntry(entry);
-          this.taskController_.executeEntryTask(entry);
-        });
+    this.directoryModel_.changeDirectoryEntry(parentEntry, () => {
+      this.directoryModel_.selectEntry(entry);
+      this.taskController_.executeEntryTask(entry);
+    });
   });
 };
 
@@ -238,7 +236,6 @@
  * @private
  */
 SearchController.prototype.search_ = function(searchString) {
-
   const onSearchRescan = function() {
     // If the current location is somewhere in Drive, all files in Drive can
     // be listed as search results regardless of current location.
@@ -254,12 +251,9 @@
   };
 
   const onClearSearch = function() {
-    this.locationLine_.show(
-        this.directoryModel_.getCurrentDirEntry());
+    this.locationLine_.show(this.directoryModel_.getCurrentDirEntry());
   };
 
   this.directoryModel_.search(
-      searchString,
-      onSearchRescan.bind(this),
-      onClearSearch.bind(this));
+      searchString, onSearchRescan.bind(this), onClearSearch.bind(this));
 };
diff --git a/ui/file_manager/file_manager/foreground/js/sort_menu_controller.js b/ui/file_manager/file_manager/foreground/js/sort_menu_controller.js
index d8fdcb0..5e88a77 100644
--- a/ui/file_manager/file_manager/foreground/js/sort_menu_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/sort_menu_controller.js
@@ -17,17 +17,17 @@
   this.fileListModel_ = fileListModel;
 
   /** @private {!HTMLElement} */
-  this.sortByNameButton_ = queryRequiredElement(
-      '#sort-menu-sort-by-name', sortButton.menu);
+  this.sortByNameButton_ =
+      queryRequiredElement('#sort-menu-sort-by-name', sortButton.menu);
   /** @private {!HTMLElement} */
-  this.sortBySizeButton_ = queryRequiredElement(
-      '#sort-menu-sort-by-size', sortButton.menu);
+  this.sortBySizeButton_ =
+      queryRequiredElement('#sort-menu-sort-by-size', sortButton.menu);
   /** @private {!HTMLElement} */
-  this.sortByTypeButton_ = queryRequiredElement(
-      '#sort-menu-sort-by-type', sortButton.menu);
+  this.sortByTypeButton_ =
+      queryRequiredElement('#sort-menu-sort-by-type', sortButton.menu);
   /** @private {!HTMLElement} */
-  this.sortByDateButton_ = queryRequiredElement(
-      '#sort-menu-sort-by-date', sortButton.menu);
+  this.sortByDateButton_ =
+      queryRequiredElement('#sort-menu-sort-by-date', sortButton.menu);
 
   sortButton.addEventListener('menushow', this.updateCheckmark_.bind(this));
   sortButton.addEventListener('menuhide', this.onHideSortMenu_.bind(this));
@@ -44,8 +44,8 @@
   this.setCheckStatus_(this.sortByNameButton_, sortField === 'name');
   this.setCheckStatus_(this.sortBySizeButton_, sortField === 'size');
   this.setCheckStatus_(this.sortByTypeButton_, sortField === 'type');
-  this.setCheckStatus_(this.sortByDateButton_,
-                       sortField === 'modificationTime');
+  this.setCheckStatus_(
+      this.sortByDateButton_, sortField === 'modificationTime');
 };
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.js
index 18279ed..e5b12861 100644
--- a/ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.js
@@ -38,12 +38,15 @@
   controller.blink();
 
   return reportPromise(
-    waitForMutation(spinner).then(() => {
-      assertFalse(spinner.hidden);
-      return waitForMutation(spinner);
-    }).then(() => {
-      assertTrue(spinner.hidden);
-    }), callback);
+      waitForMutation(spinner)
+          .then(() => {
+            assertFalse(spinner.hidden);
+            return waitForMutation(spinner);
+          })
+          .then(() => {
+            assertTrue(spinner.hidden);
+          }),
+      callback);
 }
 
 function testShow(callback) {
@@ -51,19 +54,23 @@
   const hideCallback = controller.show();
 
   return reportPromise(
-    waitForMutation(spinner).then(() => {
-      assertFalse(spinner.hidden);
-      return new Promise((fulfill, reject) => {
-        setTimeout(fulfill, 0);
-      });
-    }).then(() => {
-      assertFalse(spinner.hidden);  // It should still be hidden.
-      // Call asynchronously, so the mutation observer catches the change.
-      setTimeout(hideCallback, 0);
-      return waitForMutation(spinner);
-    }).then(() => {
-      assertTrue(spinner.hidden);
-    }), callback);
+      waitForMutation(spinner)
+          .then(() => {
+            assertFalse(spinner.hidden);
+            return new Promise((fulfill, reject) => {
+              setTimeout(fulfill, 0);
+            });
+          })
+          .then(() => {
+            assertFalse(spinner.hidden);  // It should still be hidden.
+            // Call asynchronously, so the mutation observer catches the change.
+            setTimeout(hideCallback, 0);
+            return waitForMutation(spinner);
+          })
+          .then(() => {
+            assertTrue(spinner.hidden);
+          }),
+      callback);
 }
 
 function testShowDuringBlink(callback) {
@@ -72,23 +79,28 @@
   const hideCallback = controller.show();
 
   return reportPromise(
-    waitForMutation(spinner).then(() => {
-      assertFalse(spinner.hidden);
-      return new Promise((fulfill, reject) => {
-        setTimeout(fulfill, 0);
-      });
-    }).then(() => {
-      assertFalse(spinner.hidden);
-      hideCallback();
-      return new Promise((fulfill, reject) => {
-        setTimeout(fulfill, 0);
-      });
-    }).then(() => {
-      assertFalse(spinner.hidden);
-      return waitForMutation(spinner);
-    }).then(() => {
-      assertTrue(spinner.hidden);
-    }), callback);
+      waitForMutation(spinner)
+          .then(() => {
+            assertFalse(spinner.hidden);
+            return new Promise((fulfill, reject) => {
+              setTimeout(fulfill, 0);
+            });
+          })
+          .then(() => {
+            assertFalse(spinner.hidden);
+            hideCallback();
+            return new Promise((fulfill, reject) => {
+              setTimeout(fulfill, 0);
+            });
+          })
+          .then(() => {
+            assertFalse(spinner.hidden);
+            return waitForMutation(spinner);
+          })
+          .then(() => {
+            assertTrue(spinner.hidden);
+          }),
+      callback);
 }
 
 function testStackedShows(callback) {
@@ -99,23 +111,28 @@
   hideCallbacks.push(controller.show());
 
   return reportPromise(
-    waitForMutation(spinner).then(() => {
-      assertFalse(spinner.hidden);
-      return new Promise((fulfill, reject) => {
-        setTimeout(fulfill, 0);
-      });
-    }).then(() => {
-      assertFalse(spinner.hidden);
-      hideCallbacks[1]();
-      return new Promise((fulfill, reject) => {
-        setTimeout(fulfill, 0);
-      });
-    }).then(() => {
-      assertFalse(spinner.hidden);
-      // Call asynchronously, so the mutation observer catches the change.
-      setTimeout(hideCallbacks[0], 0);
-      return waitForMutation(spinner);
-    }).then(() => {
-      assertTrue(spinner.hidden);
-    }), callback);
+      waitForMutation(spinner)
+          .then(() => {
+            assertFalse(spinner.hidden);
+            return new Promise((fulfill, reject) => {
+              setTimeout(fulfill, 0);
+            });
+          })
+          .then(() => {
+            assertFalse(spinner.hidden);
+            hideCallbacks[1]();
+            return new Promise((fulfill, reject) => {
+              setTimeout(fulfill, 0);
+            });
+          })
+          .then(() => {
+            assertFalse(spinner.hidden);
+            // Call asynchronously, so the mutation observer catches the change.
+            setTimeout(hideCallbacks[0], 0);
+            return waitForMutation(spinner);
+          })
+          .then(() => {
+            assertTrue(spinner.hidden);
+          }),
+      callback);
 }
diff --git a/ui/file_manager/file_manager/foreground/js/task_controller.js b/ui/file_manager/file_manager/foreground/js/task_controller.js
index 0070b71f..d9bb438 100644
--- a/ui/file_manager/file_manager/foreground/js/task_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/task_controller.js
@@ -100,8 +100,8 @@
    * @private {!cr.ui.Command}
    * @const
    */
-  this.defaultTaskCommand_ = assertInstanceof(
-      document.querySelector('#default-task'), cr.ui.Command);
+  this.defaultTaskCommand_ =
+      assertInstanceof(document.querySelector('#default-task'), cr.ui.Command);
 
   /**
    * More actions command that uses #open-with as selector due to the open-with
@@ -239,30 +239,29 @@
 TaskController.prototype.changeDefaultTask_ = function(selection, task) {
   const entries = selection.entries;
 
-  Promise.all(entries.map((entry) => this.getMimeType_(entry))).then(mimeTypes => {
-    chrome.fileManagerPrivate.setDefaultTask(
-        task.taskId,
-        entries,
-        mimeTypes,
-        util.checkAPIError);
-    this.metadataUpdateController_.refreshCurrentDirectoryMetadata();
+  Promise.all(entries.map((entry) => this.getMimeType_(entry)))
+      .then(mimeTypes => {
+        chrome.fileManagerPrivate.setDefaultTask(
+            task.taskId, entries, mimeTypes, util.checkAPIError);
+        this.metadataUpdateController_.refreshCurrentDirectoryMetadata();
 
-    // Update task menu button unless the task button was updated other
-    // selection.
-    if (this.selectionHandler_.selection === selection) {
-      this.tasks_ = null;
-      this.getFileTasks()
-          .then(tasks => {
-            tasks.display(this.ui_.taskMenuButton, this.ui_.shareMenuButton);
-          })
-          .catch(error => {
-            if (error) {
-              console.error(error.stack || error);
-            }
-          });
-    }
-    this.selectionHandler_.onFileSelectionChanged();
-  });
+        // Update task menu button unless the task button was updated other
+        // selection.
+        if (this.selectionHandler_.selection === selection) {
+          this.tasks_ = null;
+          this.getFileTasks()
+              .then(tasks => {
+                tasks.display(
+                    this.ui_.taskMenuButton, this.ui_.shareMenuButton);
+              })
+              .catch(error => {
+                if (error) {
+                  console.error(error.stack || error);
+                }
+              });
+        }
+        this.selectionHandler_.onFileSelectionChanged();
+      });
 };
 
 /**
@@ -371,29 +370,28 @@
     return this.tasks_;
   }
   this.tasksEntries_ = selection.entries;
-  this.tasks_ =
-      selection.computeAdditional(this.metadataModel_).then(() => {
-        if (this.selectionHandler_.selection !== selection) {
-          if (util.isSameEntries(this.tasksEntries_, selection.entries)) {
-            this.tasks_ = null;
+  this.tasks_ = selection.computeAdditional(this.metadataModel_).then(() => {
+    if (this.selectionHandler_.selection !== selection) {
+      if (util.isSameEntries(this.tasksEntries_, selection.entries)) {
+        this.tasks_ = null;
+      }
+      return Promise.reject();
+    }
+    return FileTasks
+        .create(
+            this.volumeManager_, this.metadataModel_, this.directoryModel_,
+            this.ui_, selection.entries, assert(selection.mimeTypes),
+            this.taskHistory_, this.namingController_, this.crostini_)
+        .then(tasks => {
+          if (this.selectionHandler_.selection !== selection) {
+            if (util.isSameEntries(this.tasksEntries_, selection.entries)) {
+              this.tasks_ = null;
+            }
+            return Promise.reject();
           }
-          return Promise.reject();
-        }
-        return FileTasks
-            .create(
-                this.volumeManager_, this.metadataModel_, this.directoryModel_,
-                this.ui_, selection.entries, assert(selection.mimeTypes),
-                this.taskHistory_, this.namingController_, this.crostini_)
-            .then(tasks => {
-              if (this.selectionHandler_.selection !== selection) {
-                if (util.isSameEntries(this.tasksEntries_, selection.entries)) {
-                  this.tasks_ = null;
-                }
-                return Promise.reject();
-              }
-              return tasks;
-            });
-      });
+          return tasks;
+        });
+  });
   return this.tasks_;
 };
 
diff --git a/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js b/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js
index ce2ee5e..d815266 100644
--- a/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js
+++ b/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js
@@ -18,8 +18,9 @@
  * @param {number=} opt_priority Priority, the highest is 0. default: 2.
  * @constructor
  */
-function ThumbnailLoader(entry, opt_loaderType, opt_metadata, opt_mediaType,
-    opt_loadTargets, opt_priority) {
+function ThumbnailLoader(
+    entry, opt_loaderType, opt_metadata, opt_mediaType, opt_loadTargets,
+    opt_priority) {
   const loadTargets = opt_loadTargets || [
     ThumbnailLoader.LoadTarget.CONTENT_METADATA,
     ThumbnailLoader.LoadTarget.EXTERNAL_METADATA,
@@ -108,7 +109,7 @@
     // Use fallback as the primary thumbnail.
     this.thumbnailUrl_ = this.fallbackUrl_;
     this.fallbackUrl_ = null;
-  } // else the generic thumbnail based on the media type will be used.
+  }  // else the generic thumbnail based on the media type will be used.
 }
 
 /**
@@ -124,10 +125,10 @@
  * @enum {number}
  */
 ThumbnailLoader.FillMode = {
-  FILL: 0,  // Fill whole box. Image may be cropped.
-  FIT: 1,   // Keep aspect ratio, do not crop.
+  FILL: 0,       // Fill whole box. Image may be cropped.
+  FIT: 1,        // Keep aspect ratio, do not crop.
   OVER_FILL: 2,  // Fill whole box with possible stretching.
-  AUTO: 3   // Try to fill, but if incompatible aspect ratio, then fit.
+  AUTO: 3        // Try to fill, but if incompatible aspect ratio, then fit.
 };
 
 /**
@@ -220,10 +221,9 @@
 
   // TODO(mtomasz): Smarter calculation of the requested size.
   const wasAttached = box.ownerDocument.contains(box);
-  const modificationTime = this.metadata_ &&
-                         this.metadata_.filesystem &&
-                         this.metadata_.filesystem.modificationTime &&
-                         this.metadata_.filesystem.modificationTime.getTime();
+  const modificationTime = this.metadata_ && this.metadata_.filesystem &&
+      this.metadata_.filesystem.modificationTime &&
+      this.metadata_.filesystem.modificationTime.getTime();
   this.taskId_ = ImageLoaderClient.loadToImage(
       LoadImageRequest.createRequest({
         url: this.thumbnailUrl_,
@@ -234,8 +234,7 @@
         timestamp: modificationTime,
         orientation: this.transform_
       }),
-      this.image_, () => {},
-      () => {
+      this.image_, () => {}, () => {
         this.image_.onerror(new Event('load-error'));
       });
 };
@@ -255,15 +254,15 @@
  * TODO(yawano): Support cancel operation.
  */
 ThumbnailLoader.prototype.loadAsDataUrl = function(fillMode) {
-  assert(fillMode === ThumbnailLoader.FillMode.FIT ||
+  assert(
+      fillMode === ThumbnailLoader.FillMode.FIT ||
       fillMode === ThumbnailLoader.FillMode.OVER_FILL);
 
   return new Promise((resolve, reject) => {
     // Load by using ImageLoaderClient.
-    const modificationTime = this.metadata_ &&
-                           this.metadata_.filesystem &&
-                           this.metadata_.filesystem.modificationTime &&
-                           this.metadata_.filesystem.modificationTime.getTime();
+    const modificationTime = this.metadata_ && this.metadata_.filesystem &&
+        this.metadata_.filesystem.modificationTime &&
+        this.metadata_.filesystem.modificationTime.getTime();
     let request = LoadImageRequest.createRequest({
       url: this.thumbnailUrl_,
       maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH,
@@ -348,10 +347,9 @@
   this.image_.onerror = callback.bind(null, false);
 
   // TODO(mtomasz): Smarter calculation of the requested size.
-  const modificationTime = this.metadata_ &&
-                         this.metadata_.filesystem &&
-                         this.metadata_.filesystem.modificationTime &&
-                         this.metadata_.filesystem.modificationTime.getTime();
+  const modificationTime = this.metadata_ && this.metadata_.filesystem &&
+      this.metadata_.filesystem.modificationTime &&
+      this.metadata_.filesystem.modificationTime.getTime();
   this.taskId_ = ImageLoaderClient.loadToImage(
       LoadImageRequest.createRequest({
         url: this.thumbnailUrl_,
@@ -362,8 +360,7 @@
         timestamp: modificationTime,
         orientation: this.transform_
       }),
-      this.image_, () => {},
-      () => {
+      this.image_, () => {}, () => {
         this.image_.onerror(new Event('load-error'));
       });
 };
@@ -411,8 +408,9 @@
   }
 
   this.renderMedia_();
-  const attachableMedia = this.loaderType_ === ThumbnailLoader.LoaderType.CANVAS ?
-      this.canvas_ : this.image_;
+  const attachableMedia =
+      this.loaderType_ === ThumbnailLoader.LoaderType.CANVAS ? this.canvas_ :
+                                                               this.image_;
 
   ThumbnailLoader.centerImage_(
       box, attachableMedia, fillMode, autoFillThreshold, boxWidth, boxHeight);
@@ -434,8 +432,8 @@
  */
 ThumbnailLoader.prototype.getImage = function() {
   this.renderMedia_();
-  return (this.loaderType_ === ThumbnailLoader.LoaderType.IMAGE) ?
-      this.image_ : this.canvas_;
+  return (this.loaderType_ === ThumbnailLoader.LoaderType.IMAGE) ? this.image_ :
+                                                                   this.canvas_;
 };
 
 /**
@@ -454,69 +452,69 @@
  * @param {number} boxHeight Container box's height.
  * @private
  */
-ThumbnailLoader.centerImage_ = (box, img, fillMode, autoFillThreshold, boxWidth, boxHeight) => {
-  const imageWidth = img.width;
-  const imageHeight = img.height;
+ThumbnailLoader.centerImage_ =
+    (box, img, fillMode, autoFillThreshold, boxWidth, boxHeight) => {
+      const imageWidth = img.width;
+      const imageHeight = img.height;
 
-  let fractionX;
-  let fractionY;
+      let fractionX;
+      let fractionY;
 
-  let fill;
-  switch (fillMode) {
-    case ThumbnailLoader.FillMode.FILL:
-    case ThumbnailLoader.FillMode.OVER_FILL:
-      fill = true;
-      break;
-    case ThumbnailLoader.FillMode.FIT:
-      fill = false;
-      break;
-    case ThumbnailLoader.FillMode.AUTO:
-      const imageRatio = imageWidth / imageHeight;
-      let boxRatio = 1.0;
-      if (boxWidth && boxHeight) {
-        boxRatio = boxWidth / boxHeight;
+      let fill;
+      switch (fillMode) {
+        case ThumbnailLoader.FillMode.FILL:
+        case ThumbnailLoader.FillMode.OVER_FILL:
+          fill = true;
+          break;
+        case ThumbnailLoader.FillMode.FIT:
+          fill = false;
+          break;
+        case ThumbnailLoader.FillMode.AUTO:
+          const imageRatio = imageWidth / imageHeight;
+          let boxRatio = 1.0;
+          if (boxWidth && boxHeight) {
+            boxRatio = boxWidth / boxHeight;
+          }
+          // Cropped area in percents.
+          const ratioFactor = boxRatio / imageRatio;
+          fill = (ratioFactor >= 1.0 - autoFillThreshold) &&
+              (ratioFactor <= 1.0 + autoFillThreshold);
+          break;
       }
-      // Cropped area in percents.
-      const ratioFactor = boxRatio / imageRatio;
-      fill = (ratioFactor >= 1.0 - autoFillThreshold) &&
-             (ratioFactor <= 1.0 + autoFillThreshold);
-      break;
-  }
 
-  if (boxWidth && boxHeight) {
-    // When we know the box size we can position the image correctly even
-    // in a non-square box.
-    const fitScaleX = boxWidth / imageWidth;
-    const fitScaleY = boxHeight / imageHeight;
+      if (boxWidth && boxHeight) {
+        // When we know the box size we can position the image correctly even
+        // in a non-square box.
+        const fitScaleX = boxWidth / imageWidth;
+        const fitScaleY = boxHeight / imageHeight;
 
-    let scale = fill ?
-        Math.max(fitScaleX, fitScaleY) :
-        Math.min(fitScaleX, fitScaleY);
+        let scale = fill ? Math.max(fitScaleX, fitScaleY) :
+                           Math.min(fitScaleX, fitScaleY);
 
-    if (fillMode !== ThumbnailLoader.FillMode.OVER_FILL) {
-      scale = Math.min(scale, 1);  // Never overscale.
-    }
+        if (fillMode !== ThumbnailLoader.FillMode.OVER_FILL) {
+          scale = Math.min(scale, 1);  // Never overscale.
+        }
 
-    fractionX = imageWidth * scale / boxWidth;
-    fractionY = imageHeight * scale / boxHeight;
-  } else {
-    // We do not know the box size so we assume it is square.
-    // Compute the image position based only on the image dimensions.
-    // First try vertical fit or horizontal fill.
-    fractionX = imageWidth / imageHeight;
-    fractionY = 1;
-    if ((fractionX < 1) === !!fill) {  // Vertical fill or horizontal fit.
-      fractionY = 1 / fractionX;
-      fractionX = 1;
-    }
-  }
+        fractionX = imageWidth * scale / boxWidth;
+        fractionY = imageHeight * scale / boxHeight;
+      } else {
+        // We do not know the box size so we assume it is square.
+        // Compute the image position based only on the image dimensions.
+        // First try vertical fit or horizontal fill.
+        fractionX = imageWidth / imageHeight;
+        fractionY = 1;
+        if ((fractionX < 1) === !!fill) {  // Vertical fill or horizontal fit.
+          fractionY = 1 / fractionX;
+          fractionX = 1;
+        }
+      }
 
-  function percent(fraction) {
-    return (fraction * 100).toFixed(2) + '%';
-  }
+      function percent(fraction) {
+        return (fraction * 100).toFixed(2) + '%';
+      }
 
-  img.style.width = percent(fractionX);
-  img.style.height = percent(fractionY);
-  img.style.left = percent((1 - fractionX) / 2);
-  img.style.top = percent((1 - fractionY) / 2);
-};
+      img.style.width = percent(fractionX);
+      img.style.height = percent(fractionY);
+      img.style.left = percent((1 - fractionX) / 2);
+      img.style.top = percent((1 - fractionY) / 2);
+    };
diff --git a/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.js b/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.js
index 0bc75a2d..b220b3a 100644
--- a/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.js
@@ -76,9 +76,10 @@
   const thumbnailLoader = new ThumbnailLoader(entry);
   reportPromise(
       thumbnailLoader.loadAsDataUrl(ThumbnailLoader.FillMode.OVER_FILL)
-      .then(result => {
-        assertEquals('imageDataUrl', result.data);
-      }), callback);
+          .then(result => {
+            assertEquals('imageDataUrl', result.data);
+          }),
+      callback);
 }
 
 function testLoadAsDataUrlFromExifThumbnail(callback) {
@@ -90,8 +91,8 @@
 
   const metadata = {
     thumbnail: {
-      url: generateSampleImageDataUrl(32, 32)
-    }
+      url: generateSampleImageDataUrl(32, 32),
+    },
   };
 
   const fileSystem = new MockFileSystem('volume-id');
@@ -99,9 +100,10 @@
   const thumbnailLoader = new ThumbnailLoader(entry, undefined, metadata);
   reportPromise(
       thumbnailLoader.loadAsDataUrl(ThumbnailLoader.FillMode.OVER_FILL)
-      .then(result => {
-        assertEquals(metadata.thumbnail.url, result.data);
-      }), callback);
+          .then(result => {
+            assertEquals(metadata.thumbnail.url, result.data);
+          }),
+      callback);
 }
 
 function testLoadAsDataUrlFromExifThumbnailPropagatesTransform(callback) {
@@ -133,11 +135,12 @@
   const thumbnailLoader = new ThumbnailLoader(entry, undefined, metadata);
   reportPromise(
       thumbnailLoader.loadAsDataUrl(ThumbnailLoader.FillMode.OVER_FILL)
-      .then(result => {
-        assertEquals(32, result.width);
-        assertEquals(64, result.height);
-        assertEquals(generateSampleImageDataUrl(32, 64), result.data);
-      }), callback);
+          .then(result => {
+            assertEquals(32, result.width);
+            assertEquals(64, result.height);
+            assertEquals(generateSampleImageDataUrl(32, 64), result.data);
+          }),
+      callback);
 }
 
 function testLoadAsDataUrlFromExternal(callback) {
@@ -167,9 +170,10 @@
   const thumbnailLoader = new ThumbnailLoader(entry, undefined, metadata);
   reportPromise(
       thumbnailLoader.loadAsDataUrl(ThumbnailLoader.FillMode.OVER_FILL)
-      .then(result => {
-        assertEquals(externalThumbnailDataUrl, result.data);
-      }), callback);
+          .then(result => {
+            assertEquals(externalThumbnailDataUrl, result.data);
+          }),
+      callback);
 }
 
 function testLoadDetachedFromExifInCavnasModeThumbnailDoesNotRotate(callback) {
@@ -204,12 +208,13 @@
       new ThumbnailLoader(entry, ThumbnailLoader.LoaderType.CANVAS, metadata);
 
   reportPromise(
-    new Promise((resolve, reject) => {
-      thumbnailLoader.loadDetachedImage(resolve);
-    }).then(() => {
-      const image = thumbnailLoader.getImage();
-      // No need to rotate by loadDetachedImage() as it's already done.
-      assertEquals(32, image.width);
-      assertEquals(64, image.height);
-    }), callback);
+      new Promise((resolve, reject) => {
+        thumbnailLoader.loadDetachedImage(resolve);
+      }).then(() => {
+        const image = thumbnailLoader.getImage();
+        // No need to rotate by loadDetachedImage() as it's already done.
+        assertEquals(32, image.width);
+        assertEquals(64, image.height);
+      }),
+      callback);
 }
diff --git a/ui/file_manager/file_manager/foreground/js/toolbar_controller.js b/ui/file_manager/file_manager/foreground/js/toolbar_controller.js
index 4b45ebb..ec4d97a 100644
--- a/ui/file_manager/file_manager/foreground/js/toolbar_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/toolbar_controller.js
@@ -17,12 +17,9 @@
  * @constructor
  * @struct
  */
-function ToolbarController(toolbar,
-                           navigationList,
-                           listContainer,
-                           locationLine,
-                           selectionHandler,
-                           directoryModel) {
+function ToolbarController(
+    toolbar, navigationList, listContainer, locationLine, selectionHandler,
+    directoryModel) {
   /**
    * @private {!HTMLElement}
    * @const
@@ -108,12 +105,14 @@
       'relayout', this.onNavigationListRelayout_.bind(this));
 
   // Watch visibility of toolbar buttons to update the width of location line.
-  const observer = new MutationObserver(this.onToolbarButtonsMutated_.bind(this));
+  const observer =
+      new MutationObserver(this.onToolbarButtonsMutated_.bind(this));
   const toolbarButtons =
       this.toolbar_.querySelectorAll('.icon-button, .combobutton');
   for (let i = 0; i < toolbarButtons.length; i++) {
-    observer.observe(toolbarButtons[i],
-                     /** @type MutationObserverInit */({attributes: true}));
+    observer.observe(
+        toolbarButtons[i],
+        /** @type MutationObserverInit */ ({attributes: true}));
   }
 }
 
@@ -197,8 +196,8 @@
  */
 ToolbarController.prototype.onNavigationListRelayout_ = function() {
   // Make the width of spacer same as the width of navigation list.
-  const navWidth = parseFloat(
-      window.getComputedStyle(this.navigationList_).width);
+  const navWidth =
+      parseFloat(window.getComputedStyle(this.navigationList_).width);
   this.cancelSelectionButtonWrapper_.style.width = navWidth + 'px';
 };
 
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index 892e1dd..aa8ee5b 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -252,6 +252,7 @@
     </cr-menu>
 
     <cr-menu id="sort-menu" class="chrome-menu files-menu"
+             aria-label="$i18n{SORT_BUTTON_TOOLTIP}"
              menu-item-selector="cr-menu-item">
       <cr-menu-item id="sort-menu-sort-by-name"
                     command="#sort-by-name"></cr-menu-item>
@@ -264,6 +265,7 @@
     </cr-menu>
 
     <cr-menu id="gear-menu" class="chrome-menu files-menu" showShortcuts
+             aria-label="$i18n{GEAR_BUTTON_TOOLTIP}"
              menu-item-selector="cr-menu-item, hr">
       <cr-menu-item command="#paste-into-current-folder" visibleif="full-page"></cr-menu-item>
       <hr visibleif="full-page">
@@ -304,10 +306,12 @@
     </cr-menu>
 
     <cr-menu id="tasks-menu" class="chrome-menu files-menu"
+             aria-label="$i18n{OPEN_WITH_BUTTON_LABEL}"
              menu-item-selector="cr-menu-item, hr">
     </cr-menu>
 
     <cr-menu id="share-menu" class="chrome-menu files-menu"
+             aria-label="$i18n{MORE_ACTIONS_BUTTON_LABEL}"
              menu-item-selector="cr-menu-item, hr">
       <cr-menu-item command="#share"></cr-menu-item>
       <cr-menu-item command="#share-with-linux"></cr-menu-item>
diff --git a/ui/file_manager/image_loader/piex/tests.html b/ui/file_manager/image_loader/piex/tests.html
index 329e613..91c72f9 100644
--- a/ui/file_manager/image_loader/piex/tests.html
+++ b/ui/file_manager/image_loader/piex/tests.html
@@ -117,7 +117,8 @@
     console.log('test:', JSON.stringify(image));
 
     let canvas = document.createElement('canvas');
-    Object.assign(canvas, { image.width, image.height });
+    canvas.width = image.width;
+    canvas.height = image.height;
     if (image.width > (window.screen.availWidth / 2))
       canvas.classList.add('zoom');
 
diff --git a/ui/file_manager/image_loader/piex/tests.js b/ui/file_manager/image_loader/piex/tests.js
index d5503537..ad1b934 100644
--- a/ui/file_manager/image_loader/piex/tests.js
+++ b/ui/file_manager/image_loader/piex/tests.js
@@ -44,6 +44,10 @@
     page.on('request', (request) => {
       console.log('Request: ', request.url());
     });
+
+    page.on('close', () => {
+      process.exit(1);
+    });
   }
 
   page.on('console', message => {
diff --git a/ui/file_manager/image_loader/piex/tests.sh b/ui/file_manager/image_loader/piex/tests.sh
index 07f3141..6f892d70 100755
--- a/ui/file_manager/image_loader/piex/tests.sh
+++ b/ui/file_manager/image_loader/piex/tests.sh
@@ -19,7 +19,7 @@
 kill ${HTTP_SERVER_PID} > /dev/null 2>&1
 
 # Compare their hash to the golden hash values.
-if [[ $(cmp tests.hash images.golden.hash) ]]; then
+if [[ $(cmp tests.hash images.golden.hash 2>&1) ]]; then
   echo "tests FAIL" || exit 1
 else
   echo "tests PASS"
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js
index a179ab7..4508127 100644
--- a/ui/file_manager/integration_tests/file_manager/quick_view.js
+++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -310,6 +310,43 @@
 };
 
 /**
+ * Tests opening Quick View with a document identified as text from file
+ * sniffing because it has no filename extension.
+ */
+testcase.openQuickViewSniffedText = async () => {
+  const caller = getCaller();
+
+  /**
+   * The text <webview> resides in the #quick-view shadow DOM, as a child of
+   * the #dialog element.
+   */
+  const webView = ['#quick-view', '#dialog[open] webview.text-content'];
+
+  // Open Files app on Downloads containing ENTRIES.plainText.
+  const appId =
+      await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.plainText], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.plainText.nameText);
+
+  // Wait for the Quick View <webview> to load and display its content.
+  function checkWebViewTextLoaded(elements) {
+    let haveElements = Array.isArray(elements) && elements.length === 1;
+    if (haveElements) {
+      haveElements = elements[0].styles.display.includes('block');
+    }
+    if (!haveElements || !elements[0].attributes.src) {
+      return pending(caller, 'Waiting for <webview> to load.');
+    }
+    return;
+  }
+  await repeatUntil(async () => {
+    return checkWebViewTextLoaded(await remoteCall.callRemoteTestUtil(
+        'deepQueryAllElements', appId, [webView, ['display']]));
+  });
+};
+
+/**
  * Tests opening Quick View and scrolling its <webview> which contains a tall
  * text document.
  */
@@ -685,12 +722,12 @@
    */
   const webView = ['#quick-view', 'files-safe-media[type="video"]', 'webview'];
 
-  // Open Files app on Downloads containing ENTRIES.world video.
+  // Open Files app on Downloads containing ENTRIES.webm video.
   const appId =
-      await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.world], []);
+      await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.webm], []);
 
   // Open the file in Quick View.
-  await openQuickView(appId, ENTRIES.world.nameText);
+  await openQuickView(appId, ENTRIES.webm.nameText);
 
   // Wait for the Quick View <webview> to load and display its content.
   function checkWebViewVideoLoaded(elements) {
diff --git a/ui/file_manager/integration_tests/test_util.js b/ui/file_manager/integration_tests/test_util.js
index ea9b570e77..3bbbf2f 100644
--- a/ui/file_manager/integration_tests/test_util.js
+++ b/ui/file_manager/integration_tests/test_util.js
@@ -498,6 +498,17 @@
     typeText: 'OGG video'
   }),
 
+  webm: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'world.webm',
+    targetPath: 'world.webm',
+    mimeType: 'video/webm',
+    lastModifiedTime: 'Jul 4, 2012, 10:35 AM',
+    nameText: 'world.webm',
+    sizeText: '17 KB',
+    typeText: 'WebM video'
+  }),
+
   video: new TestEntryInfo({
     type: EntryType.FILE,
     sourceFileName: 'video_long.ogv',
@@ -641,6 +652,16 @@
     typeText: 'Plain text',
   }),
 
+  plainText: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'plaintext',
+    targetPath: 'plaintext',
+    lastModifiedTime: 'Sep 4, 1998, 12:34 PM',
+    nameText: 'plaintext',
+    sizeText: '32 bytes',
+    typeText: 'Plain text',
+  }),
+
   tallHtml: new TestEntryInfo({
     type: EntryType.FILE,
     sourceFileName: 'tall.html',