diff --git a/DEPS b/DEPS
index f6eb34f..4dc5a3b 100644
--- a/DEPS
+++ b/DEPS
@@ -315,7 +315,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '460efa214171ec90f46285def504ac0894692422',
+  'angle_revision': 'c75adc3cf1dabc3a5178922fffc28a663b39244f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -378,7 +378,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': '9b0585389e2e19739ed3492415f8ded3f771b754',
+  'catapult_revision': '4793433248183dd073e608f655204d4acfdc7193',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -386,7 +386,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': 'd441bbafd39ca1cb827a67811ab63dd9f1f90059',
+  'devtools_frontend_revision': '556888db9a6044c7d7b3173e852f1ddf89b6f3f8',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -422,11 +422,11 @@
   # 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': 'bcbe527ecb670ffa35105fa82a1ae62a0e439ba9',
+  'dawn_revision': '9fcd768cf6f35383de3293484ab352ce366c544b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': '73c7fa8a2f104ae9f6cd84fb2d10bfaece59aa4c',
+  'quiche_revision': 'a338ea8277642f6d78022dc8e3aaed182a804413',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -818,7 +818,7 @@
 
   'src/clank': {
     'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' +
-    '130bc9859f6d8770f2406d164ed170740a765b31',
+    '02647eb999b2998bfe8f851a8a4a713302a074f3',
     'condition': 'checkout_android and checkout_src_internal and not checkout_clank_via_src_internal',
   },
 
@@ -1002,7 +1002,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'XL-7BvEmOjk2I9PKLeYKkahaBW1iI_5O23up19pvZzwC',
+          'version': 'h7h2tZ_Dqu-O57Bk14oz6B7AaJLu1naK5jGnsQ5vaJQC',
       },
     ],
     'condition': 'checkout_android',
@@ -1245,13 +1245,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '77355b7fe2b4a494cd785b6621d06880955c2816',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2c0a8c736a59044e4acc7be9e172343adc5c4310',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + 'cc58c5f3d991b96ca28eb13c3b639728d846d4e4',
+      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '0addf96b01a00ede048bf1dec87e61ed243b1433',
     'condition': 'checkout_src_internal',
   },
 
@@ -1851,7 +1851,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'eba1a78f3d741241b0dbee728561b61e9587a686',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '601b2f5e8c33a68b521346d6ce8ac899408d11b2',
+    Var('webrtc_git') + '/src.git' + '@' + 'fbbe415dd42f44b2f61e43848fed9a12c5c1853d',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -1921,7 +1921,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@124f4110fa09abf19754c12c649ec95c82fea19b',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d6d2381c60482a8e75722cb5c210190661646cf5',
     'condition': 'checkout_src_internal',
   },
 
@@ -1973,7 +1973,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'IYtTVHRC57ZjhJzuFiy6-gsSoXS6m8aWe5FOjXaWpHoC',
+        'version': 'tmjEGk6GqAPC9F0K_mdhLBw2tTooYZLK-LEEflL3vpIC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 67d57a0..fb7b5b6 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -363,7 +363,7 @@
 // camera app.
 BASE_FEATURE(kCameraAppMultiPageDocScan,
              "CameraAppMultiPageDocScan",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Controls whether the camera privacy switch toasts and notification should be
 // displayed.
@@ -1654,16 +1654,6 @@
              "VCBackgroundBlur",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Controls whether the vc background replace is enabled.
-BASE_FEATURE(kVCBackgroundReplace,
-             "VCBackgroundReplace",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-// Controls whether the vc portrait relighting is enabled.
-BASE_FEATURE(kVCPortraitRelighting,
-             "VCPortraitRelighting",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // Enables or disables the Quick Settings Network revamp, which updates Network
 // Quick Settings UI and related infrastructure. See https://crbug.com/1169479.
 BASE_FEATURE(kQuickSettingsNetworkRevamp,
@@ -3021,14 +3011,6 @@
   return base::FeatureList::IsEnabled(kVCBackgroundBlur);
 }
 
-bool IsVCBackgroundReplaceEnabled() {
-  return base::FeatureList::IsEnabled(kVCBackgroundReplace);
-}
-
-bool IsVCPortraitRelightingEnabled() {
-  return base::FeatureList::IsEnabled(kVCPortraitRelighting);
-}
-
 bool IsVcControlsUiEnabled() {
   return base::FeatureList::IsEnabled(kVcControlsUi);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index a5315de..5ae4a46 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -470,8 +470,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kQsRevamp);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kQuickDim);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kVCBackgroundBlur);
-COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kVCBackgroundReplace);
-COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kVCPortraitRelighting);
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kQuickSettingsNetworkRevamp);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kQuickUnlockFingerprint);
@@ -832,8 +830,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsUseLoginShelfWidgetEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsUseStorkSmdsServerAddressEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsVCBackgroundBlurEnabled();
-COMPONENT_EXPORT(ASH_CONSTANTS) bool IsVCBackgroundReplaceEnabled();
-COMPONENT_EXPORT(ASH_CONSTANTS) bool IsVCPortraitRelightingEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsVcControlsUiEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWallpaperFastRefreshEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWallpaperFullScreenPreviewEnabled();
diff --git a/ash/system/power/power_event_observer.cc b/ash/system/power/power_event_observer.cc
index 78189f93..94de2bb 100644
--- a/ash/system/power/power_event_observer.cc
+++ b/ash/system/power/power_event_observer.cc
@@ -30,6 +30,10 @@
 #include "ui/compositor/compositor_observer.h"
 #include "ui/display/manager/display_configurator.h"
 
+// TODO(b/248107965): Remove after figuring out the root cause of the bug
+#undef ENABLED_VLOG_LEVEL
+#define ENABLED_VLOG_LEVEL 1
+
 namespace ash {
 
 namespace {
@@ -243,6 +247,9 @@
                       ? LockState::kLocked
                       : LockState::kUnlocked),
       session_observer_(this) {
+  VLOG(1) << "PowerEventObserver::PowerEventObserver lock="
+          << static_cast<int>(lock_state_) << ", can_lock="
+          << Shell::Get()->session_controller()->CanLockScreen();
   chromeos::PowerManagerClient::Get()->AddObserver(this);
 
   if (Shell::Get()->session_controller()->CanLockScreen())
@@ -254,7 +261,9 @@
 }
 
 void PowerEventObserver::OnLockAnimationsComplete() {
-  VLOG(1) << "Screen locker animations have completed.";
+  VLOG(1) << "Screen locker animations have completed, lock="
+          << static_cast<int>(lock_state_) << " , block_suspend_token="
+          << static_cast<int>(!block_suspend_token_);
   if (lock_state_ != LockState::kLocking)
     return;
 
@@ -275,6 +284,8 @@
 
 void PowerEventObserver::SuspendImminent(
     power_manager::SuspendImminent::Reason reason) {
+  VLOG(1) << "PowerEventObserver::SuspendImminent: reason=" << reason
+          << ", lock=" << static_cast<int>(lock_state_);
   suspend_in_progress_ = true;
 
   block_suspend_token_ = base::UnguessableToken::Create();
@@ -286,6 +297,8 @@
   // * screen is not locked, and should remain unlocked during suspend
   if (lock_state_ == LockState::kLocked ||
       (lock_state_ == LockState::kUnlocked && !ShouldLockOnSuspend())) {
+    VLOG(1) << "Requesting StopCompositingAndSuspendDisplays from "
+               "PowerEventObserver suspend";
     StopCompositingAndSuspendDisplays();
   } else {
     // If screen is getting locked during suspend, delay suspend until screen
@@ -300,6 +313,8 @@
       // If the screen is still being locked (i.e. in kLocking state),
       // EndPendingWallpaperAnimations() will be called in
       // OnLockAnimationsComplete().
+      VLOG(1) << "Requesting EndPendingWallpaperAnimations from "
+                 "PowerEventObserver suspend";
       EndPendingWallpaperAnimations();
     }
   }
@@ -307,6 +322,9 @@
 
 void PowerEventObserver::SuspendDoneEx(
     const power_manager::SuspendDone& proto) {
+  VLOG(1) << "PowerEventObserver::SuspendDoneEx, suspend_in_progress="
+          << static_cast<int>(suspend_in_progress_)
+          << " cleared, deepest_state=" << proto.deepest_state();
   suspend_in_progress_ = false;
 
   Shell::Get()->display_configurator()->ResumeDisplays();
@@ -331,6 +349,8 @@
 void PowerEventObserver::LidEventReceived(
     chromeos::PowerManagerClient::LidState state,
     base::TimeTicks timestamp) {
+  VLOG(1) << "PowerEventObserver::LidEventReceived, state="
+          << static_cast<int>(state);
   lid_state_ = state;
   MaybeLockOnLidClose(
       ash::Shell::Get()->projecting_observer()->is_projecting());
@@ -368,6 +388,9 @@
 }
 
 void PowerEventObserver::OnLockStateChanged(bool locked) {
+  VLOG(1) << "PowerEventObserver::OnLockStateChanged, locked="
+          << static_cast<int>(locked)
+          << " ,lock_state=" << static_cast<int>(lock_state_);
   if (locked) {
     lock_state_ = LockState::kLocking;
 
@@ -398,9 +421,12 @@
       }
     }
   }
+  VLOG(1) << "PowerEventObserver::OnLockStateChanged finieshed, new lock_state="
+          << static_cast<int>(lock_state_);
 }
 
 void PowerEventObserver::StartRootWindowCompositors() {
+  VLOG(1) << "PowerEventObserver::StartRootWindowCompositors";
   for (aura::Window* window : Shell::GetAllRootWindows()) {
     ui::Compositor* compositor = window->GetHost()->compositor();
     if (!compositor->IsVisible())
@@ -409,6 +435,7 @@
 }
 
 void PowerEventObserver::StopCompositingAndSuspendDisplays() {
+  VLOG(1) << "PowerEventObserver::StopCompositingAndSuspendDisplays";
   DCHECK(block_suspend_token_);
   DCHECK(!compositor_watcher_.get());
   for (aura::Window* window : Shell::GetAllRootWindows()) {
@@ -424,6 +451,7 @@
 }
 
 void PowerEventObserver::EndPendingWallpaperAnimations() {
+  VLOG(1) << "PowerEventObserver::EndPendingWallpaperAnimations";
   for (aura::Window* window : Shell::GetAllRootWindows()) {
     WallpaperWidgetController* wallpaper_widget_controller =
         RootWindowController::ForWindow(window)->wallpaper_widget_controller();
@@ -433,6 +461,9 @@
 }
 
 void PowerEventObserver::OnCompositorsReadyForSuspend() {
+  VLOG(1)
+      << "PowerEventObserver::OnCompositorsReadyForSuspend, has_suspend_token="
+      << static_cast<int>(!block_suspend_token_.is_empty());
   compositor_watcher_.reset();
   lock_state_ = LockState::kLocked;
 
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc
index 6e29353..6542dfd5 100644
--- a/ash/system/unified/unified_system_tray_bubble.cc
+++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -332,10 +332,12 @@
 
 void UnifiedSystemTrayBubble::OnTabletModeStarted() {
   UpdateBubbleBounds();
+  tray_->CloseBubble();
 }
 
 void UnifiedSystemTrayBubble::OnTabletModeEnded() {
   UpdateBubbleBounds();
+  tray_->CloseBubble();
 }
 
 void UnifiedSystemTrayBubble::OnAutoHideStateChanged(
diff --git a/ash/system/unified/unified_system_tray_unittest.cc b/ash/system/unified/unified_system_tray_unittest.cc
index 3dea3c1..05cac148 100644
--- a/ash/system/unified/unified_system_tray_unittest.cc
+++ b/ash/system/unified/unified_system_tray_unittest.cc
@@ -24,6 +24,7 @@
 #include "ash/system/unified/unified_system_tray_controller.h"
 #include "ash/system/unified/unified_system_tray_view.h"
 #include "ash/test/ash_test_base.h"
+#include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chromeos/ash/components/audio/audio_device.h"
@@ -77,6 +78,10 @@
     MessageCenter::Get()->RemoveNotification(id, /*by_user=*/false);
   }
 
+  bool IsBubbleShown() {
+    return GetPrimaryUnifiedSystemTray()->IsBubbleShown();
+  }
+
   bool IsSliderBubbleShown() {
     return GetPrimaryUnifiedSystemTray()
         ->slider_bubble_controller_->bubble_widget_;
@@ -596,4 +601,28 @@
   EXPECT_FALSE(IsMicrophoneMuteToastShown());
 }
 
+// Tests that the bubble is closed after entering or exiting tablet mode.
+TEST_P(UnifiedSystemTrayTest, BubbleClosedAfterTabletModeChange) {
+  auto* tray = GetPrimaryUnifiedSystemTray();
+  TabletModeController* tablet_mode_controller =
+      Shell::Get()->tablet_mode_controller();
+
+  // Show bubble.
+  EXPECT_FALSE(IsBubbleShown());
+  tray->ShowBubble();
+  EXPECT_TRUE(IsBubbleShown());
+
+  // Expect bubble to close after entering tablet mode.
+  tablet_mode_controller->SetEnabledForTest(true);
+  EXPECT_FALSE(IsBubbleShown());
+
+  // Show bubble again.
+  tray->ShowBubble();
+  EXPECT_TRUE(IsBubbleShown());
+
+  // Expect bubble to close after exiting tablet mode.
+  tablet_mode_controller->SetEnabledForTest(false);
+  EXPECT_FALSE(IsBubbleShown());
+}
+
 }  // namespace ash
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 799f5f42..3413c2d 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -558,6 +558,8 @@
     "power_monitor/power_monitor.h",
     "power_monitor/power_monitor_device_source.cc",
     "power_monitor/power_monitor_device_source.h",
+    "power_monitor/power_monitor_features.cc",
+    "power_monitor/power_monitor_features.h",
     "power_monitor/power_monitor_source.cc",
     "power_monitor/power_monitor_source.h",
     "power_monitor/power_observer.h",
diff --git a/base/allocator/partition_allocator/.gn b/base/allocator/partition_allocator/.gn
new file mode 100644
index 0000000..21e1e7e
--- /dev/null
+++ b/base/allocator/partition_allocator/.gn
@@ -0,0 +1,7 @@
+# Copyright 2022 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# The python interpreter to use by default. On Windows, this will look
+# for python3.exe and python3.bat.
+script_executable = "python3"
diff --git a/base/allocator/partition_allocator/BUILD.gn b/base/allocator/partition_allocator/BUILD.gn
index c551144d..86adcc4 100644
--- a/base/allocator/partition_allocator/BUILD.gn
+++ b/base/allocator/partition_allocator/BUILD.gn
@@ -402,6 +402,9 @@
     # *Scan is currently only used by Chromium.
     "STARSCAN=$build_with_chromium",
 
+    # We can only use `//base/tracing` when building in Chromium.
+    "PA_USE_BASE_TRACING=$build_with_chromium",
+
     "ENABLE_PKEYS=$enable_pkeys",
   ]
 }
diff --git a/base/allocator/partition_allocator/DEPS b/base/allocator/partition_allocator/DEPS
index 5680172..5c69580 100644
--- a/base/allocator/partition_allocator/DEPS
+++ b/base/allocator/partition_allocator/DEPS
@@ -5,6 +5,51 @@
 # PartitionAlloc is planned to be extracted into a standalone library, and
 # therefore dependencies need to be strictly controlled and minimized.
 
+# Only these hosts are allowed for dependencies in this DEPS file.
+# This is a subset of chromium/src/DEPS's allowed_hosts.
+allowed_hosts = [
+  'chromium.googlesource.com',
+]
+
+vars = {
+  'chromium_git': 'https://chromium.googlesource.com',
+}
+
+deps = {
+  'partition_allocator/buildtools/clang_format/script':
+      Var('chromium_git') + '/external/github.com/llvm/llvm-project/clang/tools/clang-format.git',
+  'partition_allocator/buildtools/linux64': {
+    'packages': [
+      {
+        'package': 'gn/gn/linux-${{arch}}',
+        'version': 'latest',
+      }
+    ],
+    'dep_type': 'cipd',
+    'condition': 'host_os == "linux"',
+  },
+  'partition_allocator/buildtools/mac': {
+    'packages': [
+      {
+        'package': 'gn/gn/mac-${{arch}}',
+        'version': 'latest',
+      }
+    ],
+    'dep_type': 'cipd',
+    'condition': 'host_os == "mac"',
+  },
+  'partition_allocator/buildtools/win': {
+    'packages': [
+      {
+        'package': 'gn/gn/windows-amd64',
+        'version': 'latest',
+      }
+    ],
+    'dep_type': 'cipd',
+    'condition': 'host_os == "win"',
+  },
+}
+
 noparent = True
 
 include_rules = [
diff --git a/base/allocator/partition_allocator/extended_api.cc b/base/allocator/partition_allocator/extended_api.cc
index b5996dc..81dacd43 100644
--- a/base/allocator/partition_allocator/extended_api.cc
+++ b/base/allocator/partition_allocator/extended_api.cc
@@ -5,6 +5,7 @@
 #include "base/allocator/partition_allocator/extended_api.h"
 
 #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
+#include "base/allocator/partition_allocator/partition_alloc_config.h"
 #include "base/allocator/partition_allocator/shim/allocator_shim_default_dispatch_to_partition_alloc.h"
 #include "base/allocator/partition_allocator/thread_cache.h"
 
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h
index 5aa3be5..6028b49 100644
--- a/base/memory/raw_ptr.h
+++ b/base/memory/raw_ptr.h
@@ -15,14 +15,18 @@
 #include <utility>
 
 #include "base/allocator/buildflags.h"
+#include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/debug/debugging_buildflags.h"
+#include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
 #include "base/allocator/partition_allocator/partition_alloc_config.h"
 #include "base/check.h"
-#include "base/compiler_specific.h"
-#include "base/trace_event/base_tracing_forward.h"
 #include "build/build_config.h"
 #include "build/buildflag.h"
 
+#if BUILDFLAG(PA_USE_BASE_TRACING)
+#include "base/trace_event/base_tracing_forward.h"
+#endif  // BUILDFLAG(PA_USE_BASE_TRACING)
+
 #if BUILDFLAG(USE_BACKUP_REF_PTR) || \
     defined(PA_ENABLE_MTE_CHECKED_PTR_SUPPORT_WITH_64_BITS_POINTERS)
 // USE_BACKUP_REF_PTR implies USE_PARTITION_ALLOC, needed for code under
@@ -56,7 +60,7 @@
 
 namespace base {
 
-// NOTE: All methods should be `ALWAYS_INLINE`. raw_ptr is meant to be a
+// NOTE: All methods should be `PA_ALWAYS_INLINE`. raw_ptr is meant to be a
 // lightweight replacement of a raw pointer, hence performance is critical.
 
 // The following types are the different RawPtrType template option possible for
@@ -95,38 +99,38 @@
 struct RawPtrNoOpImpl {
   // Wraps a pointer.
   template <typename T>
-  static ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
+  static PA_ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
     return ptr;
   }
 
   // Notifies the allocator when a wrapped pointer is being removed or replaced.
   template <typename T>
-  static ALWAYS_INLINE void ReleaseWrappedPtr(T*) {}
+  static PA_ALWAYS_INLINE void ReleaseWrappedPtr(T*) {}
 
   // Unwraps the pointer, while asserting that memory hasn't been freed. The
   // function is allowed to crash on nullptr.
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
     return wrapped_ptr;
   }
 
   // Unwraps the pointer, while asserting that memory hasn't been freed. The
   // function must handle nullptr gracefully.
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
     return wrapped_ptr;
   }
 
   // Unwraps the pointer, without making an assertion on whether memory was
   // freed or not.
   template <typename T>
-  static ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
     return wrapped_ptr;
   }
 
   // Upcasts the wrapped pointer.
   template <typename To, typename From>
-  static ALWAYS_INLINE constexpr To* Upcast(From* wrapped_ptr) {
+  static PA_ALWAYS_INLINE constexpr To* Upcast(From* wrapped_ptr) {
     static_assert(std::is_convertible<From*, To*>::value,
                   "From must be convertible to To.");
     // Note, this cast may change the address if upcasting to base that lies in
@@ -138,27 +142,27 @@
   template <typename T,
             typename Z,
             typename = std::enable_if_t<offset_type<Z>, void>>
-  static ALWAYS_INLINE T* Advance(T* wrapped_ptr, Z delta_elems) {
+  static PA_ALWAYS_INLINE T* Advance(T* wrapped_ptr, Z delta_elems) {
     return wrapped_ptr + delta_elems;
   }
 
   template <typename T>
-  static ALWAYS_INLINE ptrdiff_t GetDeltaElems(T* wrapped_ptr1,
-                                               T* wrapped_ptr2) {
+  static PA_ALWAYS_INLINE ptrdiff_t GetDeltaElems(T* wrapped_ptr1,
+                                                  T* wrapped_ptr2) {
     return wrapped_ptr1 - wrapped_ptr2;
   }
 
   // Returns a copy of a wrapped pointer, without making an assertion on whether
   // memory was freed or not.
   template <typename T>
-  static ALWAYS_INLINE T* Duplicate(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* Duplicate(T* wrapped_ptr) {
     return wrapped_ptr;
   }
 
   // This is for accounting only, used by unit tests.
-  static ALWAYS_INLINE void IncrementSwapCountForTest() {}
-  static ALWAYS_INLINE void IncrementLessCountForTest() {}
-  static ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementSwapCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementLessCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {}
 };
 
 #if defined(PA_ENABLE_MTE_CHECKED_PTR_SUPPORT_WITH_64_BITS_POINTERS)
@@ -183,7 +187,7 @@
 struct MTECheckedPtrImplPartitionAllocSupport {
   // Checks if the necessary support is enabled in PartitionAlloc for `ptr`.
   template <typename T>
-  static ALWAYS_INLINE bool EnabledForPtr(T* ptr) {
+  static PA_ALWAYS_INLINE bool EnabledForPtr(T* ptr) {
     // Disambiguation: UntagPtr removes the hardware MTE tag, whereas this class
     // is responsible for handling the software MTE tag.
     auto addr = partition_alloc::UntagPtr(ptr);
@@ -191,7 +195,7 @@
   }
 
   // Returns pointer to the tag that protects are pointed by |addr|.
-  static ALWAYS_INLINE void* TagPointer(uintptr_t addr) {
+  static PA_ALWAYS_INLINE void* TagPointer(uintptr_t addr) {
     return partition_alloc::PartitionTagPointer(addr);
   }
 };
@@ -206,7 +210,7 @@
 
   // Wraps a pointer, and returns its uintptr_t representation.
   template <typename T>
-  static ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
+  static PA_ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
     // Disambiguation: UntagPtr removes the hardware MTE tag, whereas this
     // function is responsible for adding the software MTE tag.
     uintptr_t addr = partition_alloc::UntagPtr(ptr);
@@ -237,12 +241,12 @@
   // Notifies the allocator when a wrapped pointer is being removed or replaced.
   // No-op for MTECheckedPtrImpl.
   template <typename T>
-  static ALWAYS_INLINE void ReleaseWrappedPtr(T*) {}
+  static PA_ALWAYS_INLINE void ReleaseWrappedPtr(T*) {}
 
   // Unwraps the pointer's uintptr_t representation, while asserting that memory
   // hasn't been freed. The function is allowed to crash on nullptr.
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
     // Disambiguation: UntagPtr removes the hardware MTE tag, whereas this
     // function is responsible for removing the software MTE tag.
     uintptr_t wrapped_addr = partition_alloc::UntagPtr(wrapped_ptr);
@@ -256,7 +260,7 @@
       uintptr_t read_tag =
           *static_cast<volatile partition_alloc::PartitionTag*>(
               PartitionAllocSupport::TagPointer(ExtractAddress(wrapped_addr)));
-      if (UNLIKELY(tag != read_tag))
+      if (PA_UNLIKELY(tag != read_tag))
         IMMEDIATE_CRASH();
       // See the disambiguation comment above.
       // TODO(kdlee): Ensure that ptr's hardware MTE tag is preserved.
@@ -270,7 +274,7 @@
   // Unwraps the pointer's uintptr_t representation, while asserting that memory
   // hasn't been freed. The function must handle nullptr gracefully.
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
     // SafelyUnwrapPtrForDereference handles nullptr case well.
     return SafelyUnwrapPtrForDereference(wrapped_ptr);
   }
@@ -278,13 +282,13 @@
   // Unwraps the pointer's uintptr_t representation, without making an assertion
   // on whether memory was freed or not.
   template <typename T>
-  static ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
     return ExtractPtr(wrapped_ptr);
   }
 
   // Upcasts the wrapped pointer.
   template <typename To, typename From>
-  static ALWAYS_INLINE constexpr To* Upcast(From* wrapped_ptr) {
+  static PA_ALWAYS_INLINE constexpr To* Upcast(From* wrapped_ptr) {
     static_assert(std::is_convertible<From*, To*>::value,
                   "From must be convertible to To.");
 
@@ -296,13 +300,13 @@
   template <typename T,
             typename Z,
             typename = std::enable_if_t<offset_type<Z>, void>>
-  static ALWAYS_INLINE T* Advance(T* wrapped_ptr, Z delta_elems) {
+  static PA_ALWAYS_INLINE T* Advance(T* wrapped_ptr, Z delta_elems) {
     return wrapped_ptr + delta_elems;
   }
 
   template <typename T>
-  static ALWAYS_INLINE ptrdiff_t GetDeltaElems(T* wrapped_ptr1,
-                                               T* wrapped_ptr2) {
+  static PA_ALWAYS_INLINE ptrdiff_t GetDeltaElems(T* wrapped_ptr1,
+                                                  T* wrapped_ptr2) {
     // Ensure that both pointers come from the same allocation.
     //
     // Disambiguation: UntagPtr removes the hardware MTE tag, whereas this
@@ -331,22 +335,22 @@
   // Returns a copy of a wrapped pointer, without making an assertion
   // on whether memory was freed or not.
   template <typename T>
-  static ALWAYS_INLINE T* Duplicate(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* Duplicate(T* wrapped_ptr) {
     return wrapped_ptr;
   }
 
   // This is for accounting only, used by unit tests.
-  static ALWAYS_INLINE void IncrementSwapCountForTest() {}
-  static ALWAYS_INLINE void IncrementLessCountForTest() {}
-  static ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementSwapCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementLessCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {}
 
  private:
-  static ALWAYS_INLINE uintptr_t ExtractAddress(uintptr_t wrapped_ptr) {
+  static PA_ALWAYS_INLINE uintptr_t ExtractAddress(uintptr_t wrapped_ptr) {
     return wrapped_ptr & kAddressMask;
   }
 
   template <typename T>
-  static ALWAYS_INLINE T* ExtractPtr(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* ExtractPtr(T* wrapped_ptr) {
     // Disambiguation: UntagPtr/TagAddr handle the hardware MTE tag, whereas
     // this function is responsible for removing the software MTE tag.
     // TODO(kdlee): Ensure that wrapped_ptr's hardware MTE tag is preserved.
@@ -355,7 +359,7 @@
         ExtractAddress(partition_alloc::UntagPtr(wrapped_ptr))));
   }
 
-  static ALWAYS_INLINE uintptr_t ExtractTag(uintptr_t wrapped_ptr) {
+  static PA_ALWAYS_INLINE uintptr_t ExtractTag(uintptr_t wrapped_ptr) {
     return (wrapped_ptr & kTagMask) >> kValidAddressBits;
   }
 };
@@ -375,7 +379,7 @@
   // modify the same smart pointer object without synchronization, a data race
   // will occur.
 
-  static ALWAYS_INLINE bool IsSupportedAndNotNull(uintptr_t address) {
+  static PA_ALWAYS_INLINE bool IsSupportedAndNotNull(uintptr_t address) {
     // There are many situations where the compiler can prove that
     // `ReleaseWrappedPtr` is called on a value that is always nullptr, but the
     // way `IsManagedByPartitionAllocBRPPool` is written, the compiler can't
@@ -384,7 +388,7 @@
     // the runtime check slower, tell the compiler to skip
     // `IsManagedByPartitionAllocBRPPool` when it can statically determine that
     // address is nullptr.
-#if HAS_BUILTIN(__builtin_constant_p)
+#if PA_HAS_BUILTIN(__builtin_constant_p)
     if (__builtin_constant_p(address == 0) && (address == 0)) {
 #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
       CHECK(!partition_alloc::IsManagedByPartitionAllocBRPPool(address));
@@ -392,7 +396,7 @@
         // BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
       return false;
     }
-#endif  // HAS_BUILTIN(__builtin_constant_p)
+#endif  // PA_HAS_BUILTIN(__builtin_constant_p)
 
     // This covers the nullptr case, as address 0 is never in any
     // PartitionAlloc pool.
@@ -427,7 +431,7 @@
 
   // Wraps a pointer.
   template <typename T>
-  static ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
+  static PA_ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
     uintptr_t address = partition_alloc::UntagPtr(ptr);
     if (IsSupportedAndNotNull(address)) {
 #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
@@ -436,15 +440,15 @@
       AcquireInternal(address);
     } else {
 #if !defined(PA_HAS_64_BITS_POINTERS)
-#if HAS_BUILTIN(__builtin_constant_p)
+#if PA_HAS_BUILTIN(__builtin_constant_p)
       // Similarly to `IsSupportedAndNotNull` above, elide the
       // `BanSuperPageFromBRPPool` call if the compiler can prove that `address`
       // is zero since PA won't be able to map anything at that address anyway.
       bool known_constant_zero =
           __builtin_constant_p(address == 0) && (address == 0);
-#else   // HAS_BUILTIN(__builtin_constant_p)
+#else   // PA_HAS_BUILTIN(__builtin_constant_p)
       bool known_constant_zero = false;
-#endif  // HAS_BUILTIN(__builtin_constant_p)
+#endif  // PA_HAS_BUILTIN(__builtin_constant_p)
 
       if (!known_constant_zero) {
         partition_alloc::internal::AddressPoolManagerBitmap::
@@ -458,7 +462,7 @@
 
   // Notifies the allocator when a wrapped pointer is being removed or replaced.
   template <typename T>
-  static ALWAYS_INLINE void ReleaseWrappedPtr(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE void ReleaseWrappedPtr(T* wrapped_ptr) {
     uintptr_t address = partition_alloc::UntagPtr(wrapped_ptr);
     if (IsSupportedAndNotNull(address)) {
 #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
@@ -478,7 +482,7 @@
   // Unwraps the pointer, while asserting that memory hasn't been freed. The
   // function is allowed to crash on nullptr.
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
 #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
     uintptr_t address = partition_alloc::UntagPtr(wrapped_ptr);
     if (IsSupportedAndNotNull(address)) {
@@ -492,20 +496,20 @@
   // Unwraps the pointer, while asserting that memory hasn't been freed. The
   // function must handle nullptr gracefully.
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
     return wrapped_ptr;
   }
 
   // Unwraps the pointer, without making an assertion on whether memory was
   // freed or not.
   template <typename T>
-  static ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
     return wrapped_ptr;
   }
 
   // Upcasts the wrapped pointer.
   template <typename To, typename From>
-  static ALWAYS_INLINE constexpr To* Upcast(From* wrapped_ptr) {
+  static PA_ALWAYS_INLINE constexpr To* Upcast(From* wrapped_ptr) {
     static_assert(std::is_convertible<From*, To*>::value,
                   "From must be convertible to To.");
     // Note, this cast may change the address if upcasting to base that lies in
@@ -517,7 +521,7 @@
   template <typename T,
             typename Z,
             typename = std::enable_if_t<offset_type<Z>, void>>
-  static ALWAYS_INLINE T* Advance(T* wrapped_ptr, Z delta_elems) {
+  static PA_ALWAYS_INLINE T* Advance(T* wrapped_ptr, Z delta_elems) {
 #if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)
     // First check if the new address lands within the same allocation
     // (end-of-allocation address is ok too). It has a non-trivial cost, but
@@ -559,8 +563,8 @@
   }
 
   template <typename T>
-  static ALWAYS_INLINE ptrdiff_t GetDeltaElems(T* wrapped_ptr1,
-                                               T* wrapped_ptr2) {
+  static PA_ALWAYS_INLINE ptrdiff_t GetDeltaElems(T* wrapped_ptr1,
+                                                  T* wrapped_ptr2) {
     uintptr_t address1 = partition_alloc::UntagPtr(wrapped_ptr1);
     uintptr_t address2 = partition_alloc::UntagPtr(wrapped_ptr2);
     // Ensure that both pointers are within the same slot, and pool!
@@ -578,20 +582,20 @@
   // memory was freed or not.
   // This method increments the reference count of the allocation slot.
   template <typename T>
-  static ALWAYS_INLINE T* Duplicate(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* Duplicate(T* wrapped_ptr) {
     return WrapRawPtr(wrapped_ptr);
   }
 
   // Report the current wrapped pointer if pointee isn't alive anymore.
   template <typename T>
-  static ALWAYS_INLINE void ReportIfDangling(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE void ReportIfDangling(T* wrapped_ptr) {
     ReportIfDanglingInternal(partition_alloc::UntagPtr(wrapped_ptr));
   }
 
   // This is for accounting only, used by unit tests.
-  static ALWAYS_INLINE void IncrementSwapCountForTest() {}
-  static ALWAYS_INLINE void IncrementLessCountForTest() {}
-  static ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementSwapCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementLessCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {}
 
  private:
   // We've evaluated several strategies (inline nothing, various parts, or
@@ -599,22 +603,26 @@
   // to measure performance. The best results were obtained when only the
   // lightweight |IsManagedByPartitionAllocBRPPool()| check was inlined.
   // Therefore, we've extracted the rest into the functions below and marked
-  // them as NOINLINE to prevent unintended LTO effects.
-  static BASE_EXPORT NOINLINE void AcquireInternal(uintptr_t address);
-  static BASE_EXPORT NOINLINE void ReleaseInternal(uintptr_t address);
-  static BASE_EXPORT NOINLINE bool IsPointeeAlive(uintptr_t address);
-  static BASE_EXPORT NOINLINE void ReportIfDanglingInternal(uintptr_t address);
+  // them as PA_NOINLINE to prevent unintended LTO effects.
+  static BASE_EXPORT PA_NOINLINE void AcquireInternal(uintptr_t address);
+  static BASE_EXPORT PA_NOINLINE void ReleaseInternal(uintptr_t address);
+  static BASE_EXPORT PA_NOINLINE bool IsPointeeAlive(uintptr_t address);
+  static BASE_EXPORT PA_NOINLINE void ReportIfDanglingInternal(
+      uintptr_t address);
   template <typename Z, typename = std::enable_if_t<offset_type<Z>, void>>
-  static ALWAYS_INLINE bool IsValidDelta(uintptr_t address, Z delta_in_bytes) {
+  static PA_ALWAYS_INLINE bool IsValidDelta(uintptr_t address,
+                                            Z delta_in_bytes) {
     if constexpr (std::is_signed_v<Z>)
       return IsValidSignedDelta(address, ptrdiff_t{delta_in_bytes});
     else
       return IsValidUnsignedDelta(address, size_t{delta_in_bytes});
   }
-  static BASE_EXPORT NOINLINE bool IsValidSignedDelta(uintptr_t address,
-                                                      ptrdiff_t delta_in_bytes);
-  static BASE_EXPORT NOINLINE bool IsValidUnsignedDelta(uintptr_t address,
-                                                        size_t delta_in_bytes);
+  static BASE_EXPORT PA_NOINLINE bool IsValidSignedDelta(
+      uintptr_t address,
+      ptrdiff_t delta_in_bytes);
+  static BASE_EXPORT PA_NOINLINE bool IsValidUnsignedDelta(
+      uintptr_t address,
+      size_t delta_in_bytes);
 };
 
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR)
@@ -623,19 +631,19 @@
 struct AsanBackupRefPtrImpl {
   // Wraps a pointer.
   template <typename T>
-  static ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
+  static PA_ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
     AsanCheckIfValidInstantiation(ptr);
     return ptr;
   }
 
   // Notifies the allocator when a wrapped pointer is being removed or replaced.
   template <typename T>
-  static ALWAYS_INLINE void ReleaseWrappedPtr(T*) {}
+  static PA_ALWAYS_INLINE void ReleaseWrappedPtr(T*) {}
 
   // Unwraps the pointer, while asserting that memory hasn't been freed. The
   // function is allowed to crash on nullptr.
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
     AsanCheckIfValidDereference(wrapped_ptr);
     return wrapped_ptr;
   }
@@ -643,7 +651,7 @@
   // Unwraps the pointer, while asserting that memory hasn't been freed. The
   // function must handle nullptr gracefully.
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
     AsanCheckIfValidExtraction(wrapped_ptr);
     return wrapped_ptr;
   }
@@ -651,13 +659,13 @@
   // Unwraps the pointer, without making an assertion on whether memory was
   // freed or not.
   template <typename T>
-  static ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
     return wrapped_ptr;
   }
 
   // Upcasts the wrapped pointer.
   template <typename To, typename From>
-  static ALWAYS_INLINE constexpr To* Upcast(From* wrapped_ptr) {
+  static PA_ALWAYS_INLINE constexpr To* Upcast(From* wrapped_ptr) {
     static_assert(std::is_convertible<From*, To*>::value,
                   "From must be convertible to To.");
     // Note, this cast may change the address if upcasting to base that lies in
@@ -669,34 +677,34 @@
   template <typename T,
             typename Z,
             typename = std::enable_if_t<offset_type<Z>, void>>
-  static ALWAYS_INLINE T* Advance(T* wrapped_ptr, Z delta_elems) {
+  static PA_ALWAYS_INLINE T* Advance(T* wrapped_ptr, Z delta_elems) {
     return wrapped_ptr + delta_elems;
   }
 
   template <typename T>
-  static ALWAYS_INLINE ptrdiff_t GetDeltaElems(T* wrapped_ptr1,
-                                               T* wrapped_ptr2) {
+  static PA_ALWAYS_INLINE ptrdiff_t GetDeltaElems(T* wrapped_ptr1,
+                                                  T* wrapped_ptr2) {
     return wrapped_ptr1 - wrapped_ptr2;
   }
 
   // Returns a copy of a wrapped pointer, without making an assertion on whether
   // memory was freed or not.
   template <typename T>
-  static ALWAYS_INLINE T* Duplicate(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* Duplicate(T* wrapped_ptr) {
     return wrapped_ptr;
   }
 
   // This is for accounting only, used by unit tests.
-  static ALWAYS_INLINE void IncrementSwapCountForTest() {}
-  static ALWAYS_INLINE void IncrementLessCountForTest() {}
-  static ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementSwapCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementLessCountForTest() {}
+  static PA_ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {}
 
  private:
-  static BASE_EXPORT NOINLINE void AsanCheckIfValidInstantiation(
+  static BASE_EXPORT PA_NOINLINE void AsanCheckIfValidInstantiation(
       void const volatile* ptr);
-  static BASE_EXPORT NOINLINE void AsanCheckIfValidDereference(
+  static BASE_EXPORT PA_NOINLINE void AsanCheckIfValidDereference(
       void const volatile* ptr);
-  static BASE_EXPORT NOINLINE void AsanCheckIfValidExtraction(
+  static BASE_EXPORT PA_NOINLINE void AsanCheckIfValidExtraction(
       void const volatile* ptr);
 };
 
@@ -705,44 +713,44 @@
     : public raw_ptr_traits::RawPtrTypeToImpl<Super>::Impl {
   using SuperImpl = typename raw_ptr_traits::RawPtrTypeToImpl<Super>::Impl;
   template <typename T>
-  static ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
+  static PA_ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
     ++wrap_raw_ptr_cnt;
     return SuperImpl::WrapRawPtr(ptr);
   }
 
   template <typename T>
-  static ALWAYS_INLINE void ReleaseWrappedPtr(T* ptr) {
+  static PA_ALWAYS_INLINE void ReleaseWrappedPtr(T* ptr) {
     ++release_wrapped_ptr_cnt;
     SuperImpl::ReleaseWrappedPtr(ptr);
   }
 
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
     ++get_for_dereference_cnt;
     return SuperImpl::SafelyUnwrapPtrForDereference(wrapped_ptr);
   }
 
   template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
     ++get_for_extraction_cnt;
     return SuperImpl::SafelyUnwrapPtrForExtraction(wrapped_ptr);
   }
 
   template <typename T>
-  static ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
+  static PA_ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
     ++get_for_comparison_cnt;
     return SuperImpl::UnsafelyUnwrapPtrForComparison(wrapped_ptr);
   }
 
-  static ALWAYS_INLINE void IncrementSwapCountForTest() {
+  static PA_ALWAYS_INLINE void IncrementSwapCountForTest() {
     ++wrapped_ptr_swap_cnt;
   }
 
-  static ALWAYS_INLINE void IncrementLessCountForTest() {
+  static PA_ALWAYS_INLINE void IncrementLessCountForTest() {
     ++wrapped_ptr_less_cnt;
   }
 
-  static ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {
+  static PA_ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {
     ++pointer_to_member_operator_cnt;
   }
 
@@ -927,7 +935,7 @@
 using DefaultRawPtrType = RawPtrBanDanglingIfSupported;
 
 template <typename T, typename RawPtrType = DefaultRawPtrType>
-class TRIVIAL_ABI GSL_POINTER raw_ptr {
+class PA_TRIVIAL_ABI PA_GSL_POINTER raw_ptr {
   using Impl = typename raw_ptr_traits::RawPtrTypeToImpl<RawPtrType>::Impl;
   using DanglingRawPtr = std::conditional_t<
       raw_ptr_traits::IsRawPtrCountingImpl<Impl>::value,
@@ -940,17 +948,17 @@
 
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
   // BackupRefPtr requires a non-trivial default constructor, destructor, etc.
-  constexpr ALWAYS_INLINE raw_ptr() noexcept : wrapped_ptr_(nullptr) {}
+  constexpr PA_ALWAYS_INLINE raw_ptr() noexcept : wrapped_ptr_(nullptr) {}
 
-  ALWAYS_INLINE raw_ptr(const raw_ptr& p) noexcept
+  PA_ALWAYS_INLINE raw_ptr(const raw_ptr& p) noexcept
       : wrapped_ptr_(Impl::Duplicate(p.wrapped_ptr_)) {}
 
-  ALWAYS_INLINE raw_ptr(raw_ptr&& p) noexcept {
+  PA_ALWAYS_INLINE raw_ptr(raw_ptr&& p) noexcept {
     wrapped_ptr_ = p.wrapped_ptr_;
     p.wrapped_ptr_ = nullptr;
   }
 
-  ALWAYS_INLINE raw_ptr& operator=(const raw_ptr& p) noexcept {
+  PA_ALWAYS_INLINE raw_ptr& operator=(const raw_ptr& p) noexcept {
     // Duplicate before releasing, in case the pointer is assigned to itself.
     //
     // Unlike the move version of this operator, don't add |this != &p| branch,
@@ -964,10 +972,10 @@
     return *this;
   }
 
-  ALWAYS_INLINE raw_ptr& operator=(raw_ptr&& p) noexcept {
+  PA_ALWAYS_INLINE raw_ptr& operator=(raw_ptr&& p) noexcept {
     // Unlike the the copy version of this operator, this branch is necessaty
     // for correctness.
-    if (LIKELY(this != &p)) {
+    if (PA_LIKELY(this != &p)) {
       Impl::ReleaseWrappedPtr(wrapped_ptr_);
       wrapped_ptr_ = p.wrapped_ptr_;
       p.wrapped_ptr_ = nullptr;
@@ -975,7 +983,7 @@
     return *this;
   }
 
-  ALWAYS_INLINE ~raw_ptr() noexcept {
+  PA_ALWAYS_INLINE ~raw_ptr() noexcept {
     Impl::ReleaseWrappedPtr(wrapped_ptr_);
     // Work around external issues where raw_ptr is used after destruction.
     wrapped_ptr_ = nullptr;
@@ -988,30 +996,30 @@
   //
   // TODO(lukasza): Always initialize |wrapped_ptr_|.  Fix resulting build
   // errors.  Analyze performance impact.
-  constexpr ALWAYS_INLINE raw_ptr() noexcept = default;
+  constexpr PA_ALWAYS_INLINE raw_ptr() noexcept = default;
 
   // In addition to nullptr_t ctor above, raw_ptr needs to have these
   // as |=default| or |constexpr| to avoid hitting -Wglobal-constructors in
   // cases like this:
   //     struct SomeStruct { int int_field; raw_ptr<int> ptr_field; };
   //     SomeStruct g_global_var = { 123, nullptr };
-  ALWAYS_INLINE raw_ptr(const raw_ptr&) noexcept = default;
-  ALWAYS_INLINE raw_ptr(raw_ptr&&) noexcept = default;
-  ALWAYS_INLINE raw_ptr& operator=(const raw_ptr&) noexcept = default;
-  ALWAYS_INLINE raw_ptr& operator=(raw_ptr&&) noexcept = default;
+  PA_ALWAYS_INLINE raw_ptr(const raw_ptr&) noexcept = default;
+  PA_ALWAYS_INLINE raw_ptr(raw_ptr&&) noexcept = default;
+  PA_ALWAYS_INLINE raw_ptr& operator=(const raw_ptr&) noexcept = default;
+  PA_ALWAYS_INLINE raw_ptr& operator=(raw_ptr&&) noexcept = default;
 
-  ALWAYS_INLINE ~raw_ptr() noexcept = default;
+  PA_ALWAYS_INLINE ~raw_ptr() noexcept = default;
 
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR)
 
   // Deliberately implicit, because raw_ptr is supposed to resemble raw ptr.
   // NOLINTNEXTLINE(google-explicit-constructor)
-  constexpr ALWAYS_INLINE raw_ptr(std::nullptr_t) noexcept
+  constexpr PA_ALWAYS_INLINE raw_ptr(std::nullptr_t) noexcept
       : wrapped_ptr_(nullptr) {}
 
   // Deliberately implicit, because raw_ptr is supposed to resemble raw ptr.
   // NOLINTNEXTLINE(google-explicit-constructor)
-  ALWAYS_INLINE raw_ptr(T* p) noexcept : wrapped_ptr_(Impl::WrapRawPtr(p)) {}
+  PA_ALWAYS_INLINE raw_ptr(T* p) noexcept : wrapped_ptr_(Impl::WrapRawPtr(p)) {}
 
   // Deliberately implicit in order to support implicit upcast.
   template <typename U,
@@ -1019,7 +1027,7 @@
                 std::is_convertible<U*, T*>::value &&
                 !std::is_void<typename std::remove_cv<T>::type>::value>>
   // NOLINTNEXTLINE(google-explicit-constructor)
-  ALWAYS_INLINE raw_ptr(const raw_ptr<U, RawPtrType>& ptr) noexcept
+  PA_ALWAYS_INLINE raw_ptr(const raw_ptr<U, RawPtrType>& ptr) noexcept
       : wrapped_ptr_(
             Impl::Duplicate(Impl::template Upcast<T, U>(ptr.wrapped_ptr_))) {}
   // Deliberately implicit in order to support implicit upcast.
@@ -1028,19 +1036,19 @@
                 std::is_convertible<U*, T*>::value &&
                 !std::is_void<typename std::remove_cv<T>::type>::value>>
   // NOLINTNEXTLINE(google-explicit-constructor)
-  ALWAYS_INLINE raw_ptr(raw_ptr<U, RawPtrType>&& ptr) noexcept
+  PA_ALWAYS_INLINE raw_ptr(raw_ptr<U, RawPtrType>&& ptr) noexcept
       : wrapped_ptr_(Impl::template Upcast<T, U>(ptr.wrapped_ptr_)) {
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
     ptr.wrapped_ptr_ = nullptr;
 #endif
   }
 
-  ALWAYS_INLINE raw_ptr& operator=(std::nullptr_t) noexcept {
+  PA_ALWAYS_INLINE raw_ptr& operator=(std::nullptr_t) noexcept {
     Impl::ReleaseWrappedPtr(wrapped_ptr_);
     wrapped_ptr_ = nullptr;
     return *this;
   }
-  ALWAYS_INLINE raw_ptr& operator=(T* p) noexcept {
+  PA_ALWAYS_INLINE raw_ptr& operator=(T* p) noexcept {
     Impl::ReleaseWrappedPtr(wrapped_ptr_);
     wrapped_ptr_ = Impl::WrapRawPtr(p);
     return *this;
@@ -1051,7 +1059,8 @@
             typename Unused = std::enable_if_t<
                 std::is_convertible<U*, T*>::value &&
                 !std::is_void<typename std::remove_cv<T>::type>::value>>
-  ALWAYS_INLINE raw_ptr& operator=(const raw_ptr<U, RawPtrType>& ptr) noexcept {
+  PA_ALWAYS_INLINE raw_ptr& operator=(
+      const raw_ptr<U, RawPtrType>& ptr) noexcept {
     // Make sure that pointer isn't assigned to itself (look at pointer address,
     // not its value).
 #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
@@ -1067,7 +1076,7 @@
             typename Unused = std::enable_if_t<
                 std::is_convertible<U*, T*>::value &&
                 !std::is_void<typename std::remove_cv<T>::type>::value>>
-  ALWAYS_INLINE raw_ptr& operator=(raw_ptr<U, RawPtrType>&& ptr) noexcept {
+  PA_ALWAYS_INLINE raw_ptr& operator=(raw_ptr<U, RawPtrType>&& ptr) noexcept {
     // Make sure that pointer isn't assigned to itself (look at pointer address,
     // not its value).
 #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
@@ -1084,17 +1093,17 @@
 
   // Avoid using. The goal of raw_ptr is to be as close to raw pointer as
   // possible, so use it only if absolutely necessary (e.g. for const_cast).
-  ALWAYS_INLINE T* get() const { return GetForExtraction(); }
+  PA_ALWAYS_INLINE T* get() const { return GetForExtraction(); }
 
-  explicit ALWAYS_INLINE operator bool() const { return !!wrapped_ptr_; }
+  explicit PA_ALWAYS_INLINE operator bool() const { return !!wrapped_ptr_; }
 
   template <typename U = T,
             typename Unused = std::enable_if_t<
                 !std::is_void<typename std::remove_cv<U>::type>::value>>
-  ALWAYS_INLINE U& operator*() const {
+  PA_ALWAYS_INLINE U& operator*() const {
     return *GetForDereference();
   }
-  ALWAYS_INLINE T* operator->() const { return GetForDereference(); }
+  PA_ALWAYS_INLINE T* operator->() const { return GetForDereference(); }
 
   // Disables `(my_raw_ptr->*pmf)(...)` as a workaround for
   // the ICE in GCC parsing the code, reported at
@@ -1104,60 +1113,60 @@
 
   // Deliberately implicit, because raw_ptr is supposed to resemble raw ptr.
   // NOLINTNEXTLINE(runtime/explicit)
-  ALWAYS_INLINE operator T*() const { return GetForExtraction(); }
+  PA_ALWAYS_INLINE operator T*() const { return GetForExtraction(); }
   template <typename U>
-  explicit ALWAYS_INLINE operator U*() const {
+  explicit PA_ALWAYS_INLINE operator U*() const {
     // This operator may be invoked from static_cast, meaning the types may not
     // be implicitly convertible, hence the need for static_cast here.
     return static_cast<U*>(GetForExtraction());
   }
 
-  ALWAYS_INLINE raw_ptr& operator++() {
+  PA_ALWAYS_INLINE raw_ptr& operator++() {
     wrapped_ptr_ = Impl::Advance(wrapped_ptr_, 1);
     return *this;
   }
-  ALWAYS_INLINE raw_ptr& operator--() {
+  PA_ALWAYS_INLINE raw_ptr& operator--() {
     wrapped_ptr_ = Impl::Advance(wrapped_ptr_, -1);
     return *this;
   }
-  ALWAYS_INLINE raw_ptr operator++(int /* post_increment */) {
+  PA_ALWAYS_INLINE raw_ptr operator++(int /* post_increment */) {
     raw_ptr result = *this;
     ++(*this);
     return result;
   }
-  ALWAYS_INLINE raw_ptr operator--(int /* post_decrement */) {
+  PA_ALWAYS_INLINE raw_ptr operator--(int /* post_decrement */) {
     raw_ptr result = *this;
     --(*this);
     return result;
   }
   template <typename Z, typename = std::enable_if_t<internal::offset_type<Z>>>
-  ALWAYS_INLINE raw_ptr& operator+=(Z delta_elems) {
+  PA_ALWAYS_INLINE raw_ptr& operator+=(Z delta_elems) {
     wrapped_ptr_ = Impl::Advance(wrapped_ptr_, delta_elems);
     return *this;
   }
   template <typename Z, typename = std::enable_if_t<internal::offset_type<Z>>>
-  ALWAYS_INLINE raw_ptr& operator-=(Z delta_elems) {
+  PA_ALWAYS_INLINE raw_ptr& operator-=(Z delta_elems) {
     return *this += -delta_elems;
   }
 
   template <typename Z, typename = std::enable_if_t<internal::offset_type<Z>>>
-  friend ALWAYS_INLINE raw_ptr operator+(const raw_ptr& p, Z delta_elems) {
+  friend PA_ALWAYS_INLINE raw_ptr operator+(const raw_ptr& p, Z delta_elems) {
     raw_ptr result = p;
     return result += delta_elems;
   }
   template <typename Z, typename = std::enable_if_t<internal::offset_type<Z>>>
-  friend ALWAYS_INLINE raw_ptr operator-(const raw_ptr& p, Z delta_elems) {
+  friend PA_ALWAYS_INLINE raw_ptr operator-(const raw_ptr& p, Z delta_elems) {
     raw_ptr result = p;
     return result -= delta_elems;
   }
-  friend ALWAYS_INLINE ptrdiff_t operator-(const raw_ptr& p1,
-                                           const raw_ptr& p2) {
+  friend PA_ALWAYS_INLINE ptrdiff_t operator-(const raw_ptr& p1,
+                                              const raw_ptr& p2) {
     return Impl::GetDeltaElems(p1.wrapped_ptr_, p2.wrapped_ptr_);
   }
-  friend ALWAYS_INLINE ptrdiff_t operator-(T* p1, const raw_ptr& p2) {
+  friend PA_ALWAYS_INLINE ptrdiff_t operator-(T* p1, const raw_ptr& p2) {
     return Impl::GetDeltaElems(p1, p2.wrapped_ptr_);
   }
-  friend ALWAYS_INLINE ptrdiff_t operator-(const raw_ptr& p1, T* p2) {
+  friend PA_ALWAYS_INLINE ptrdiff_t operator-(const raw_ptr& p1, T* p2) {
     return Impl::GetDeltaElems(p1.wrapped_ptr_, p2);
   }
 
@@ -1165,10 +1174,10 @@
   // raw delete calls, this avoids the raw_ptr to be temporarily dangling
   // during the free operation, which will lead to taking the slower path that
   // involves quarantine.
-  ALWAYS_INLINE void ClearAndDelete() noexcept {
+  PA_ALWAYS_INLINE void ClearAndDelete() noexcept {
     delete GetForExtractionAndReset();
   }
-  ALWAYS_INLINE void ClearAndDeleteArray() noexcept {
+  PA_ALWAYS_INLINE void ClearAndDeleteArray() noexcept {
     delete[] GetForExtractionAndReset();
   }
 
@@ -1188,7 +1197,7 @@
   // variable (or worse, a field)! It's meant to be used as a temporary, to be
   // passed into a cleanup & freeing function, and destructed at the end of the
   // statement.
-  ALWAYS_INLINE DanglingRawPtr ExtractAsDangling() noexcept {
+  PA_ALWAYS_INLINE DanglingRawPtr ExtractAsDangling() noexcept {
     if constexpr (std::is_same_v<
                       typename std::remove_reference<decltype(*this)>::type,
                       DanglingRawPtr>) {
@@ -1219,96 +1228,97 @@
   // because a comparison operator defined inline would not be allowed to call
   // `raw_ptr<U>`'s private `GetForComparison()` method.
   template <typename U, typename V, typename I>
-  friend ALWAYS_INLINE bool operator==(const raw_ptr<U, I>& lhs,
-                                       const raw_ptr<V, I>& rhs);
+  friend PA_ALWAYS_INLINE bool operator==(const raw_ptr<U, I>& lhs,
+                                          const raw_ptr<V, I>& rhs);
   template <typename U>
-  friend ALWAYS_INLINE bool operator!=(const raw_ptr& lhs,
-                                       const raw_ptr<U, Impl>& rhs) {
+  friend PA_ALWAYS_INLINE bool operator!=(const raw_ptr& lhs,
+                                          const raw_ptr<U, Impl>& rhs) {
     return !(lhs == rhs);
   }
   template <typename U, typename V, typename I>
-  friend ALWAYS_INLINE bool operator<(const raw_ptr<U, I>& lhs,
-                                      const raw_ptr<V, I>& rhs);
+  friend PA_ALWAYS_INLINE bool operator<(const raw_ptr<U, I>& lhs,
+                                         const raw_ptr<V, I>& rhs);
   template <typename U, typename V, typename I>
-  friend ALWAYS_INLINE bool operator>(const raw_ptr<U, I>& lhs,
-                                      const raw_ptr<V, I>& rhs);
+  friend PA_ALWAYS_INLINE bool operator>(const raw_ptr<U, I>& lhs,
+                                         const raw_ptr<V, I>& rhs);
   template <typename U, typename V, typename I>
-  friend ALWAYS_INLINE bool operator<=(const raw_ptr<U, I>& lhs,
-                                       const raw_ptr<V, I>& rhs);
+  friend PA_ALWAYS_INLINE bool operator<=(const raw_ptr<U, I>& lhs,
+                                          const raw_ptr<V, I>& rhs);
   template <typename U, typename V, typename I>
-  friend ALWAYS_INLINE bool operator>=(const raw_ptr<U, I>& lhs,
-                                       const raw_ptr<V, I>& rhs);
+  friend PA_ALWAYS_INLINE bool operator>=(const raw_ptr<U, I>& lhs,
+                                          const raw_ptr<V, I>& rhs);
 
   // Comparisons with U*. These operators also handle the case where the RHS is
   // T*.
   template <typename U>
-  friend ALWAYS_INLINE bool operator==(const raw_ptr& lhs, U* rhs) {
+  friend PA_ALWAYS_INLINE bool operator==(const raw_ptr& lhs, U* rhs) {
     return lhs.GetForComparison() == rhs;
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator!=(const raw_ptr& lhs, U* rhs) {
+  friend PA_ALWAYS_INLINE bool operator!=(const raw_ptr& lhs, U* rhs) {
     return !(lhs == rhs);
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator==(U* lhs, const raw_ptr& rhs) {
+  friend PA_ALWAYS_INLINE bool operator==(U* lhs, const raw_ptr& rhs) {
     return rhs == lhs;  // Reverse order to call the operator above.
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator!=(U* lhs, const raw_ptr& rhs) {
+  friend PA_ALWAYS_INLINE bool operator!=(U* lhs, const raw_ptr& rhs) {
     return rhs != lhs;  // Reverse order to call the operator above.
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator<(const raw_ptr& lhs, U* rhs) {
+  friend PA_ALWAYS_INLINE bool operator<(const raw_ptr& lhs, U* rhs) {
     return lhs.GetForComparison() < rhs;
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator<=(const raw_ptr& lhs, U* rhs) {
+  friend PA_ALWAYS_INLINE bool operator<=(const raw_ptr& lhs, U* rhs) {
     return lhs.GetForComparison() <= rhs;
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator>(const raw_ptr& lhs, U* rhs) {
+  friend PA_ALWAYS_INLINE bool operator>(const raw_ptr& lhs, U* rhs) {
     return lhs.GetForComparison() > rhs;
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator>=(const raw_ptr& lhs, U* rhs) {
+  friend PA_ALWAYS_INLINE bool operator>=(const raw_ptr& lhs, U* rhs) {
     return lhs.GetForComparison() >= rhs;
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator<(U* lhs, const raw_ptr& rhs) {
+  friend PA_ALWAYS_INLINE bool operator<(U* lhs, const raw_ptr& rhs) {
     return lhs < rhs.GetForComparison();
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator<=(U* lhs, const raw_ptr& rhs) {
+  friend PA_ALWAYS_INLINE bool operator<=(U* lhs, const raw_ptr& rhs) {
     return lhs <= rhs.GetForComparison();
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator>(U* lhs, const raw_ptr& rhs) {
+  friend PA_ALWAYS_INLINE bool operator>(U* lhs, const raw_ptr& rhs) {
     return lhs > rhs.GetForComparison();
   }
   template <typename U>
-  friend ALWAYS_INLINE bool operator>=(U* lhs, const raw_ptr& rhs) {
+  friend PA_ALWAYS_INLINE bool operator>=(U* lhs, const raw_ptr& rhs) {
     return lhs >= rhs.GetForComparison();
   }
 
   // Comparisons with `std::nullptr_t`.
-  friend ALWAYS_INLINE bool operator==(const raw_ptr& lhs, std::nullptr_t) {
+  friend PA_ALWAYS_INLINE bool operator==(const raw_ptr& lhs, std::nullptr_t) {
     return !lhs;
   }
-  friend ALWAYS_INLINE bool operator!=(const raw_ptr& lhs, std::nullptr_t) {
+  friend PA_ALWAYS_INLINE bool operator!=(const raw_ptr& lhs, std::nullptr_t) {
     return !!lhs;  // Use !! otherwise the costly implicit cast will be used.
   }
-  friend ALWAYS_INLINE bool operator==(std::nullptr_t, const raw_ptr& rhs) {
+  friend PA_ALWAYS_INLINE bool operator==(std::nullptr_t, const raw_ptr& rhs) {
     return !rhs;
   }
-  friend ALWAYS_INLINE bool operator!=(std::nullptr_t, const raw_ptr& rhs) {
+  friend PA_ALWAYS_INLINE bool operator!=(std::nullptr_t, const raw_ptr& rhs) {
     return !!rhs;  // Use !! otherwise the costly implicit cast will be used.
   }
 
-  friend ALWAYS_INLINE void swap(raw_ptr& lhs, raw_ptr& rhs) noexcept {
+  friend PA_ALWAYS_INLINE void swap(raw_ptr& lhs, raw_ptr& rhs) noexcept {
     Impl::IncrementSwapCountForTest();
     std::swap(lhs.wrapped_ptr_, rhs.wrapped_ptr_);
   }
 
+#if BUILDFLAG(PA_USE_BASE_TRACING)
   // If T can be serialised into trace, its alias is also
   // serialisable.
   template <class U = T>
@@ -1316,8 +1326,9 @@
       perfetto::TracedValue&& context) const {
     perfetto::WriteIntoTracedValue(std::move(context), get());
   }
+#endif  // BUILDFLAG(PA_USE_BASE_TRACING)
 
-  ALWAYS_INLINE void ReportIfDangling() const noexcept {
+  PA_ALWAYS_INLINE void ReportIfDangling() const noexcept {
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
     Impl::ReportIfDangling(wrapped_ptr_);
 #endif
@@ -1327,23 +1338,23 @@
   // This getter is meant for situations where the pointer is meant to be
   // dereferenced. It is allowed to crash on nullptr (it may or may not),
   // because it knows that the caller will crash on nullptr.
-  ALWAYS_INLINE T* GetForDereference() const {
+  PA_ALWAYS_INLINE T* GetForDereference() const {
     return Impl::SafelyUnwrapPtrForDereference(wrapped_ptr_);
   }
   // This getter is meant for situations where the raw pointer is meant to be
   // extracted outside of this class, but not necessarily with an intention to
   // dereference. It mustn't crash on nullptr.
-  ALWAYS_INLINE T* GetForExtraction() const {
+  PA_ALWAYS_INLINE T* GetForExtraction() const {
     return Impl::SafelyUnwrapPtrForExtraction(wrapped_ptr_);
   }
   // This getter is meant *only* for situations where the pointer is meant to be
   // compared (guaranteeing no dereference or extraction outside of this class).
   // Any verifications can and should be skipped for performance reasons.
-  ALWAYS_INLINE T* GetForComparison() const {
+  PA_ALWAYS_INLINE T* GetForComparison() const {
     return Impl::UnsafelyUnwrapPtrForComparison(wrapped_ptr_);
   }
 
-  ALWAYS_INLINE T* GetForExtractionAndReset() {
+  PA_ALWAYS_INLINE T* GetForExtractionAndReset() {
     T* ptr = GetForExtraction();
     operator=(nullptr);
     return ptr;
@@ -1356,32 +1367,32 @@
 };
 
 template <typename U, typename V, typename I>
-ALWAYS_INLINE bool operator==(const raw_ptr<U, I>& lhs,
-                              const raw_ptr<V, I>& rhs) {
+PA_ALWAYS_INLINE bool operator==(const raw_ptr<U, I>& lhs,
+                                 const raw_ptr<V, I>& rhs) {
   return lhs.GetForComparison() == rhs.GetForComparison();
 }
 
 template <typename U, typename V, typename I>
-ALWAYS_INLINE bool operator<(const raw_ptr<U, I>& lhs,
-                             const raw_ptr<V, I>& rhs) {
+PA_ALWAYS_INLINE bool operator<(const raw_ptr<U, I>& lhs,
+                                const raw_ptr<V, I>& rhs) {
   return lhs.GetForComparison() < rhs.GetForComparison();
 }
 
 template <typename U, typename V, typename I>
-ALWAYS_INLINE bool operator>(const raw_ptr<U, I>& lhs,
-                             const raw_ptr<V, I>& rhs) {
+PA_ALWAYS_INLINE bool operator>(const raw_ptr<U, I>& lhs,
+                                const raw_ptr<V, I>& rhs) {
   return lhs.GetForComparison() > rhs.GetForComparison();
 }
 
 template <typename U, typename V, typename I>
-ALWAYS_INLINE bool operator<=(const raw_ptr<U, I>& lhs,
-                              const raw_ptr<V, I>& rhs) {
+PA_ALWAYS_INLINE bool operator<=(const raw_ptr<U, I>& lhs,
+                                 const raw_ptr<V, I>& rhs) {
   return lhs.GetForComparison() <= rhs.GetForComparison();
 }
 
 template <typename U, typename V, typename I>
-ALWAYS_INLINE bool operator>=(const raw_ptr<U, I>& lhs,
-                              const raw_ptr<V, I>& rhs) {
+PA_ALWAYS_INLINE bool operator>=(const raw_ptr<U, I>& lhs,
+                                 const raw_ptr<V, I>& rhs) {
   return lhs.GetForComparison() >= rhs.GetForComparison();
 }
 
diff --git a/base/memory/raw_ptr_unittest.cc b/base/memory/raw_ptr_unittest.cc
index 84306bd..e494b4ab 100644
--- a/base/memory/raw_ptr_unittest.cc
+++ b/base/memory/raw_ptr_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/allocator/partition_allocator/dangling_raw_ptr_checks.h"
 #include "base/allocator/partition_allocator/partition_alloc.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/numerics/checked_math.h"
+#include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
 #include "base/allocator/partition_allocator/partition_alloc_config.h"
 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
 #include "base/allocator/partition_allocator/tagging.h"
@@ -33,9 +34,9 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-#if BUILDFLAG(ENABLE_BASE_TRACING)
+#if BUILDFLAG(ENABLE_BASE_TRACING) && BUILDFLAG(PA_USE_BASE_TRACING)
 #include "third_party/perfetto/include/perfetto/test/traced_value_test_support.h"  // no-presubmit-check nogncheck
-#endif  // BUILDFLAG(ENABLE_BASE_TRACING)
+#endif  // BUILDFLAG(ENABLE_BASE_TRACING) && BUILDFLAG(PA_USE_BASE_TRACING)
 
 #if defined(PA_ENABLE_MTE_CHECKED_PTR_SUPPORT_WITH_64_BITS_POINTERS)
 #include "base/allocator/partition_allocator/partition_tag_types.h"
@@ -1302,7 +1303,7 @@
             checked_derived2_ptr);
 }
 
-#if BUILDFLAG(ENABLE_BASE_TRACING)
+#if BUILDFLAG(ENABLE_BASE_TRACING) && BUILDFLAG(PA_USE_BASE_TRACING)
 TEST_F(RawPtrTest, TracedValueSupport) {
   // Serialise nullptr.
   EXPECT_EQ(perfetto::TracedValueToString(raw_ptr<int>()), "0x0");
@@ -1325,7 +1326,7 @@
               "result");
   }
 }
-#endif  // BUILDFLAG(ENABLE_BASE_TRACING)
+#endif  // BUILDFLAG(ENABLE_BASE_TRACING) && BUILDFLAG(PA_USE_BASE_TRACING)
 
 class PmfTestBase {
  public:
diff --git a/base/memory/raw_ref.h b/base/memory/raw_ref.h
index 9cbb285..0c8afdf 100644
--- a/base/memory/raw_ref.h
+++ b/base/memory/raw_ref.h
@@ -9,6 +9,7 @@
 #include <type_traits>
 #include <utility>
 
+#include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
 #include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "third_party/abseil-cpp/absl/base/attributes.h"
@@ -167,6 +168,7 @@
     swap(lhs.inner_, rhs.inner_);
   }
 
+#if BUILDFLAG(PA_USE_BASE_TRACING)
   // If T can be serialised into trace, its alias is also
   // serialisable.
   template <class U = T>
@@ -175,6 +177,7 @@
     CHECK(inner_.get());  // Catch use-after-move.
     inner_.WriteIntoTrace(std::move(context));
   }
+#endif  // BUILDFLAG(PA_USE_BASE_TRACING)
 
   template <class U>
   friend ALWAYS_INLINE bool operator==(const raw_ref& lhs,
diff --git a/base/power_monitor/power_monitor_device_source_ios.mm b/base/power_monitor/power_monitor_device_source_ios.mm
index 8ed1d8b..b4fb1697 100644
--- a/base/power_monitor/power_monitor_device_source_ios.mm
+++ b/base/power_monitor/power_monitor_device_source_ios.mm
@@ -6,6 +6,8 @@
 
 #import <UIKit/UIKit.h>
 
+#import "base/power_monitor/power_monitor_features.h"
+
 namespace base {
 
 bool PowerMonitorDeviceSource::IsOnBatteryPower() {
@@ -23,6 +25,10 @@
 }
 
 void PowerMonitorDeviceSource::PlatformInit() {
+  if (FeatureList::IsEnabled(kRemoveIOSPowerEventNotifications)) {
+    return;
+  }
+
   NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
   id foreground =
       [nc addObserverForName:UIApplicationWillEnterForegroundNotification
diff --git a/base/power_monitor/power_monitor_features.cc b/base/power_monitor/power_monitor_features.cc
new file mode 100644
index 0000000..42b3c5a
--- /dev/null
+++ b/base/power_monitor/power_monitor_features.cc
@@ -0,0 +1,17 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/power_monitor/power_monitor_features.h"
+
+#include "base/feature_list.h"
+
+namespace base {
+
+#if BUILDFLAG(IS_IOS)
+BASE_FEATURE(kRemoveIOSPowerEventNotifications,
+             "RemoveIOSPowerEventNotifications",
+             FEATURE_DISABLED_BY_DEFAULT);
+#endif
+
+}  // namespace base
diff --git a/base/power_monitor/power_monitor_features.h b/base/power_monitor/power_monitor_features.h
new file mode 100644
index 0000000..548eb7d
--- /dev/null
+++ b/base/power_monitor/power_monitor_features.h
@@ -0,0 +1,23 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_POWER_MONITOR_POWER_MONITOR_FEATURES_H_
+#define BASE_POWER_MONITOR_POWER_MONITOR_FEATURES_H_
+
+#include "base/base_export.h"
+#include "base/feature_list.h"
+#include "build/build_config.h"
+
+namespace base {
+
+#if BUILDFLAG(IS_IOS)
+// Under this feature, iOS power monitor will not post power suspend/resume
+// event notifications on application entering background/foreground. This
+// feature can keep tcp socket connection always alive on iOS.
+BASE_EXPORT BASE_DECLARE_FEATURE(kRemoveIOSPowerEventNotifications);
+#endif
+
+}  // namespace base
+
+#endif  // BASE_POWER_MONITOR_POWER_MONITOR_FEATURES_H_
diff --git a/build/fuchsia/cipd/BUILD.gn b/build/fuchsia/cipd/BUILD.gn
index 78f5a046..12b6dd73 100644
--- a/build/fuchsia/cipd/BUILD.gn
+++ b/build/fuchsia/cipd/BUILD.gn
@@ -146,8 +146,6 @@
 #              set contains:
 #     manifest_path: The path to the generated manifest JSON file.
 #     far_sources: An optional list of CFv2 test component .far files.
-#     cfv1_far_sources: An optional list of legacy CFv1 test component .far
-#                       files.
 #
 # Required parameters used by the cipd_archive template:
 #   "package_subdirectory",
@@ -180,8 +178,7 @@
     # archive.
     sources = []
     foreach(test_set, test_sets) {
-      assert(
-          defined(test_set.far_sources) || defined(test_set.cfv1_far_sources))
+      assert(defined(test_set.far_sources))
       sources += [ test_set.manifest_path ]
       _manifest_contents = []
       if (defined(test_set.far_sources)) {
@@ -197,19 +194,6 @@
         }
         sources += test_set.far_sources
       }
-      if (defined(test_set.cfv1_far_sources)) {
-        foreach(source, test_set.cfv1_far_sources) {
-          package_name = get_path_info(source, "name")
-
-          _manifest_contents += [
-            {
-              package = package_name
-              component_name = package_name + ".cmx"
-            },
-          ]
-        }
-        sources += test_set.cfv1_far_sources
-      }
       write_file(test_set.manifest_path, _manifest_contents, "json")
     }
   }
@@ -311,13 +295,13 @@
         "${root_gen_dir}/fuchsia_web/runners/cast_runner_integration_tests/cast_runner_integration_tests.far",
         "${root_gen_dir}/fuchsia_web/runners/web_runner_integration_tests/web_runner_integration_tests.far",
         "${root_gen_dir}/fuchsia_web/webengine/web_engine_integration_tests/web_engine_integration_tests.far",
+        "${root_gen_dir}/fuchsia_web/webengine/web_engine_integration_tests_cfv1/web_engine_integration_tests_cfv1.far",
         "${root_gen_dir}/ipc/ipc_tests/ipc_tests.far",
         "${root_gen_dir}/media/media_unittests/media_unittests.far",
         "${root_gen_dir}/mojo/mojo_unittests/mojo_unittests.far",
         "${root_gen_dir}/skia/skia_unittests/skia_unittests.far",
         "${root_gen_dir}/third_party/blink/common/blink_common_unittests/blink_common_unittests.far",
       ]
-      cfv1_far_sources = [ "${root_gen_dir}/fuchsia_web/webengine/web_engine_integration_tests_cfv1/web_engine_integration_tests_cfv1.far" ]
     },
     {
       manifest_path = "${target_gen_dir}/common_tests_manifest.json"
@@ -335,8 +319,8 @@
       far_sources = [
         "${root_gen_dir}/fuchsia_web/runners/web_runner_integration_tests/web_runner_integration_tests.far",
         "${root_gen_dir}/fuchsia_web/webengine/web_engine_integration_tests/web_engine_integration_tests.far",
+        "${root_gen_dir}/fuchsia_web/webengine/web_engine_integration_tests_cfv1/web_engine_integration_tests_cfv1.far",
       ]
-      cfv1_far_sources = [ "${root_gen_dir}/fuchsia_web/webengine/web_engine_integration_tests_cfv1/web_engine_integration_tests_cfv1.far" ]
     },
     {
       manifest_path = "${target_gen_dir}/cast_runner_tests_manifest.json"
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni
index 1db3cb89..19a1fbdd 100644
--- a/build/toolchain/gcc_toolchain.gni
+++ b/build/toolchain/gcc_toolchain.gni
@@ -220,13 +220,13 @@
     }
 
     if (use_goma_thin_lto && toolchain_uses_goma && use_thin_lto) {
-      # goma_ld.py uses autoninja in an attempt to set a reasonable
+      # remote_ld.py uses autoninja in an attempt to set a reasonable
       # number of jobs, but this results in too low a value on
       # Chrome OS builders. So we pass in an explicit value.
       link_prefix =
           "$python_path " +
-          rebase_path("//tools/clang/scripts/goma_ld.py", root_build_dir) +
-          " --gomacc ${goma_path} --jobs 200 -- "
+          rebase_path("//tools/clang/scripts/remote_ld.py", root_build_dir) +
+          " --wrapper ${goma_path} --jobs 200 -- "
     } else {
       link_prefix = ""
       not_needed([ "goma_path" ])
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn
index 86f167d3..e86f698 100644
--- a/chrome/android/features/autofill_assistant/BUILD.gn
+++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -99,6 +99,7 @@
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInputActionIntegrationTest.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInterruptIntegrationTest.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantKeyboardIntegrationTest.java",
+    "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantLegalDisclaimerUiTest.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantNavigationIntegrationTest.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java",
     "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantLegalDisclaimerUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantLegalDisclaimerUiTest.java
new file mode 100644
index 0000000..1c7b7eeef
--- /dev/null
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantLegalDisclaimerUiTest.java
@@ -0,0 +1,148 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.autofill_assistant;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+
+import android.support.test.InstrumentationRegistry;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+import androidx.test.filters.MediumTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.chrome.browser.customtabs.CustomTabActivity;
+import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
+import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.components.autofill_assistant.R;
+import org.chromium.components.autofill_assistant.legal_disclaimer.AssistantLegalDisclaimerCoordinator;
+import org.chromium.components.autofill_assistant.legal_disclaimer.AssistantLegalDisclaimerDelegate;
+import org.chromium.components.autofill_assistant.legal_disclaimer.AssistantLegalDisclaimerModel;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+
+/**
+ * Tests for the Autofill Assistant Legal Disclaimer.
+ */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+public class AutofillAssistantLegalDisclaimerUiTest {
+    private AssistantLegalDisclaimerModel mModel;
+    private AssistantLegalDisclaimerCoordinator mCoordinator;
+
+    private static class TestViewHolder {
+        final View mRootView;
+        final View mMessageView;
+
+        private TestViewHolder(View rootView) {
+            mRootView = rootView;
+            mMessageView = mRootView.findViewById(R.id.legal_disclaimer_text);
+        }
+    }
+
+    @Rule
+    public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule();
+
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    static class MockDelegate implements AssistantLegalDisclaimerDelegate {
+        @Nullable
+        Integer mLinkClicked;
+
+        @Override
+        public void onLinkClicked(int link) {
+            mLinkClicked = link;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(), "about:blank"));
+        mModel = createLegalDisclaimerModel();
+        mCoordinator = createLegalDisclaimerCoordinator(mModel);
+    }
+
+    @Test
+    @MediumTest
+    public void testInitialStateIsHidden() throws Exception {
+        TestViewHolder viewHolder = attachToCoordinator();
+        onView(is(viewHolder.mRootView)).check(matches(not(isDisplayed())));
+    }
+
+    @Test
+    @MediumTest
+    public void testClickLegalDisclaimerMessageLink() throws Exception {
+        TestViewHolder viewHolder = attachToCoordinator();
+        MockDelegate delegateMock = new MockDelegate();
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mModel.setLegalDisclaimer(delegateMock, "<link3>Terms and Conditions</link3>");
+        });
+        assertNull(delegateMock.mLinkClicked);
+        onView(is(viewHolder.mMessageView))
+                .check(matches(allOf(isDisplayed(), withText("Terms and Conditions"))))
+                .perform(click());
+        assertThat(delegateMock.mLinkClicked, is(3));
+    }
+
+    @Test
+    @MediumTest
+    public void testHideLegalDisclaimer() throws Exception {
+        TestViewHolder viewHolder = attachToCoordinator();
+        MockDelegate delegateMock = new MockDelegate();
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mModel.setLegalDisclaimer(delegateMock, "<link3>Terms and Conditions</link3>");
+        });
+        onView(is(viewHolder.mMessageView))
+                .check(matches(allOf(isDisplayed(), withText("Terms and Conditions"))));
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.setLegalDisclaimer(null, null); });
+        onView(is(viewHolder.mRootView)).check(matches(not(isDisplayed())));
+    }
+
+    private CustomTabActivity getActivity() {
+        return mCustomTabActivityTestRule.getActivity();
+    }
+
+    private AssistantLegalDisclaimerModel createLegalDisclaimerModel() {
+        return TestThreadUtils.runOnUiThreadBlockingNoException(AssistantLegalDisclaimerModel::new);
+    }
+
+    private AssistantLegalDisclaimerCoordinator createLegalDisclaimerCoordinator(
+            AssistantLegalDisclaimerModel model) throws Exception {
+        AssistantLegalDisclaimerCoordinator coordinator = TestThreadUtils.runOnUiThreadBlocking(
+                () -> new AssistantLegalDisclaimerCoordinator(getActivity(), model));
+        return coordinator;
+    }
+
+    private TestViewHolder attachToCoordinator() throws Exception {
+        return TestThreadUtils.runOnUiThreadBlocking(() -> {
+            AutofillAssistantUiTestUtil.attachToCoordinator(getActivity(), mCoordinator.getView());
+            return new TestViewHolder(mCoordinator.getView());
+        });
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 2fb9f90..86a8b56a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1943,8 +1943,7 @@
                 if (!navigation.hasCommitted()) return;
 
                 try (TraceEvent e = TraceEvent.scoped("CheckSyncErrorOnDidFinishNavigation")) {
-                    SyncErrorMessage.maybeShowMessageUi(
-                            getWindowAndroid(), ChromeTabbedActivity.this);
+                    SyncErrorMessage.maybeShowMessageUi(getWindowAndroid());
                 }
                 try (TraceEvent te = TraceEvent.scoped("updateActiveWebContents")) {
                     SendTabToSelfAndroidBridge.updateActiveWebContents(tab.getWebContents());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index e722010f..86cfca3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -112,6 +112,7 @@
                 add(ChromeFeatureList.sInterestFeedV2);
                 add(ChromeFeatureList.sNewWindowAppMenu);
                 add(ChromeFeatureList.sOmniboxModernizeVisualUpdate);
+                add(ChromeFeatureList.sOmniboxRemoveExcessiveRecycledViewClearCalls);
                 add(ChromeFeatureList.sOptimizationGuidePushNotifications);
                 add(ChromeFeatureList.sOSKResizesVisualViewportByDefault);
                 add(ChromeFeatureList.sPaintPreviewDemo);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java
index e21a290..d0bece3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java
@@ -4,7 +4,7 @@
 
 package org.chromium.chrome.browser.sync.ui;
 
-import android.content.Context;
+import android.app.Activity;
 import android.content.res.Resources;
 
 import androidx.annotation.VisibleForTesting;
@@ -40,6 +40,7 @@
  */
 public class SyncErrorMessage implements SyncStateChangedListener, UnownedUserData {
     private final @SyncErrorPromptType int mType;
+    private final Activity mActivity;
     private final MessageDispatcher mMessageDispatcher;
     private final PropertyModel mModel;
     private static MessageDispatcher sMessageDispatcherForTesting;
@@ -57,9 +58,8 @@
      * d) there is a valid {@link MessageDispatcher} in this window.
      *
      * @param windowAndroid The {@link WindowAndroid} to show and dismiss message UIs.
-     * @param context The {@link Context} to get string and drawable resources.
      */
-    public static void maybeShowMessageUi(WindowAndroid windowAndroid, Context context) {
+    public static void maybeShowMessageUi(WindowAndroid windowAndroid) {
         try (TraceEvent t = TraceEvent.scoped("SyncErrorMessage.maybeShowMessageUi")) {
             if (!SyncErrorPromptUtils.shouldShowPrompt(SyncErrorPromptUtils.getSyncErrorUiType(
                         SyncSettingsUtils.getSyncError()))) {
@@ -78,17 +78,18 @@
                 // Show prompt UI next time when the previous message has disappeared.
                 return;
             }
-            SYNC_ERROR_MESSAGE_KEY.attachToHost(host, new SyncErrorMessage(dispatcher, context));
+            SYNC_ERROR_MESSAGE_KEY.attachToHost(
+                    host, new SyncErrorMessage(dispatcher, windowAndroid.getActivity().get()));
         }
     }
 
-    private SyncErrorMessage(MessageDispatcher dispatcher, Context context) {
+    private SyncErrorMessage(MessageDispatcher dispatcher, Activity activity) {
         @SyncError
         int error = SyncSettingsUtils.getSyncError();
-        String errorMessage = SyncErrorPromptUtils.getErrorMessage(context, error);
-        String title = SyncErrorPromptUtils.getTitle(context, error);
-        String primaryButtonText = SyncErrorPromptUtils.getPrimaryButtonText(context, error);
-        Resources resources = context.getResources();
+        String errorMessage = SyncErrorPromptUtils.getErrorMessage(activity, error);
+        String title = SyncErrorPromptUtils.getTitle(activity, error);
+        String primaryButtonText = SyncErrorPromptUtils.getPrimaryButtonText(activity, error);
+        Resources resources = activity.getResources();
         mModel = new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
                          .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
                                  MessageIdentifier.SYNC_ERROR)
@@ -99,7 +100,7 @@
                                  ApiCompatibilityUtils.getDrawable(
                                          resources, R.drawable.ic_sync_error_legacy_24dp))
                          .with(MessageBannerProperties.ICON_TINT_COLOR,
-                                 context.getColor(R.color.default_red))
+                                 activity.getColor(R.color.default_red))
                          .with(MessageBannerProperties.ON_PRIMARY_ACTION, this::onAccepted)
                          .with(MessageBannerProperties.ON_DISMISSED, this::onDismissed)
                          .build();
@@ -107,6 +108,7 @@
                 sMessageDispatcherForTesting == null ? dispatcher : sMessageDispatcherForTesting;
         mMessageDispatcher.enqueueWindowScopedMessage(mModel, false);
         mType = SyncErrorPromptUtils.getSyncErrorUiType(error);
+        mActivity = activity;
         SyncService.get().addSyncStateChangedListener(this);
         SyncErrorPromptUtils.updateLastShownTime();
         recordHistogram(SyncErrorPromptAction.SHOWN);
@@ -123,7 +125,7 @@
     }
 
     private @PrimaryActionClickBehavior int onAccepted() {
-        SyncErrorPromptUtils.onUserAccepted(mType);
+        SyncErrorPromptUtils.onUserAccepted(mType, mActivity);
         recordHistogram(SyncErrorPromptAction.BUTTON_CLICKED);
         return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorPromptUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorPromptUtils.java
index 74361ba7..547260a7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorPromptUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorPromptUtils.java
@@ -5,8 +5,10 @@
 package org.chromium.chrome.browser.sync.ui;
 
 import static org.chromium.base.ContextUtils.getApplicationContext;
+import static org.chromium.chrome.browser.flags.ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ERROR_MESSAGES;
 import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.SYNC_ERROR_PROMPT_SHOWN_AT_TIME;
 
+import android.app.Activity;
 import android.content.Context;
 
 import androidx.annotation.IntDef;
@@ -21,6 +23,7 @@
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
+import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
 import org.chromium.chrome.browser.sync.SyncService;
 import org.chromium.chrome.browser.sync.TrustedVaultClient;
 import org.chromium.chrome.browser.sync.settings.ManageSyncSettings;
@@ -28,7 +31,9 @@
 import org.chromium.chrome.browser.sync.settings.SyncSettingsUtils.SyncError;
 import org.chromium.components.browser_ui.settings.SettingsLauncher;
 import org.chromium.components.prefs.PrefService;
+import org.chromium.components.signin.AccountManagerFacadeProvider;
 import org.chromium.components.signin.base.CoreAccountInfo;
+import org.chromium.components.signin.identitymanager.ConsentLevel;
 import org.chromium.components.sync.TrustedVaultUserActionTriggerForUMA;
 import org.chromium.components.user_prefs.UserPrefs;
 
@@ -93,6 +98,10 @@
 
     public static String getPrimaryButtonText(Context context, @SyncError int error) {
         switch (error) {
+            case SyncError.AUTH_ERROR:
+                return ChromeFeatureList.isEnabled(UNIFIED_PASSWORD_MANAGER_ERROR_MESSAGES)
+                        ? context.getString(R.string.password_error_sign_in_button_title)
+                        : context.getString(R.string.open_settings_button);
             case SyncError.TRUSTED_VAULT_KEY_REQUIRED_FOR_EVERYTHING:
             case SyncError.TRUSTED_VAULT_KEY_REQUIRED_FOR_PASSWORDS:
             case SyncError.TRUSTED_VAULT_RECOVERABILITY_DEGRADED_FOR_EVERYTHING:
@@ -133,18 +142,22 @@
         }
     }
 
-    public static void onUserAccepted(@SyncErrorPromptType int type) {
+    public static void onUserAccepted(@SyncErrorPromptType int type, Activity activity) {
         switch (type) {
             case SyncErrorPromptType.NOT_SHOWN:
                 assert false;
                 return;
             case SyncErrorPromptType.AUTH_ERROR:
+                if (ChromeFeatureList.isEnabled(UNIFIED_PASSWORD_MANAGER_ERROR_MESSAGES)) {
+                    startUpdateCredentialsFlow(activity);
+                } else {
+                    openSyncSettings();
+                }
+                return;
             case SyncErrorPromptType.PASSPHRASE_REQUIRED:
             case SyncErrorPromptType.SYNC_SETUP_INCOMPLETE:
             case SyncErrorPromptType.CLIENT_OUT_OF_DATE:
-                SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
-                settingsLauncher.launchSettingsActivity(getApplicationContext(),
-                        ManageSyncSettings.class, ManageSyncSettings.createArguments(false));
+                openSyncSettings();
                 return;
 
             case SyncErrorPromptType.TRUSTED_VAULT_KEY_REQUIRED_FOR_EVERYTHING:
@@ -259,6 +272,22 @@
                                         exception));
     }
 
+    private static void openSyncSettings() {
+        SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
+        settingsLauncher.launchSettingsActivity(getApplicationContext(), ManageSyncSettings.class,
+                ManageSyncSettings.createArguments(false));
+    }
+
+    private static void startUpdateCredentialsFlow(Activity activity) {
+        Profile profile = Profile.getLastUsedRegularProfile();
+        final CoreAccountInfo primaryAccountInfo =
+                IdentityServicesProvider.get().getIdentityManager(profile).getPrimaryAccountInfo(
+                        ConsentLevel.SYNC);
+        assert primaryAccountInfo != null;
+        AccountManagerFacadeProvider.getInstance().updateCredentials(
+                CoreAccountInfo.getAndroidAccountFrom(primaryAccountInfo), activity, null);
+    }
+
     private static CoreAccountInfo getSyncConsentedAccountInfo() {
         if (!SyncService.get().hasSyncConsent()) {
             return null;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java
index 0230dee9..aee203b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java
@@ -28,6 +28,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Matchers;
 import org.chromium.chrome.R;
@@ -41,6 +42,7 @@
 import org.chromium.chrome.browser.sync.ui.SyncErrorPromptUtils.SyncErrorPromptType;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRenderTestRule;
+import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
 import org.chromium.components.embedder_support.util.UrlConstants;
@@ -56,6 +58,7 @@
  * Test suites for {@link SyncErrorMessage}.
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
+@DoNotBatch(reason = "TODO(crbug.com/1168590): SyncTestRule doesn't support batching.")
 @EnableFeatures({ChromeFeatureList.MESSAGES_FOR_ANDROID_INFRASTRUCTURE,
         ChromeFeatureList.MESSAGES_FOR_ANDROID_SYNC_ERROR})
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@@ -201,6 +204,7 @@
     @Test
     @LargeTest
     @Feature("RenderTest")
+    @DisableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ERROR_MESSAGES})
     public void testSyncErrorMessageForAuthErrorView() throws IOException {
         SyncErrorMessage.setMessageDispatcherForTesting(null);
         mSyncTestRule.setUpAccountAndEnableSyncForTesting();
@@ -215,6 +219,21 @@
     @Test
     @LargeTest
     @Feature("RenderTest")
+    @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ERROR_MESSAGES})
+    public void testSyncErrorMessageForAuthErrorViewModern() throws IOException {
+        SyncErrorMessage.setMessageDispatcherForTesting(null);
+        mSyncTestRule.setUpAccountAndEnableSyncForTesting();
+        mFakeSyncServiceImpl.setAuthError(GoogleServiceAuthError.State.INVALID_GAIA_CREDENTIALS);
+        mSyncTestRule.loadUrl(UrlConstants.VERSION_URL);
+        ViewGroup view = mSyncTestRule.getActivity().findViewById(R.id.message_container);
+        // Wait until the message ui is shown.
+        CriteriaHelper.pollUiThread(() -> Criteria.checkThat(view.getChildCount(), Matchers.is(1)));
+        mRenderTestRule.render(view, "sync_error_message_auth_error_modern");
+    }
+
+    @Test
+    @LargeTest
+    @Feature("RenderTest")
     public void testSyncErrorMessageForSyncSetupIncompleteView() throws IOException {
         SyncErrorMessage.setMessageDispatcherForTesting(null);
         mSyncTestRule.setUpTestAccountAndSignInWithSyncSetupAsIncomplete();
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index b11b5ad4..a05636c9 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-108.0.5344.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-108.0.5355.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 343c982..c09c3d50 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5061,6 +5061,9 @@
         <message name="IDS_EXTENSIONS_TOOLBAR_ACTION_HOVER_CARD_FOOTER_DESCRIPTION_EXTENSION_REQUESTS_ACESSS" desc="The description in the footer of the card that shows up on mouse hover of a toolbar action when the extension requests access to the current site.">
           Click this extension's icon to read &amp; change <ph name="HOST">$1<ex>google.com</ex></ph>
         </message>
+        <message name="IDS_EXTENSIONS_TOOLBAR_ACTION_HOVER_CARD_FOOTER_POLICY_LABEL_TEXT" desc="The text in the footer of the card that shows up on mouse hover of a toolbar action when extension was pinned by the administrator.">
+          Pinned by your administrator
+        </message>
 
         <if expr="not use_titlecase">
           <message name="IDS_EXTENSIONS_CONTEXT_MENU_CANT_ACCESS_PAGE" desc="The label in an extension's context menu indicating the extension cannot access the current page. (sentence case)">
@@ -5913,9 +5916,11 @@
       <message name="IDS_PASSWORD_ERROR_DESCRIPTION" desc="The description of the password manager error message.">
         Sign back in to Google Password Manager
       </message>
-      <message name="IDS_PASSWORD_ERROR_SIGN_IN_BUTTON_TITLE" desc="The title of the sign in button in the password manager error message.">
-        Sign in
-      </message>
+      <if expr="is_android">
+        <message name="IDS_PASSWORD_ERROR_SIGN_IN_BUTTON_TITLE" desc="The title of the sign in button in the password manager error message." formatter_data="android_java">
+          Sign in
+        </message>
+      </if>
       <message name="IDS_SAVE_PASSWORD_DIFFERENT_DOMAINS_TITLE" desc="The title of the save password bubble when the submitted form origin isn't equal to the page origin.">
         Save password for <ph name="ORIGIN">$1<ex>example.com</ex></ph>?
       </message>
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSIONS_TOOLBAR_ACTION_HOVER_CARD_FOOTER_POLICY_LABEL_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSIONS_TOOLBAR_ACTION_HOVER_CARD_FOOTER_POLICY_LABEL_TEXT.png.sha1
new file mode 100644
index 0000000..0a338df
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_EXTENSIONS_TOOLBAR_ACTION_HOVER_CARD_FOOTER_POLICY_LABEL_TEXT.png.sha1
@@ -0,0 +1 @@
+5e1bdfc51f850233ccdb2ee60dc9f5bd13d44e1f
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 9eb25a91..b2ba0534 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3138,37 +3138,70 @@
      std::size(kQuickDim10sQuickLock130sFeedback), nullptr},
 };
 
-const FeatureEntry::FeatureParam kVCBackgroundBlurLowest[] = {
-    {"blur_level", "lowest"},
+const FeatureEntry::FeatureParam kVCBackgroundBlurScale15Sample4[] = {
+    {"blur_scale", "0.15"},
+    {"blur_samples", "4"},
 };
 
-const FeatureEntry::FeatureParam kVCBackgroundBlurLight[] = {
-    {"blur_level", "light"},
+const FeatureEntry::FeatureParam kVCBackgroundBlurScale15Sample8[] = {
+    {"blur_scale", "0.15"},
+    {"blur_samples", "8"},
 };
 
-const FeatureEntry::FeatureParam kVCBackgroundBlurMedium[] = {
-    {"blur_level", "medium"},
+const FeatureEntry::FeatureParam kVCBackgroundBlurScale15Sample16[] = {
+    {"blur_scale", "0.15"},
+    {"blur_samples", "16"},
 };
 
-const FeatureEntry::FeatureParam kVCBackgroundBlurHeavy[] = {
-    {"blur_level", "heavy"},
+const FeatureEntry::FeatureParam kVCBackgroundBlurScale25Sample4[] = {
+    {"blur_scale", "0.25"},
+    {"blur_samples", "4"},
 };
 
-const FeatureEntry::FeatureParam kVCBackgroundBlurMaximum[] = {
-    {"blur_level", "maximum"},
+const FeatureEntry::FeatureParam kVCBackgroundBlurScale25Sample8[] = {
+    {"blur_scale", "0.25"},
+    {"blur_samples", "8"},
+};
+
+const FeatureEntry::FeatureParam kVCBackgroundBlurScale25Sample16[] = {
+    {"blur_scale", "0.25"},
+    {"blur_samples", "16"},
+};
+
+const FeatureEntry::FeatureParam kVCBackgroundBlurScale35Sample4[] = {
+    {"blur_scale", "0.35"},
+    {"blur_samples", "4"},
+};
+
+const FeatureEntry::FeatureParam kVCBackgroundBlurScale35Sample8[] = {
+    {"blur_scale", "0.35"},
+    {"blur_samples", "8"},
+};
+
+const FeatureEntry::FeatureParam kVCBackgroundBlurScale35Sample16[] = {
+    {"blur_scale", "0.35"},
+    {"blur_samples", "16"},
 };
 
 const FeatureEntry::FeatureVariation kVCBackgroundBlurVariations[] = {
-    {"Lowest Blur", kVCBackgroundBlurLowest, std::size(kVCBackgroundBlurLowest),
-     nullptr},
-    {"Light Blur", kVCBackgroundBlurLight, std::size(kVCBackgroundBlurLight),
-     nullptr},
-    {"Medium Blur", kVCBackgroundBlurMedium, std::size(kVCBackgroundBlurMedium),
-     nullptr},
-    {"Heavy Blur", kVCBackgroundBlurHeavy, std::size(kVCBackgroundBlurHeavy),
-     nullptr},
-    {"Maximum Blur", kVCBackgroundBlurMaximum,
-     std::size(kVCBackgroundBlurMaximum), nullptr},
+    {"Scale15Sample4", kVCBackgroundBlurScale15Sample4,
+     std::size(kVCBackgroundBlurScale15Sample4), nullptr},
+    {"Scale15Sample8", kVCBackgroundBlurScale15Sample8,
+     std::size(kVCBackgroundBlurScale15Sample8), nullptr},
+    {"Scale15Sample16", kVCBackgroundBlurScale15Sample16,
+     std::size(kVCBackgroundBlurScale15Sample16), nullptr},
+    {"Scale25Sample4", kVCBackgroundBlurScale25Sample4,
+     std::size(kVCBackgroundBlurScale25Sample4), nullptr},
+    {"Scale25Sample8", kVCBackgroundBlurScale25Sample8,
+     std::size(kVCBackgroundBlurScale25Sample8), nullptr},
+    {"Scale25Sample16", kVCBackgroundBlurScale25Sample16,
+     std::size(kVCBackgroundBlurScale25Sample16), nullptr},
+    {"Scale35Sample4", kVCBackgroundBlurScale35Sample4,
+     std::size(kVCBackgroundBlurScale35Sample4), nullptr},
+    {"Scale35Sample8", kVCBackgroundBlurScale35Sample8,
+     std::size(kVCBackgroundBlurScale35Sample8), nullptr},
+    {"Scale35Sample16", kVCBackgroundBlurScale35Sample16,
+     std::size(kVCBackgroundBlurScale35Sample16), nullptr},
 };
 
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -5477,6 +5510,14 @@
      flag_descriptions::kOmniboxMostVisitedTilesTitleWrapAroundName,
      flag_descriptions::kOmniboxMostVisitedTilesTitleWrapAroundDescription,
      kOsAndroid, FEATURE_VALUE_TYPE(omnibox::kMostVisitedTilesTitleWrapAround)},
+
+    {"omnibox-remove-excessive-recycled-view-clear-calls",
+     flag_descriptions::kOmniboxRemoveExcessiveRecycledViewClearCallsName,
+     flag_descriptions::
+         kOmniboxRemoveExcessiveRecycledViewClearCallsDescription,
+     kOsAndroid,
+     FEATURE_VALUE_TYPE(
+         omnibox::kOmniboxRemoveExcessiveRecycledViewClearCalls)},
 #endif  // BUILDFLAG(IS_ANDROID)
 
     {"omnibox-local-history-zero-suggest-beyond-ntp",
@@ -8957,14 +8998,6 @@
      FEATURE_WITH_PARAMS_VALUE_TYPE(ash::features::kVCBackgroundBlur,
                                     kVCBackgroundBlurVariations,
                                     "VCBackgroundBlur")},
-
-    {"vc-background-replace", flag_descriptions::kVCBackgroundReplaceName,
-     flag_descriptions::kVCBackgroundReplaceDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(ash::features::kVCBackgroundReplace)},
-
-    {"vc-portrait-relighting", flag_descriptions::kVCPortraitRelightingName,
-     flag_descriptions::kVCPortraitRelightingDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(ash::features::kVCPortraitRelighting)},
 #endif
 
 #if BUILDFLAG(IS_WIN)
@@ -9709,6 +9742,11 @@
      FEATURE_VALUE_TYPE(ash::features::kEnable16Desks)},
 #endif
 
+    {"use-nat64-for-ipv4-literal",
+     flag_descriptions::kUseNAT64ForIPv4LiteralName,
+     flag_descriptions::kUseNAT64ForIPv4LiteralDescription, kOsAll,
+     FEATURE_VALUE_TYPE(net::features::kUseNAT64ForIPv4Literal)},
+
     // NOTE: Adding a new flag requires adding a corresponding entry to enum
     // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
     // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc b/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc
index 4a52aa8..aa7c28b8 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc
@@ -721,7 +721,6 @@
   iv->icon_type = icon_type_;
   iv->uncompressed = image;
   iv->is_placeholder_icon = is_placeholder_icon_;
-  iv->is_fallback_icon = using_fallback_icon_resource_;
 
   // Apply the icon effects on the uncompressed data. If the caller requests
   // an uncompressed icon, return the uncompressed result; otherwise, encode
@@ -855,7 +854,6 @@
     LoadIconCallback fallback_adaptor = base::BindOnce(
         [](scoped_refptr<AppIconLoader> icon_loader, IconValuePtr iv) {
           if (iv) {
-            iv->is_fallback_icon = true;
             std::move(icon_loader->callback_).Run(std::move(iv));
           } else {
             icon_loader->MaybeLoadFallbackOrCompleteEmpty();
@@ -874,11 +872,11 @@
     return;
   }
 
-  if (fallback_icon_resource_ != kInvalidIconResource &&
-      !using_fallback_icon_resource_) {
-    // Set to avoid infinite loops.
-    using_fallback_icon_resource_ = true;
-    LoadIconFromResource(fallback_icon_resource_);
+  if (fallback_icon_resource_ != kInvalidIconResource) {
+    int icon_resource = fallback_icon_resource_;
+    // Resetting default icon resource to ensure no infinite loops.
+    fallback_icon_resource_ = kInvalidIconResource;
+    LoadIconFromResource(icon_resource);
     return;
   }
 
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_loader.h b/chrome/browser/apps/app_service/app_icon/app_icon_loader.h
index 2b66f02..a39475f 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_loader.h
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_loader.h
@@ -167,8 +167,7 @@
   // If |fallback_icon_resource_| is not |kInvalidIconResource|, then it is the
   // second fallback method attempted in MaybeLoadFallbackOrCompleteEmpty()
   // (after the favicon service).
-  const int fallback_icon_resource_ = kInvalidIconResource;
-  bool using_fallback_icon_resource_ = false;
+  int fallback_icon_resource_ = kInvalidIconResource;
 
   LoadIconCallback callback_;
 
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 882d287..4e62123 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -4118,8 +4118,18 @@
 
 // This test verify that the set of rules registries of a webview will be
 // removed from RulesRegistryService after the webview is gone.
-IN_PROC_BROWSER_TEST_P(WebViewChannelTest,
-                       Shim_TestRulesRegistryIDAreRemovedAfterWebViewIsGone) {
+// TODO(crbug.com/1344573): The test has the same callstack caused by the race
+// with ScopedFeatureList as the issue describes.
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_Shim_TestRulesRegistryIDAreRemovedAfterWebViewIsGone \
+  DISABLED_Shim_TestRulesRegistryIDAreRemovedAfterWebViewIsGone
+#else
+#define MAYBE_Shim_TestRulesRegistryIDAreRemovedAfterWebViewIsGone \
+  Shim_TestRulesRegistryIDAreRemovedAfterWebViewIsGone
+#endif
+IN_PROC_BROWSER_TEST_P(
+    WebViewChannelTest,
+    MAYBE_Shim_TestRulesRegistryIDAreRemovedAfterWebViewIsGone) {
   ASSERT_EQ(extensions::GetCurrentChannel(), GetChannelParam());
   SCOPED_TRACE(base::StringPrintf(
       "Testing Channel %s",
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 2d8ad852..869719c4 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -3540,7 +3540,6 @@
     "//chromeos/ime:gencode",
     "//chromeos/services/machine_learning/public/cpp",
     "//chromeos/services/network_config:in_process_instance",
-    "//chromeos/services/network_health:in_process_instance",
     "//chromeos/strings",
     "//chromeos/ui/vector_icons",
     "//chromeos/utils",
diff --git a/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc b/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc
index 4d16e525..143a6219 100644
--- a/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc
+++ b/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc
@@ -47,7 +47,6 @@
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
 #include "extensions/common/manifest.h"
-#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
 #include "url/gurl.h"
 
 using extensions::ExternalInstallInfoFile;
@@ -391,9 +390,6 @@
 
     KioskAppManager::InitializeForTesting(this);
 
-    in_process_data_decoder_ =
-        std::make_unique<data_decoder::test::InProcessDataDecoder>();
-
     InitializePrimaryAppState();
 
     extensions::ExtensionServiceTestBase::SetUp();
@@ -419,7 +415,6 @@
     primary_app_provider_->ServiceShutdown();
     secondary_apps_provider_->ServiceShutdown();
     external_apps_loader_handler_.reset();
-    in_process_data_decoder_.reset();
 
     app_launch_tracker_.reset();
 
@@ -633,9 +628,6 @@
   std::unique_ptr<extensions::ExternalProviderImpl> secondary_apps_provider_;
 
   std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_;
-
-  std::unique_ptr<data_decoder::test::InProcessDataDecoder>
-      in_process_data_decoder_;
 };
 
 TEST_F(StartupAppLauncherTest, PrimaryAppLaunchFlow) {
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.cc b/chrome/browser/ash/crosapi/crosapi_ash.cc
index 9df4f46e..acbbdd3 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.cc
+++ b/chrome/browser/ash/crosapi/crosapi_ash.cc
@@ -72,6 +72,7 @@
 #include "chrome/browser/ash/crosapi/network_settings_service_ash.h"
 #include "chrome/browser/ash/crosapi/networking_attributes_ash.h"
 #include "chrome/browser/ash/crosapi/networking_private_ash.h"
+#include "chrome/browser/ash/crosapi/parent_access_ash.h"
 #include "chrome/browser/ash/crosapi/policy_service_ash.h"
 #include "chrome/browser/ash/crosapi/prefs_ash.h"
 #include "chrome/browser/ash/crosapi/remoting_ash.h"
@@ -228,6 +229,7 @@
       networking_private_ash_(std::make_unique<NetworkingPrivateAsh>()),
       network_settings_service_ash_(std::make_unique<NetworkSettingsServiceAsh>(
           g_browser_process->local_state())),
+      parent_access_ash_(std::make_unique<ParentAccessAsh>()),
       policy_service_ash_(std::make_unique<PolicyServiceAsh>()),
       prefs_ash_(
           std::make_unique<PrefsAsh>(g_browser_process->profile_manager(),
@@ -704,6 +706,11 @@
 #endif  // BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC)
 }
 
+void CrosapiAsh::BindParentAccess(
+    mojo::PendingReceiver<mojom::ParentAccess> receiver) {
+  parent_access_ash_->BindReceiver(std::move(receiver));
+}
+
 void CrosapiAsh::BindPolicyService(
     mojo::PendingReceiver<mojom::PolicyService> receiver) {
   policy_service_ash_->BindReceiver(std::move(receiver));
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.h b/chrome/browser/ash/crosapi/crosapi_ash.h
index 28aff00..cd69dd65 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.h
+++ b/chrome/browser/ash/crosapi/crosapi_ash.h
@@ -82,6 +82,7 @@
 class NetworkChangeAsh;
 class NetworkingAttributesAsh;
 class NetworkingPrivateAsh;
+class ParentAccessAsh;
 class PolicyServiceAsh;
 class PrefsAsh;
 class PrintingMetricsAsh;
@@ -243,6 +244,8 @@
       mojo::PendingReceiver<mojom::NetworkingAttributes> receiver) override;
   void BindNetworkingPrivate(
       mojo::PendingReceiver<mojom::NetworkingPrivate> receiver) override;
+  void BindParentAccess(
+      mojo::PendingReceiver<mojom::ParentAccess> receiver) override;
   void BindPolicyService(
       mojo::PendingReceiver<mojom::PolicyService> receiver) override;
   void BindPower(mojo::PendingReceiver<mojom::Power> receiver) override;
@@ -434,6 +437,8 @@
 
   LoginStateAsh* login_state_ash() { return login_state_ash_.get(); }
 
+  ParentAccessAsh* parent_access_ash() { return parent_access_ash_.get(); }
+
   SharesheetAsh* sharesheet_ash() { return sharesheet_ash_.get(); }
 
   StructuredMetricsServiceAsh* structured_metrics_service_ash() {
@@ -511,6 +516,7 @@
   std::unique_ptr<NetworkingAttributesAsh> networking_attributes_ash_;
   std::unique_ptr<NetworkingPrivateAsh> networking_private_ash_;
   std::unique_ptr<NetworkSettingsServiceAsh> network_settings_service_ash_;
+  std::unique_ptr<ParentAccessAsh> parent_access_ash_;
   std::unique_ptr<PolicyServiceAsh> policy_service_ash_;
   std::unique_ptr<PrefsAsh> prefs_ash_;
   std::unique_ptr<PrintingMetricsAsh> printing_metrics_ash_;
diff --git a/chrome/browser/ash/crosapi/crosapi_util.cc b/chrome/browser/ash/crosapi/crosapi_util.cc
index 3705bb7..80a41992 100644
--- a/chrome/browser/ash/crosapi/crosapi_util.cc
+++ b/chrome/browser/ash/crosapi/crosapi_util.cc
@@ -92,6 +92,7 @@
 #include "chromeos/crosapi/mojom/network_settings_service.mojom.h"
 #include "chromeos/crosapi/mojom/networking_attributes.mojom.h"
 #include "chromeos/crosapi/mojom/networking_private.mojom.h"
+#include "chromeos/crosapi/mojom/parent_access.mojom.h"
 #include "chromeos/crosapi/mojom/policy_service.mojom.h"
 #include "chromeos/crosapi/mojom/power.mojom.h"
 #include "chromeos/crosapi/mojom/prefs.mojom.h"
@@ -245,7 +246,7 @@
   return {T::Uuid_, T::Version_};
 }
 
-static_assert(crosapi::mojom::Crosapi::Version_ == 96,
+static_assert(crosapi::mojom::Crosapi::Version_ == 97,
               "If you add a new crosapi, please add it to "
               "kInterfaceVersionEntries below.");
 
@@ -350,6 +351,7 @@
     MakeInterfaceVersionEntry<media_session::mojom::MediaControllerManager>(),
     MakeInterfaceVersionEntry<media_session::mojom::AudioFocusManager>(),
     MakeInterfaceVersionEntry<media_session::mojom::AudioFocusManagerDebug>(),
+    MakeInterfaceVersionEntry<crosapi::mojom::ParentAccess>(),
 };
 
 constexpr bool HasDuplicatedUuid() {
diff --git a/chrome/browser/ash/crosapi/parent_access_ash.cc b/chrome/browser/ash/crosapi/parent_access_ash.cc
index 45938fe..e77ee7a 100644
--- a/chrome/browser/ash/crosapi/parent_access_ash.cc
+++ b/chrome/browser/ash/crosapi/parent_access_ash.cc
@@ -38,8 +38,10 @@
               parent_access_ui::mojom::WebApprovalsParams::New(
                   url, child_display_name, favicon_bitmap)));
 
-  chromeos::ParentAccessDialog::ShowError show_dialog_result =
-      chromeos::ParentAccessDialog::Show(
+  chromeos::ParentAccessDialogProvider provider;
+
+  chromeos::ParentAccessDialogProvider::ShowError show_dialog_result =
+      provider.Show(
           std::move(params),
           base::BindOnce(
               [](std::unique_ptr<chromeos::ParentAccessDialog::Result> result)
@@ -54,17 +56,17 @@
   // TODO(b/246671931) Other async results will be dealt with in the
   // ParentAccessDialogCallback when it is ready.
   switch (show_dialog_result) {
-    case chromeos::ParentAccessDialog::kDialogAlreadyVisible:
+    case chromeos::ParentAccessDialogProvider::ShowError::kDialogAlreadyVisible:
       result->status = crosapi::mojom::ParentAccessResult::Status::kError;
       result->error_type =
           crosapi::mojom::ParentAccessResult::ErrorType::kAlreadyVisible;
       break;
-    case chromeos::ParentAccessDialog::kNotAChildUser:
+    case chromeos::ParentAccessDialogProvider::ShowError::kNotAChildUser:
       result->status = crosapi::mojom::ParentAccessResult::Status::kError;
       result->error_type =
           crosapi::mojom::ParentAccessResult::ErrorType::kNotAChildUser;
       break;
-    case chromeos::ParentAccessDialog::kNone:
+    case chromeos::ParentAccessDialogProvider::ShowError::kNone:
       result->status = crosapi::mojom::ParentAccessResult::Status::kUnknown;
       break;
   }
diff --git a/chrome/browser/ash/login/users/avatar/user_image_loader.cc b/chrome/browser/ash/login/users/avatar/user_image_loader.cc
index c8bec3e7..685a637 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_loader.cc
+++ b/chrome/browser/ash/login/users/avatar/user_image_loader.cc
@@ -16,25 +16,14 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/task_runner_util.h"
-#include "base/task/thread_pool.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/ash/login/helper.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/ash/image_downloader_impl.h"
 #include "components/user_manager/user_image/user_image.h"
-#include "ipc/ipc_channel.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/data_decoder/public/cpp/data_decoder.h"
-#include "services/data_decoder/public/cpp/decode_image.h"
-#include "services/data_decoder/public/mojom/image_decoder.mojom.h"
-#include "services/network/public/cpp/resource_request.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/network/public/cpp/simple_url_loader.h"
 #include "skia/ext/image_operations.h"
 #include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/encode/SkWebpEncoder.h"
 #include "ui/gfx/codec/png_codec.h"
-#include "ui/gfx/codec/webp_codec.h"
 #include "ui/gfx/skbitmap_operations.h"
 #include "url/gurl.h"
 
@@ -42,9 +31,6 @@
 namespace user_image_loader {
 namespace {
 
-constexpr int64_t kMaxImageSizeInBytes =
-    static_cast<int64_t>(IPC::Channel::kMaximumMessageSize);
-
 // Contains attributes we need to know about each image we decode.
 struct ImageInfo {
   ImageInfo(const base::FilePath& file_path,
@@ -250,112 +236,11 @@
   ImageDecoder::StartWithOptions(image_request, *data, codec, false);
 }
 
-void OnAnimationDecoded(
-    LoadedCallback loaded_cb,
-    std::vector<data_decoder::mojom::AnimationFramePtr> mojo_frames) {
-  auto frame_size = mojo_frames.size();
-  if (!frame_size) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(std::move(loaded_cb),
-                                  std::make_unique<user_manager::UserImage>()));
-    return;
-  }
-
-  // Re-encode static image as PNG and send to requester.
-  if (frame_size == 1) {
-    base::ThreadPool::PostTaskAndReplyWithResult(
-        FROM_HERE,
-        base::BindOnce(
-            [](const SkBitmap& bitmap) {
-              auto encoded = base::MakeRefCounted<base::RefCountedBytes>();
-              if (!gfx::PNGCodec::EncodeBGRASkBitmap(
-                      bitmap, /*discard_transparency=*/false,
-                      &encoded->data())) {
-                return std::make_unique<user_manager::UserImage>();
-              }
-
-              auto image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
-              image_skia.MakeThreadSafe();
-
-              auto user_image = std::make_unique<user_manager::UserImage>(
-                  image_skia, encoded, user_manager::UserImage::FORMAT_PNG);
-              user_image->MarkAsSafe();
-
-              return user_image;
-            },
-            mojo_frames[0]->bitmap),
-        std::move(loaded_cb));
-    return;
-  }
-
-  // The image is animated, re-encode as WebP animated image and send to
-  // requester.
-  std::vector<gfx::WebpCodec::Frame> frames;
-  for (auto& mojo_frame : mojo_frames) {
-    gfx::WebpCodec::Frame frame;
-    frame.bitmap = mojo_frame->bitmap;
-    frame.duration = mojo_frame->duration.InMilliseconds();
-    frames.push_back(frame);
-  }
-
-  base::ThreadPool::PostTaskAndReplyWithResult(
-      FROM_HERE,
-      base::BindOnce(
-          [](const std::vector<gfx::WebpCodec::Frame>& frames) {
-            SkWebpEncoder::Options options;
-            options.fCompression = SkWebpEncoder::Compression::kLossless;
-            // Lower quality under kLossless compression means compress faster
-            // into larger files.
-            options.fQuality = 0;
-
-            auto encoded = gfx::WebpCodec::EncodeAnimated(frames, options);
-            if (!encoded.has_value()) {
-              return std::make_unique<user_manager::UserImage>();
-            }
-
-            auto image_skia =
-                gfx::ImageSkia::CreateFrom1xBitmap(frames[0].bitmap);
-            image_skia.MakeThreadSafe();
-
-            auto bytes =
-                base::MakeRefCounted<base::RefCountedBytes>(encoded.value());
-
-            auto user_image = std::make_unique<user_manager::UserImage>(
-                image_skia, bytes, user_manager::UserImage::FORMAT_WEBP);
-            user_image->MarkAsSafe();
-
-            return user_image;
-          },
-          std::move(frames)),
-      std::move(loaded_cb));
-}
-
-void DecodeAnimation(LoadedCallback loaded_cb, base::StringPiece data) {
-  if (data.empty()) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(std::move(loaded_cb),
-                                  std::make_unique<user_manager::UserImage>()));
-    return;
-  }
-
-  base::span<const uint8_t> bytes = base::make_span(
-      reinterpret_cast<const uint8_t*>(data.data()), data.size());
-
-  data_decoder::DecodeAnimationIsolated(
-      bytes, /*shrink_to_fit=*/true, kMaxImageSizeInBytes,
-      base::BindOnce(&OnAnimationDecoded, std::move(loaded_cb)));
-}
-
-void OnImageDownloaded(std::unique_ptr<network::SimpleURLLoader> loader,
-                       LoadedCallback loaded_cb,
-                       std::unique_ptr<std::string> body) {
-  if (loader->NetError() != net::OK || !body) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(std::move(loaded_cb),
-                                  std::make_unique<user_manager::UserImage>()));
-    return;
-  }
-  DecodeAnimation(std::move(loaded_cb), *body);
+void OnImageDownloaded(LoadedCallback loaded_cb,
+                       const gfx::ImageSkia& image_skia) {
+  std::move(loaded_cb).Run(user_manager::UserImage::CreateAndEncode(
+      image_skia,
+      user_manager::UserImage::ChooseImageFormat(*image_skia.bitmap())));
 }
 
 }  // namespace
@@ -387,30 +272,16 @@
               background_task_runner, data.get(), true /* data_is_ready */);
 }
 
-void StartWithDataAnimated(base::StringPiece data, LoadedCallback loaded_cb) {
-  DecodeAnimation(std::move(loaded_cb), data);
-}
-
-void StartWithFilePathAnimated(const base::FilePath& file_path,
-                               LoadedCallback loaded_cb) {
-  base::ThreadTaskRunnerHandle::Get()->PostTaskAndReplyWithResult(
-      FROM_HERE,
-      base::BindOnce(
-          [](const base::FilePath& file_path) {
-            std::string data;
-            if (!base::ReadFileToString(file_path, &data)) {
-              return std::string();
-            }
-            return data;
-          },
-          file_path),
-      base::BindOnce(&DecodeAnimation, std::move(loaded_cb)));
-}
-
 // Used to load user images from GURL, specifically in the case of
 // retrieving images from the cloud.
-void StartWithGURLAnimated(const GURL& default_image_url,
-                           LoadedCallback loaded_cb) {
+void StartWithGURL(const GURL& default_image_url, LoadedCallback loaded_cb) {
+  if (!ash::ImageDownloader::Get()) {
+    LOG(ERROR) << "Could not retrieve image downloader for user image";
+    return;
+  }
+
+  ash::ImageDownloader::DownloadCallback download_callback =
+      base::BindOnce(&OnImageDownloaded, std::move(loaded_cb));
   constexpr net::NetworkTrafficAnnotationTag kNetworkTrafficAnnotationTag =
       net::DefineNetworkTrafficAnnotation("user_image_downloader", R"(
             semantics: {
@@ -432,25 +303,9 @@
               policy_exception_justification: "Not implemented."
             })");
 
-  auto request = std::make_unique<network::ResourceRequest>();
-  request->url = default_image_url;
-  request->credentials_mode = network::mojom::CredentialsMode::kOmit;
-
-  auto loader = network::SimpleURLLoader::Create(std::move(request),
-                                                 kNetworkTrafficAnnotationTag);
-  loader->SetRetryOptions(
-      /*max_retries=*/5,
-      network::SimpleURLLoader::RetryMode::RETRY_ON_5XX |
-          network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE |
-          network::SimpleURLLoader::RETRY_ON_NAME_NOT_RESOLVED);
-
-  auto* loader_ptr = loader.get();
-  loader_ptr->DownloadToString(
-      g_browser_process->shared_url_loader_factory().get(),
-      base::BindOnce(&OnImageDownloaded, std::move(loader),
-                     std::move(loaded_cb)),
-      network::SimpleURLLoader::kMaxBoundedStringDownloadSize);
+  ash::ImageDownloader::Get()->Download(default_image_url,
+                                        kNetworkTrafficAnnotationTag,
+                                        std::move(download_callback));
 }
-
 }  // namespace user_image_loader
 }  // namespace ash
diff --git a/chrome/browser/ash/login/users/avatar/user_image_loader.h b/chrome/browser/ash/login/users/avatar/user_image_loader.h
index 9a717f9..a288e24 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_loader.h
+++ b/chrome/browser/ash/login/users/avatar/user_image_loader.h
@@ -50,20 +50,10 @@
     int pixels_per_side,
     LoadedCallback loaded_cb);
 
-// Loads user image from provided |data| bytes. If the image is animated, encode
-// with WebP encoder, otherwise encode with PNG encoder.
-void StartWithDataAnimated(base::StringPiece data, LoadedCallback loaded_cb);
-
-// Loads user image from |file_path|. If the image is animated, encode with WebP
-// encoder, otherwise encode with PNG encoder.
-// TODO(b/251083485): Add support for external image from file.
-void StartWithFilePathAnimated(const base::FilePath& file_path,
-                               LoadedCallback loaded_cb);
-
-// Loads the default image fetched from |default_image_url|. If the image is
-// animated, encode with WebP encoder, otherwise encode with PNG encoder.
-void StartWithGURLAnimated(const GURL& default_image_url,
-                           LoadedCallback loaded_cb);
+// Loads the default image fetched from `default_image_url` and calls
+// `loaded_cb` with the resulting UserImage (which may be empty in case of
+// error).
+void StartWithGURL(const GURL& default_image_url, LoadedCallback loaded_cb);
 
 }  // namespace user_image_loader
 }  // namespace ash
diff --git a/chrome/browser/ash/login/users/avatar/user_image_manager_browsertest.cc b/chrome/browser/ash/login/users/avatar/user_image_manager_browsertest.cc
index 1ab0ce4..296f72b 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_manager_browsertest.cc
+++ b/chrome/browser/ash/login/users/avatar/user_image_manager_browsertest.cc
@@ -371,8 +371,6 @@
   const gfx::ImageSkia& default_image =
       default_user_image::GetDefaultImageDeprecated(
           default_user_image::kFirstDefaultImageIndex);
-  auto scale =
-      ui::ResourceBundle::GetSharedInstance().GetMaxResourceScaleFactor();
 
   run_loop_ = std::make_unique<base::RunLoop>();
   UserImageManager* user_image_manager =
@@ -383,17 +381,10 @@
 
   EXPECT_TRUE(user->HasDefaultImage());
   EXPECT_EQ(default_user_image::kFirstDefaultImageIndex, user->image_index());
-
+  EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
   ExpectUserImageInfo(test_account_id1_,
                       default_user_image::kFirstDefaultImageIndex,
-                      GetUserImagePath(test_account_id1_, "png"));
-
-  // Check image dimensions. Images can't be compared since we decode and
-  // re-encode the image bytes.
-  EXPECT_EQ(default_image.GetRepresentation(scale).pixel_width(),
-            user->GetImage().width());
-  EXPECT_EQ(default_image.GetRepresentation(scale).pixel_height(),
-            user->GetImage().height());
+                      GetUserImagePath(test_account_id1_, "jpg"));
 }
 
 // Verifies that SaveUserImage() correctly sets and persists the chosen user
@@ -739,8 +730,6 @@
   const gfx::ImageSkia& default_image =
       default_user_image::GetDefaultImageDeprecated(
           default_user_image::kFirstDefaultImageIndex);
-  auto scale =
-      ui::ResourceBundle::GetSharedInstance().GetMaxResourceScaleFactor();
 
   run_loop_ = std::make_unique<base::RunLoop>();
   UserImageManager* user_image_manager =
@@ -751,16 +740,10 @@
 
   EXPECT_TRUE(user->HasDefaultImage());
   EXPECT_EQ(default_user_image::kFirstDefaultImageIndex, user->image_index());
-
+  EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
   ExpectUserImageInfo(enterprise_account_id_,
                       default_user_image::kFirstDefaultImageIndex,
-                      GetUserImagePath(enterprise_account_id_, "png"));
-  // Check image dimensions. Images can't be compared since we decode and
-  // re-encode the image bytes.
-  EXPECT_EQ(default_image.GetRepresentation(scale).pixel_width(),
-            user->GetImage().width());
-  EXPECT_EQ(default_image.GetRepresentation(scale).pixel_height(),
-            user->GetImage().height());
+                      GetUserImagePath(enterprise_account_id_, "jpg"));
 
   // Set policy. Verify that the policy-provided user image is downloaded, set
   // and persisted, overriding the previously set image.
diff --git a/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc b/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc
index a425ff43..a503cf2 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc
+++ b/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc
@@ -104,8 +104,6 @@
       return ".jpg";
     case user_manager::UserImage::FORMAT_PNG:
       return ".png";
-    case user_manager::UserImage::FORMAT_WEBP:
-      return ".webp";
     default:
       NOTREACHED() << "Invalid format: " << image_format;
       return ".jpg";
@@ -290,30 +288,30 @@
           !base::DirectoryExists(image_path_)) {
         // Will refactor to remove this redundant call after the feature flag
         // IsAvatarsCloudMigrationEnabled is no longer needed.
-        user_image_loader::StartWithFilePathAnimated(
-            image_path_, base::BindOnce(&Job::OnLoadImageDone,
-                                        weak_factory_.GetWeakPtr(), false));
+        user_image_loader::StartWithFilePath(
+            parent_->background_task_runner_, image_path_,
+            ChooseCodecFromPath(image_path_),
+            0,  // Do not crop.
+            base::BindOnce(&Job::OnLoadImageDone, weak_factory_.GetWeakPtr(),
+                           false));
       } else {
         // Fetch the default image from cloud before caching it.
         image_url_ = default_user_image::GetDefaultImageUrl(image_index_);
-        user_image_loader::StartWithGURLAnimated(
+        user_image_loader::StartWithGURL(
             image_url_, base::BindOnce(&Job::OnLoadImageDone,
                                        weak_factory_.GetWeakPtr(), true));
       }
     } else {
-      auto& resource_bundle = ui::ResourceBundle::GetSharedInstance();
-      auto data = resource_bundle.GetRawDataResourceForScale(
-          default_user_image::GetDefaultImageResourceId(image_index_),
-          resource_bundle.GetMaxResourceScaleFactor());
-
+      gfx::ImageSkia default_image =
+          default_user_image::GetDefaultImageDeprecated(image_index_);
+      std::unique_ptr<user_manager::UserImage> user_image(
+          user_manager::UserImage::CreateAndEncode(
+              default_image, user_manager::UserImage::ChooseImageFormat(
+                                 *default_image.bitmap())));
       // Cache the in-use default image as part of the migration of avatar
       // images to cloud.
-      user_image_loader::StartWithDataAnimated(
-          data,
-          base::BindOnce(&Job::OnLoadImageDone, weak_factory_.GetWeakPtr(),
-                         /*save=*/true));
+      UpdateUserAndSaveImage(std::move(user_image));
     }
-
   } else if (image_index_ == user_manager::User::USER_IMAGE_EXTERNAL ||
              image_index_ == user_manager::User::USER_IMAGE_PROFILE) {
     // Load the user image from a file referenced by `image_path`. This happens
@@ -343,20 +341,21 @@
   if (ash::features::IsAvatarsCloudMigrationEnabled()) {
     // Fetch the default image from cloud before caching it.
     image_url_ = default_user_image::GetDefaultImageUrl(image_index_);
-    user_image_loader::StartWithGURLAnimated(
+    user_image_loader::StartWithGURL(
         image_url_, base::BindOnce(&Job::OnLoadImageDone,
                                    weak_factory_.GetWeakPtr(), true));
   } else {
-    auto& resource_bundle = ui::ResourceBundle::GetSharedInstance();
-    auto data = resource_bundle.GetRawDataResourceForScale(
-        default_user_image::GetDefaultImageResourceId(image_index_),
-        resource_bundle.GetMaxResourceScaleFactor());
+    gfx::ImageSkia default_image =
+        default_user_image::GetDefaultImageDeprecated(image_index_);
+    std::unique_ptr<user_manager::UserImage> user_image(
+        user_manager::UserImage::CreateAndEncode(
+            default_image, user_manager::UserImage::ChooseImageFormat(
+                               *default_image.bitmap())));
 
-    // Cache the in-use default image as part of the migration of avatar
-    // images to cloud.
-    user_image_loader::StartWithDataAnimated(
-        data, base::BindOnce(&Job::OnLoadImageDone, weak_factory_.GetWeakPtr(),
-                             /*save=*/true));
+    // Now that default images are served from the cloud, the current in-use
+    // user avatar image needs to be saved and cached in local state for
+    // offline usage.
+    UpdateUserAndSaveImage(std::move(user_image));
   }
 }
 
diff --git a/chrome/browser/ash/login/users/user_manager_unittest.cc b/chrome/browser/ash/login/users/user_manager_unittest.cc
index 0d07ff1..3d4bfe9 100644
--- a/chrome/browser/ash/login/users/user_manager_unittest.cc
+++ b/chrome/browser/ash/login/users/user_manager_unittest.cc
@@ -38,7 +38,6 @@
 #include "content/public/test/browser_task_environment.h"
 #include "extensions/common/features/feature_session_type.h"
 #include "extensions/common/mojom/feature_session_type.mojom.h"
-#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -147,13 +146,9 @@
     wallpaper_controller_client_ =
         std::make_unique<WallpaperControllerClientImpl>();
     wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);
-
-    in_process_data_decoder_ =
-        std::make_unique<data_decoder::test::InProcessDataDecoder>();
   }
 
   void TearDown() override {
-    in_process_data_decoder_.reset();
     wallpaper_controller_client_.reset();
 
     // Shut down the DeviceSettingsService.
@@ -239,8 +234,6 @@
       session_type_;
   std::unique_ptr<WallpaperControllerClientImpl> wallpaper_controller_client_;
   TestWallpaperController test_wallpaper_controller_;
-  std::unique_ptr<data_decoder::test::InProcessDataDecoder>
-      in_process_data_decoder_;
 
   content::BrowserTaskEnvironment task_environment_;
 
diff --git a/chrome/browser/ash/net/network_health/network_health_manager.cc b/chrome/browser/ash/net/network_health/network_health_manager.cc
index a2b6d3c..1094106e 100644
--- a/chrome/browser/ash/net/network_health/network_health_manager.cc
+++ b/chrome/browser/ash/net/network_health/network_health_manager.cc
@@ -7,13 +7,14 @@
 #include "base/no_destructor.h"
 #include "chrome/browser/ash/net/network_diagnostics/network_diagnostics.h"
 #include "chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.h"
-#include "chromeos/services/network_health/in_process_instance.h"
 #include "chromeos/services/network_health/network_health_service.h"
 
 namespace ash {
 namespace network_health {
 
 NetworkHealthManager::NetworkHealthManager() {
+  network_health_service_ =
+      std::make_unique<chromeos::network_health::NetworkHealthService>();
   network_diagnostics_ =
       std::make_unique<network_diagnostics::NetworkDiagnostics>(
           DebugDaemonClient::Get());
@@ -40,8 +41,7 @@
 void NetworkHealthManager::BindHealthReceiver(
     mojo::PendingReceiver<chromeos::network_health::mojom::NetworkHealthService>
         receiver) {
-  chromeos::network_health::GetInProcessInstance()->BindReceiver(
-      std::move(receiver));
+  network_health_service_->BindReceiver(std::move(receiver));
 }
 
 void NetworkHealthManager::BindDiagnosticsReceiver(
@@ -54,8 +54,7 @@
 void NetworkHealthManager::AddObserver(
     mojo::PendingRemote<chromeos::network_health::mojom::NetworkEventsObserver>
         observer) {
-  chromeos::network_health::GetInProcessInstance()->AddObserver(
-      std::move(observer));
+  network_health_service_->AddObserver(std::move(observer));
 }
 
 NetworkHealthManager* NetworkHealthManager::GetInstance() {
diff --git a/chrome/browser/ash/net/network_health/network_health_manager.h b/chrome/browser/ash/net/network_health/network_health_manager.h
index 6da030e..3bdc5b1d 100644
--- a/chrome/browser/ash/net/network_health/network_health_manager.h
+++ b/chrome/browser/ash/net/network_health/network_health_manager.h
@@ -47,6 +47,8 @@
           chromeos::network_health::mojom::NetworkEventsObserver> observer);
 
  private:
+  std::unique_ptr<chromeos::network_health::NetworkHealthService>
+      network_health_service_;
   std::unique_ptr<network_diagnostics::NetworkDiagnostics> network_diagnostics_;
 };
 
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl_unittest.cc
index 9006388..e7c7fe1 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl_unittest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl_unittest.cc
@@ -39,7 +39,6 @@
 #include "mojo/public/cpp/base/big_buffer.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -183,9 +182,6 @@
 
     user_provider_->BindInterface(
         user_provider_remote_.BindNewPipeAndPassReceiver());
-
-    in_process_data_decoder_ =
-        std::make_unique<data_decoder::test::InProcessDataDecoder>();
   }
 
   TestingProfile* profile() { return profile_; }
@@ -246,8 +242,6 @@
 
   const base::HistogramTester& histogram_tester() { return histogram_tester_; }
 
-  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
-
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
   content::BrowserTaskEnvironment task_environment_;
@@ -261,8 +255,6 @@
       user_provider_remote_;
   std::unique_ptr<PersonalizationAppUserProviderImpl> user_provider_;
   base::HistogramTester histogram_tester_;
-  std::unique_ptr<data_decoder::test::InProcessDataDecoder>
-      in_process_data_decoder_;
 };
 
 TEST_F(PersonalizationAppUserProviderImplTest, GetsUserInfo) {
@@ -291,7 +283,6 @@
   // Select a default image.
   int image_index = ash::default_user_image::GetRandomDefaultImageIndex();
   user_image_manager()->SaveUserDefaultImageIndex(image_index);
-  RunUntilIdle();
 
   // Observer received the updated image information. Because it is a default
   // image, receives a default image with the right index.
@@ -306,7 +297,6 @@
   int image_index = ash::default_user_image::GetRandomDefaultImageIndex();
   user_provider_remote()->get()->SelectDefaultImage(image_index);
   user_provider_remote()->FlushForTesting();
-  RunUntilIdle();
 
   // Observer received the updated user image of type default with the right
   // index.
@@ -380,7 +370,6 @@
 
   user_provider_remote()->get()->SelectDefaultImage(image_index);
   user_provider_remote()->FlushForTesting();
-  RunUntilIdle();
 
   // Bucket count is incremented after selecting this default image.
   histogram_tester().ExpectBucketCount(
@@ -390,7 +379,6 @@
   // Select the same image again.
   user_provider_remote()->get()->SelectDefaultImage(image_index);
   user_provider_remote()->FlushForTesting();
-  RunUntilIdle();
 
   // Bucket count is not incremented.
   histogram_tester().ExpectBucketCount(
@@ -435,7 +423,6 @@
   // Select a default image first to make sure profile is not selected.
   user_provider_remote()->get()->SelectDefaultImage(
       ash::default_user_image::GetRandomDefaultImageIndex());
-  RunUntilIdle();
   // Now select profile.
   user_provider_remote()->get()->SelectProfileImage();
   user_provider_remote()->FlushForTesting();
@@ -470,7 +457,6 @@
   user_provider_remote()->get()->SelectDefaultImage(
       ash::default_user_image::GetRandomDefaultImageIndex());
   user_provider_remote()->FlushForTesting();
-  RunUntilIdle();
 
   histogram_tester().ExpectBucketCount(
       ash::UserImageManager::kUserImageChangedHistogramName,
@@ -513,7 +499,6 @@
   user_image_manager()->SaveUserDefaultImageIndex(
       kDeprecatedImageWithSourceInfoIndex);
   SetUserImageObserver();
-  RunUntilIdle();
 
   absl::optional<default_user_image::DeprecatedSourceInfo>
       expected_source_info =
diff --git a/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc b/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
index 23b9b5d..d4c6e1d 100644
--- a/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
+++ b/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/callback_helpers.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/values_test_util.h"
 #include "chrome/browser/extensions/chrome_test_extension_loader.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_service_test_with_install.h"
@@ -28,7 +29,6 @@
 #include "extensions/common/url_pattern.h"
 #include "extensions/common/url_pattern_set.h"
 #include "extensions/common/user_script.h"
-#include "extensions/common/value_builder.h"
 #include "extensions/test/test_extension_dir.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
@@ -652,10 +652,11 @@
        RemoveAllGrantedHostPermissions_GrantedOptionalPermissions) {
   InitializeEmptyExtensionService();
 
+  static constexpr char kOptionalPermissions[] = R"(["https://example.com/*"])";
   scoped_refptr<const Extension> extension =
       ExtensionBuilder("test")
           .SetManifestKey("optional_permissions",
-                          ListBuilder().Append("https://example.com/*").Build())
+                          base::test::ParseJsonList(kOptionalPermissions))
           .Build();
 
   EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());
@@ -775,14 +776,16 @@
        GrantingHostPermissionsBeyondRequested) {
   InitializeEmptyExtensionService();
 
-  DictionaryBuilder content_script;
-  content_script
-      .Set("matches", ListBuilder().Append("https://google.com/maps").Build())
-      .Set("js", ListBuilder().Append("foo.js").Build());
+  static constexpr char kContentScripts[] = R"([
+    {
+      "matches": ["https://google.com/maps"],
+      "js": ["foo.js"]
+    }
+  ])";
   scoped_refptr<const Extension> extension =
       ExtensionBuilder("test")
           .SetManifestKey("content_scripts",
-                          ListBuilder().Append(content_script.Build()).Build())
+                          base::test::ParseJsonList(kContentScripts))
           .Build();
 
   // At installation, all permissions granted.
@@ -1056,10 +1059,11 @@
        RemoveAllURLsGrantedOptionalPermission) {
   InitializeEmptyExtensionService();
 
+  static constexpr char kOptionalPermissions[] = R"(["<all_urls>"])";
   scoped_refptr<const Extension> extension =
       ExtensionBuilder("extension")
           .SetManifestKey("optional_permissions",
-                          ListBuilder().Append("<all_urls>").Build())
+                          base::test::ParseJsonList(kOptionalPermissions))
           .Build();
   InitializeExtensionPermissions(profile(), *extension);
 
diff --git a/chrome/browser/file_select_helper.cc b/chrome/browser/file_select_helper.cc
index ab0022f9..5bcfac8f 100644
--- a/chrome/browser/file_select_helper.cc
+++ b/chrome/browser/file_select_helper.cc
@@ -159,7 +159,7 @@
 FileSelectHelper::~FileSelectHelper() {
   // There may be pending file dialogs, we need to tell them that we've gone
   // away so they don't try and call back to us.
-  if (select_file_dialog_.get())
+  if (select_file_dialog_)
     select_file_dialog_->ListenerDestroyed();
 }
 
@@ -481,14 +481,13 @@
 std::unique_ptr<ui::SelectFileDialog::FileTypeInfo>
 FileSelectHelper::GetFileTypesFromAcceptType(
     const std::vector<std::u16string>& accept_types) {
-  std::unique_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type(
-      new ui::SelectFileDialog::FileTypeInfo());
+  auto base_file_type = std::make_unique<ui::SelectFileDialog::FileTypeInfo>();
   if (accept_types.empty())
     return base_file_type;
 
   // Create FileTypeInfo and pre-allocate for the first extension list.
-  std::unique_ptr<ui::SelectFileDialog::FileTypeInfo> file_type(
-      new ui::SelectFileDialog::FileTypeInfo(*base_file_type));
+  auto file_type =
+      std::make_unique<ui::SelectFileDialog::FileTypeInfo>(*base_file_type);
   file_type->include_all_files = true;
   file_type->extensions.resize(1);
   std::vector<base::FilePath::StringType>* extensions =
@@ -707,7 +706,7 @@
 
   select_file_dialog_ = ui::SelectFileDialog::Create(
       this, std::make_unique<ChromeSelectFilePolicy>(web_contents_));
-  if (!select_file_dialog_.get())
+  if (!select_file_dialog_)
     return;
 
   dialog_mode_ = params->mode;
@@ -737,6 +736,9 @@
   // Android needs the original MIME types and an additional capture value.
   std::pair<std::vector<std::u16string>, bool> accept_types =
       std::make_pair(params->accept_types, params->use_media_capture);
+  void* accept_types_ptr = &accept_types;
+#else
+  void* accept_types_ptr = nullptr;
 #endif
 
   // Never consider the current scope as hung. The hang watching deadline (if
@@ -744,17 +746,13 @@
   // file.
   base::HangWatcher::InvalidateActiveExpectations();
 
-  select_file_dialog_->SelectFile(
-      dialog_type_, params->title, default_file_path, select_file_types_.get(),
-      select_file_types_.get() && !select_file_types_->extensions.empty()
-          ? 1
-          : 0,  // 1-based index of default extension to show.
-      base::FilePath::StringType(), owning_window,
-#if BUILDFLAG(IS_ANDROID)
-      &accept_types);
-#else
-      nullptr);
-#endif
+  // 1-based index of default extension to show.
+  int file_type_index =
+      select_file_types_ && !select_file_types_->extensions.empty() ? 1 : 0;
+  select_file_dialog_->SelectFile(dialog_type_, params->title,
+                                  default_file_path, select_file_types_.get(),
+                                  file_type_index, base::FilePath::StringType(),
+                                  owning_window, accept_types_ptr);
 
   select_file_types_.reset();
 }
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
index 17ab2c56..927169d 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
@@ -1178,7 +1178,7 @@
     PathType path_type,
     const base::FilePath& path,
     HandleType handle_type,
-    ui::SelectFileDialog::Type dialog_type,
+    UserAction user_action,
     content::GlobalRenderFrameHostId frame_id,
     base::OnceCallback<void(SensitiveEntryResult)> callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -1189,7 +1189,7 @@
   // should have a separate Chrome OS only code path to block for example the
   // root of certain external file systems.
   if (path_type == PathType::kExternal) {
-    DidConfirmSensitiveDirectoryAccess(origin, path, handle_type, dialog_type,
+    DidConfirmSensitiveDirectoryAccess(origin, path, handle_type, user_action,
                                        frame_id, std::move(callback),
                                        /*should_block=*/false);
     return;
@@ -1200,7 +1200,7 @@
       base::BindOnce(&ShouldBlockAccessToPath, path, handle_type),
       base::BindOnce(&ChromeFileSystemAccessPermissionContext::
                          DidConfirmSensitiveDirectoryAccess,
-                     GetWeakPtr(), origin, path, handle_type, dialog_type,
+                     GetWeakPtr(), origin, path, handle_type, user_action,
                      frame_id, std::move(callback)));
 }
 
@@ -1231,7 +1231,7 @@
         const url::Origin& origin,
         const base::FilePath& path,
         HandleType handle_type,
-        ui::SelectFileDialog::Type dialog_type,
+        UserAction user_action,
         content::GlobalRenderFrameHostId frame_id,
         base::OnceCallback<void(SensitiveEntryResult)> callback,
         bool should_block) {
@@ -1239,7 +1239,7 @@
   if (!should_block) {
     // If attempting to save a file with a dangerous extension, prompt the user
     // to make them confirm they actually want to save the file.
-    if (dialog_type == ui::SelectFileDialog::SELECT_SAVEAS_FILE) {
+    if (user_action == UserAction::kSave) {
       safe_browsing::DownloadFileType::DangerLevel danger_level =
           safe_browsing::FileTypePolicies::GetInstance()->GetFileDangerLevel(
               path, origin.GetURL(),
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
index 1667ac6..9fa06d87 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
@@ -85,7 +85,7 @@
       PathType path_type,
       const base::FilePath& path,
       HandleType handle_type,
-      ui::SelectFileDialog::Type dialog_type,
+      UserAction user_action,
       content::GlobalRenderFrameHostId frame_id,
       base::OnceCallback<void(SensitiveEntryResult)> callback) override;
   void PerformAfterWriteChecks(
@@ -197,7 +197,7 @@
       const url::Origin& origin,
       const base::FilePath& path,
       HandleType handle_type,
-      ui::SelectFileDialog::Type dialog_type,
+      UserAction user_action,
       content::GlobalRenderFrameHostId frame_id,
       base::OnceCallback<void(SensitiveEntryResult)> callback,
       bool should_block);
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
index fd8feb01..0085f979 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
@@ -122,12 +122,12 @@
       PathType path_type,
       const base::FilePath& path,
       HandleType handle_type,
-      ui::SelectFileDialog::Type dialog_type) {
+      UserAction user_action) {
     base::test::TestFuture<
         ChromeFileSystemAccessPermissionContext::SensitiveEntryResult>
         future;
     permission_context_->ConfirmSensitiveEntryAccess(
-        kTestOrigin, path_type, path, handle_type, dialog_type,
+        kTestOrigin, path_type, path, handle_type, user_action,
         content::GlobalRenderFrameHostId(), future.GetCallback());
     return future.Get();
   }
@@ -219,23 +219,21 @@
 #endif
 
   // Path outside any special directories should be allowed.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAllowed,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, kTestPath, HandleType::kFile,
-          ui::SelectFileDialog::Type::SELECT_OPEN_FILE));
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAllowed,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, kTestPath,
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
+  EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal, kTestPath,
+                HandleType::kFile, UserAction::kOpen));
+  EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal, kTestPath,
+                HandleType::kDirectory, UserAction::kOpen));
 
   // External (relative) paths should also be allowed.
   EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
             ConfirmSensitiveEntryAccessSync(
                 permission_context(), PathType::kExternal,
                 base::FilePath(FILE_PATH_LITERAL("foo/bar")), HandleType::kFile,
-                ui::SelectFileDialog::Type::SELECT_OPEN_FILE));
+                UserAction::kOpen));
 }
 
 TEST_F(ChromeFileSystemAccessPermissionContextTest,
@@ -244,28 +242,26 @@
   base::ScopedPathOverride home_override(base::DIR_HOME, home_dir, true, true);
 
   // Home directory itself should not be allowed.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, home_dir,
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal, home_dir,
+                HandleType::kDirectory, UserAction::kOpen));
   // Parent of home directory should also not be allowed.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, temp_dir_.GetPath(),
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal, temp_dir_.GetPath(),
+                HandleType::kDirectory, UserAction::kOpen));
   // Paths inside home directory should be allowed.
   EXPECT_EQ(
       SensitiveDirectoryResult::kAllowed,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, home_dir.AppendASCII("foo"),
-          HandleType::kFile, ui::SelectFileDialog::Type::SELECT_OPEN_FILE));
+      ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal,
+                                      home_dir.AppendASCII("foo"),
+                                      HandleType::kFile, UserAction::kOpen));
   EXPECT_EQ(
       SensitiveDirectoryResult::kAllowed,
       ConfirmSensitiveEntryAccessSync(
           permission_context(), PathType::kLocal, home_dir.AppendASCII("foo"),
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
+          HandleType::kDirectory, UserAction::kOpen));
 }
 
 TEST_F(ChromeFileSystemAccessPermissionContextTest,
@@ -274,28 +270,26 @@
   base::ScopedPathOverride app_override(base::DIR_EXE, app_dir, true, true);
 
   // App directory itself should not be allowed.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, app_dir,
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal, app_dir,
+                HandleType::kDirectory, UserAction::kOpen));
   // Parent of App directory should also not be allowed.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, temp_dir_.GetPath(),
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal, temp_dir_.GetPath(),
+                HandleType::kDirectory, UserAction::kOpen));
   // Paths inside App directory should also not be allowed.
   EXPECT_EQ(
       SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, app_dir.AppendASCII("foo"),
-          HandleType::kFile, ui::SelectFileDialog::Type::SELECT_OPEN_FILE));
+      ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal,
+                                      app_dir.AppendASCII("foo"),
+                                      HandleType::kFile, UserAction::kOpen));
   EXPECT_EQ(
       SensitiveDirectoryResult::kAbort,
       ConfirmSensitiveEntryAccessSync(
           permission_context(), PathType::kLocal, app_dir.AppendASCII("foo"),
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
+          HandleType::kDirectory, UserAction::kOpen));
 }
 
 TEST_F(ChromeFileSystemAccessPermissionContextTest,
@@ -308,34 +302,31 @@
                                              download_dir, true, true);
 
   // User Data directory itself should not be allowed.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, user_data_dir,
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
-  // Parent of User Data directory should also not be allowed.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, temp_dir_.GetPath(),
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
-  // The nested Download directory itself should not be allowed.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, download_dir,
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
-  // Paths inside the nested Download directory should be allowed.
-  EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
             ConfirmSensitiveEntryAccessSync(
-                permission_context(), PathType::kLocal,
-                download_dir.AppendASCII("foo"), HandleType::kFile,
-                ui::SelectFileDialog::Type::SELECT_OPEN_FILE));
+                permission_context(), PathType::kLocal, user_data_dir,
+                HandleType::kDirectory, UserAction::kOpen));
+  // Parent of User Data directory should also not be allowed.
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal, temp_dir_.GetPath(),
+                HandleType::kDirectory, UserAction::kOpen));
+  // The nested Download directory itself should not be allowed.
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal, download_dir,
+                HandleType::kDirectory, UserAction::kOpen));
+  // Paths inside the nested Download directory should be allowed.
+  EXPECT_EQ(
+      SensitiveDirectoryResult::kAllowed,
+      ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal,
+                                      download_dir.AppendASCII("foo"),
+                                      HandleType::kFile, UserAction::kOpen));
   EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
             ConfirmSensitiveEntryAccessSync(
                 permission_context(), PathType::kLocal,
                 download_dir.AppendASCII("foo"), HandleType::kDirectory,
-                ui::SelectFileDialog::Type::SELECT_FOLDER));
+                UserAction::kOpen));
 
 #if BUILDFLAG(IS_WIN)
   // DIR_IE_INTERNET_CACHE is an example of a directory where nested directories
@@ -345,23 +336,22 @@
                                                    internet_cache, true, true);
 
   // The nested INetCache directory itself should not be allowed.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal, internet_cache,
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
-  // Files inside the nested INetCache directory should be allowed.
-  EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
             ConfirmSensitiveEntryAccessSync(
-                permission_context(), PathType::kLocal,
-                internet_cache.AppendASCII("foo"), HandleType::kFile,
-                ui::SelectFileDialog::Type::SELECT_OPEN_FILE));
+                permission_context(), PathType::kLocal, internet_cache,
+                HandleType::kDirectory, UserAction::kOpen));
+  // Files inside the nested INetCache directory should be allowed.
+  EXPECT_EQ(
+      SensitiveDirectoryResult::kAllowed,
+      ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal,
+                                      internet_cache.AppendASCII("foo"),
+                                      HandleType::kFile, UserAction::kOpen));
   // But directories should be blocked.
   EXPECT_EQ(SensitiveDirectoryResult::kAbort,
             ConfirmSensitiveEntryAccessSync(
                 permission_context(), PathType::kLocal,
                 internet_cache.AppendASCII("foo"), HandleType::kDirectory,
-                ui::SelectFileDialog::Type::SELECT_FOLDER));
+                UserAction::kOpen));
 #endif
 }
 
@@ -375,13 +365,13 @@
       SensitiveDirectoryResult::kAbort,
       ConfirmSensitiveEntryAccessSync(
           permission_context(), PathType::kLocal, home_dir.AppendASCII(".ssh"),
-          HandleType::kDirectory, ui::SelectFileDialog::Type::SELECT_FOLDER));
+          HandleType::kDirectory, UserAction::kOpen));
   // And anything inside ~/.ssh should also be blocked
-  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
-            ConfirmSensitiveEntryAccessSync(
-                permission_context(), PathType::kLocal,
-                home_dir.AppendASCII(".ssh/id_rsa"), HandleType::kFile,
-                ui::SelectFileDialog::Type::SELECT_OPEN_FILE));
+  EXPECT_EQ(
+      SensitiveDirectoryResult::kAbort,
+      ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal,
+                                      home_dir.AppendASCII(".ssh/id_rsa"),
+                                      HandleType::kFile, UserAction::kOpen));
 }
 
 TEST_F(ChromeFileSystemAccessPermissionContextTest,
@@ -390,25 +380,22 @@
 // paths (as opposed to PathService provided paths).
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   // /dev should be blocked.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal,
-          base::FilePath(FILE_PATH_LITERAL("/dev")), HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER));
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal,
+                base::FilePath(FILE_PATH_LITERAL("/dev")),
+                HandleType::kDirectory, UserAction::kOpen));
   // As well as children of /dev.
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal,
-          base::FilePath(FILE_PATH_LITERAL("/dev/foo")), HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER));
-  EXPECT_EQ(
-      SensitiveDirectoryResult::kAbort,
-      ConfirmSensitiveEntryAccessSync(
-          permission_context(), PathType::kLocal,
-          base::FilePath(FILE_PATH_LITERAL("/dev/foo")), HandleType::kFile,
-          ui::SelectFileDialog::Type::SELECT_OPEN_FILE));
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal,
+                base::FilePath(FILE_PATH_LITERAL("/dev/foo")),
+                HandleType::kDirectory, UserAction::kOpen));
+  EXPECT_EQ(SensitiveDirectoryResult::kAbort,
+            ConfirmSensitiveEntryAccessSync(
+                permission_context(), PathType::kLocal,
+                base::FilePath(FILE_PATH_LITERAL("/dev/foo")),
+                HandleType::kFile, UserAction::kOpen));
 #endif
 }
 
@@ -419,25 +406,25 @@
             ConfirmSensitiveEntryAccessSync(
                 permission_context(), PathType::kLocal,
                 temp_dir_.GetPath().AppendASCII("test.txt"), HandleType::kFile,
-                ui::SelectFileDialog::SELECT_SAVEAS_FILE));
+                UserAction::kSave));
   // Saving files with a dangerous extension should show a prompt.
   EXPECT_EQ(SensitiveDirectoryResult::kAbort,
             ConfirmSensitiveEntryAccessSync(
                 permission_context(), PathType::kLocal,
                 temp_dir_.GetPath().AppendASCII("test.swf"), HandleType::kFile,
-                ui::SelectFileDialog::SELECT_SAVEAS_FILE));
+                UserAction::kSave));
   // Opening files with a dangerous extension should be allowed.
   EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
             ConfirmSensitiveEntryAccessSync(
                 permission_context(), PathType::kLocal,
                 temp_dir_.GetPath().AppendASCII("test.swf"), HandleType::kFile,
-                ui::SelectFileDialog::SELECT_OPEN_FILE));
+                UserAction::kOpen));
   // Opening files with a dangerous compound extension should show a prompt.
   EXPECT_EQ(SensitiveDirectoryResult::kAbort,
             ConfirmSensitiveEntryAccessSync(
                 permission_context(), PathType::kLocal,
                 temp_dir_.GetPath().AppendASCII("test.txt.swf"),
-                HandleType::kFile, ui::SelectFileDialog::SELECT_SAVEAS_FILE));
+                HandleType::kFile, UserAction::kSave));
 }
 
 TEST_F(ChromeFileSystemAccessPermissionContextTest,
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index e142c81..4655c46e 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -5128,6 +5128,11 @@
     "expiry_milestone": 108
   },
   {
+    "name": "omnibox-remove-excessive-recycled-view-clear-calls",
+    "owners": [ "rongtan", "ender", "chrome-omnibox-team@google.com" ],
+    "expiry_milestone": 110
+  },
+  {
     "name": "omnibox-remove-suggestion-header-capitalization",
     "owners": [ "rongtan", "ender", "chrome-omnibox-team@google.com" ],
     "expiry_milestone": 110
@@ -6805,6 +6810,11 @@
     "expiry_milestone": 110
   },
   {
+    "name": "use-nat64-for-ipv4-literal",
+    "owners": [ "horo", "net-dev" ],
+    "expiry_milestone": 120
+  },
+  {
     "name": "use-passthrough-command-decoder",
     "owners": [ "//third_party/angle/OWNERS" ],
     "expiry_milestone": 120
@@ -6876,12 +6886,7 @@
   },
   {
     "name": "vc-background-blur",
-    "owners": [ "shafron", "skyostil", "charleszhao", "jmpollock" ],
-    "expiry_milestone": 115
-  },
-  {
-    "name": "vc-background-replace",
-    "owners": [ "shafron", "skyostil", "charleszhao", "jmpollock" ],
+    "owners": [ "shafron", "skyostil", "charleszhao" ],
     "expiry_milestone": 115
   },
   {
@@ -6890,11 +6895,6 @@
     "expiry_milestone": 117
   },
   {
-    "name": "vc-portrait-relighting",
-    "owners": [ "shafron", "skyostil", "charleszhao", "jmpollock" ],
-    "expiry_milestone": 115
-  },
-  {
     "name": "verbose-logging-in-nacl",
     "owners": [ "fabiansommer", "native-client-dev@googlegroups.com" ],
     // This flag is useful for debugging NaCl-related issues.
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index eba4e404..6510f3cb 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2051,6 +2051,11 @@
 const char kOmniboxRemoveSuggestionHeaderCapitalizationDescription[] =
     "Remove the capitalization of the omnibox suggestion search header.";
 
+const char kOmniboxRemoveExcessiveRecycledViewClearCallsName[] =
+    "Omnibox Remove Excessive Recycled View Clear Calls";
+const char kOmniboxRemoveExcessiveRecycledViewClearCallsDescription[] =
+    "Remove excessive clear calls on RecycledViewPool in omnibox.";
+
 const char kOmniboxRemoveSuggestionHeaderChevronName[] =
     "Omnibox Remove Suggestion Header Chevron";
 const char kOmniboxRemoveSuggestionHeaderChevronDescription[] =
@@ -3071,6 +3076,12 @@
 const char kUiPartialSwapName[] = "Partial swap";
 const char kUiPartialSwapDescription[] = "Sets partial swap behavior.";
 
+const char kUseNAT64ForIPv4LiteralName[] =
+    "Use NAT64 translation for IPv4 literals";
+const char kUseNAT64ForIPv4LiteralDescription[] =
+    "Enables IPv4 to IPv6 address translation for IPv4 literals when chrome is "
+    "on an IPv6 only network";
+
 const char kUsernameFirstFlowName[] = "Username first flow voting";
 const char kUsernameFirstFlowDescription[] =
     "Support of sending votes on username first flow i.e. login "
@@ -3105,16 +3116,6 @@
 const char kVCBackgroundBlurDescription[] =
     "Enables background blur feature for video conferencing on chromebooks.";
 
-const char kVCBackgroundReplaceName[] = "Enable vc background replacement";
-const char kVCBackgroundReplaceDescription[] =
-    "Enables background replacement feature for video conferencing on "
-    "chromebooks. THIS WILL OVERRIDE BACKGROUND BLUR.";
-
-const char kVCPortraitRelightingName[] = "Enable vc portrait relighting";
-const char kVCPortraitRelightingDescription[] =
-    "Enables portrait relighting feature for video conferencing on "
-    "chromebooks. THIS WILL OVERRIDE BACKGROUND BLUR & REPLACE.";
-
 const char kV8VmFutureName[] = "Future V8 VM features";
 const char kV8VmFutureDescription[] =
     "This enables upcoming and experimental V8 VM features. "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index a5ffbaa..7700846e 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1161,6 +1161,9 @@
 extern const char kOmniboxOnDeviceHeadSuggestionsIncognitoName[];
 extern const char kOmniboxOnDeviceHeadSuggestionsIncognitoDescription[];
 
+extern const char kOmniboxRemoveExcessiveRecycledViewClearCallsName[];
+extern const char kOmniboxRemoveExcessiveRecycledViewClearCallsDescription[];
+
 extern const char kOmniboxRemoveSuggestionHeaderChevronName[];
 extern const char kOmniboxRemoveSuggestionHeaderChevronDescription[];
 
@@ -1736,18 +1739,15 @@
 extern const char kUiPartialSwapName[];
 extern const char kUiPartialSwapDescription[];
 
+extern const char kUseNAT64ForIPv4LiteralName[];
+extern const char kUseNAT64ForIPv4LiteralDescription[];
+
 extern const char kUseSearchClickForRightClickName[];
 extern const char kUseSearchClickForRightClickDescription[];
 
 extern const char kVCBackgroundBlurName[];
 extern const char kVCBackgroundBlurDescription[];
 
-extern const char kVCBackgroundReplaceName[];
-extern const char kVCBackgroundReplaceDescription[];
-
-extern const char kVCPortraitRelightingName[];
-extern const char kVCPortraitRelightingDescription[];
-
 extern const char kV8VmFutureName[];
 extern const char kV8VmFutureDescription[];
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 28445c7..0baa5367 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -368,6 +368,7 @@
     &omnibox::kMostVisitedTilesTitleWrapAround,
     &omnibox::kOmniboxAssistantVoiceSearch,
     &omnibox::kOmniboxHeaderPaddingUpdate,
+    &omnibox::kOmniboxRemoveExcessiveRecycledViewClearCalls,
     &omnibox::kOmniboxRemoveSuggestionHeaderCapitalization,
     &omnibox::kOmniboxRemoveSuggestionHeaderChevron,
     &omnibox::kOmniboxMostVisitedTilesFadingOnTablet,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
index 6daec86..a4efd600 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -84,6 +84,8 @@
                     .put(ChromeFeatureList.OMAHA_MIN_SDK_VERSION_ANDROID, false)
                     .put(ChromeFeatureList.OMNIBOX_ANDROID_AUXILIARY_SEARCH, false)
                     .put(ChromeFeatureList.OMNIBOX_MODERNIZE_VISUAL_UPDATE, false)
+                    .put(ChromeFeatureList.OMNIBOX_REMOVE_EXCESSIVE_RECYCLED_VIEW_CLEAR_CALLS,
+                            false)
                     .put(ChromeFeatureList.OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS, false)
                     .put(ChromeFeatureList.OSK_RESIZES_VISUAL_VIEWPORT, false)
                     .put(ChromeFeatureList.PAINT_PREVIEW_DEMO, false)
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 8a00aea..c50054a 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -448,6 +448,8 @@
             "OmniboxMostVisitedTilesDynamicSpacing";
     public static final String OMNIBOX_MOST_VISITED_TILES_TITLE_WRAP_AROUND =
             "OmniboxMostVisitedTilesTitleWrapAround";
+    public static final String OMNIBOX_REMOVE_EXCESSIVE_RECYCLED_VIEW_CLEAR_CALLS =
+            "OmniboxRemoveExcessiveRecycledViewClearCalls";
     public static final String OMNIBOX_REMOVE_SUGGESTION_HEADER_CHEVRON =
             "OmniboxRemoveSuggestionHeaderChevron";
     public static final String OMNIBOX_REMOVE_SUGGESTION_HEADER_CAPITALIZATION =
@@ -705,6 +707,8 @@
             new CachedFlag(OMAHA_MIN_SDK_VERSION_ANDROID, false);
     public static final CachedFlag sOmniboxModernizeVisualUpdate =
             new CachedFlag(OMNIBOX_MODERNIZE_VISUAL_UPDATE, false);
+    public static final CachedFlag sOmniboxRemoveExcessiveRecycledViewClearCalls =
+            new CachedFlag(OMNIBOX_REMOVE_EXCESSIVE_RECYCLED_VIEW_CLEAR_CALLS, false);
     public static final CachedFlag sOptimizationGuidePushNotifications =
             new CachedFlag(OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS, false);
     public static final CachedFlag sOSKResizesVisualViewportByDefault =
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/animated_image_with_larger_text_first.html b/chrome/browser/page_load_metrics/integration_tests/data/animated_image_with_larger_text_first.html
index 1f19a9d..af74933 100644
--- a/chrome/browser/page_load_metrics/integration_tests/data/animated_image_with_larger_text_first.html
+++ b/chrome/browser/page_load_metrics/integration_tests/data/animated_image_with_larger_text_first.html
@@ -1,6 +1,8 @@
 <body>
 <div style="width: 500px; height: 500px; background: blue">
-  This is an extremely contentful div. I swear.
+  This is an extremely contentful div. I swear. It has words and a background
+  and everything. There's even four different sentences of actual content to
+  fill it up.
 </div>
 <script>
 const run_test = async () => {
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/is_video.html b/chrome/browser/page_load_metrics/integration_tests/data/is_video.html
new file mode 100644
index 0000000..bddedfe
--- /dev/null
+++ b/chrome/browser/page_load_metrics/integration_tests/data/is_video.html
@@ -0,0 +1,9 @@
+<video autoplay muted src="/images/pattern.ogv" width="300">
+<script>
+const run_test = async () => {
+  await new Promise(resolve => {
+    new PerformanceObserver(list => resolve())
+      .observe({type: "largest-contentful-paint", buffered: true});
+  });
+};
+</script>
diff --git a/chrome/browser/page_load_metrics/integration_tests/jsdeps.gni b/chrome/browser/page_load_metrics/integration_tests/jsdeps.gni
index d3f414f..8e7bee3 100644
--- a/chrome/browser/page_load_metrics/integration_tests/jsdeps.gni
+++ b/chrome/browser/page_load_metrics/integration_tests/jsdeps.gni
@@ -9,6 +9,7 @@
   "//third_party/blink/web_tests/external/wpt/images/green-100x50.png",
   "//third_party/blink/web_tests/external/wpt/images/green-16x16.png",
   "//third_party/blink/web_tests/external/wpt/images/green-256x256.png",
+  "//third_party/blink/web_tests/external/wpt/images/pattern.ogv",
   "//third_party/blink/web_tests/external/wpt/layout-instability/resources/util.js",
   "//third_party/blink/web_tests/external/wpt/layout-instability/simple-block-movement.html",
   "//third_party/blink/web_tests/external/wpt/layout-instability/sources-enclosure.html",
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
index 92560ce..7afa4f8c 100644
--- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -18,6 +18,7 @@
 #include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h"
 #include "components/paint_preview/buildflags/buildflags.h"
 #include "content/public/browser/render_widget_host_view.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/hit_test_region_observer.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
index 6a8dfd7..7282914 100644
--- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
@@ -481,6 +481,31 @@
           30 /* image_bpp = "8.0 - 9.0" */);
 }
 
+TEST_F(UkmPageLoadMetricsObserverTest, LargestImagePaintVideo) {
+  page_load_metrics::mojom::PageLoadTiming timing;
+  page_load_metrics::InitPageLoadTimingForTest(&timing);
+  timing.navigation_start = base::Time::FromDoubleT(1);
+  timing.paint_timing->largest_contentful_paint->largest_image_paint =
+      base::Milliseconds(600);
+  timing.paint_timing->largest_contentful_paint->largest_image_paint_size = 50u;
+  timing.paint_timing->largest_contentful_paint->type =
+      blink::LargestContentfulPaintTypeToUKMFlags(
+          blink::LargestContentfulPaintType::kVideo);
+  timing.paint_timing->largest_contentful_paint->image_bpp = 8.5;
+  PopulateExperimentalLCP(timing.paint_timing);
+  PopulateRequiredTimingFields(&timing);
+
+  NavigateAndCommit(GURL(kTestUrl1));
+  tester()->SimulateTimingUpdate(timing);
+
+  // Simulate closing the tab.
+  DeleteContents();
+
+  TestLCP(600, LargestContentTextOrImage::kImage, true /* test_main_frame */,
+          30 /* image_bpp = "8.0 - 9.0" */,
+          blink::LargestContentfulPaintType::kVideo);
+}
+
 TEST_F(UkmPageLoadMetricsObserverTest, LargestImagePaintAnimated) {
   page_load_metrics::mojom::PageLoadTiming timing;
   page_load_metrics::InitPageLoadTimingForTest(&timing);
diff --git a/chrome/browser/password_manager/account_password_store_factory.cc b/chrome/browser/password_manager/account_password_store_factory.cc
index b69b5963..62bde03 100644
--- a/chrome/browser/password_manager/account_password_store_factory.cc
+++ b/chrome/browser/password_manager/account_password_store_factory.cc
@@ -51,11 +51,13 @@
 using password_manager::PasswordStoreInterface;
 using password_manager::UnsyncedCredentialsDeletionNotifier;
 
-#if !BUILDFLAG(IS_ANDROID)
-
 namespace {
 
-void UpdateAllFormManagersAndPasswordReuseManager(Profile* profile) {
+void SyncEnabledOrDisabled(Profile* profile) {
+#if BUILDFLAG(IS_ANDROID)
+  NOTREACHED();
+#else
+  // Update all form managers.
   for (Browser* browser : *BrowserList::GetInstance()) {
     if (browser->profile() != profile)
       continue;
@@ -70,8 +72,10 @@
       PasswordReuseManagerFactory::GetForProfile(profile);
   if (reuse_manager)
     reuse_manager->AccountStoreStateChanged();
+#endif  // BUILDFLAG(IS_ANDROID)
 }
 
+#if !BUILDFLAG(IS_ANDROID)
 class UnsyncedCredentialsDeletionNotifierImpl
     : public UnsyncedCredentialsDeletionNotifier {
  public:
@@ -112,18 +116,9 @@
 UnsyncedCredentialsDeletionNotifierImpl::GetWeakPtr() {
   return weak_ptr_factory_.GetWeakPtr();
 }
-
-}  // namespace
-
 #endif  // !BUILDFLAG(IS_ANDROID)
 
-void SyncEnabledOrDisabled(Profile* profile) {
-#if BUILDFLAG(IS_ANDROID)
-  NOTREACHED();
-#else
-  UpdateAllFormManagersAndPasswordReuseManager(profile);
-#endif  // BUILDFLAG(IS_ANDROID)
-}
+}  // namespace
 
 // static
 scoped_refptr<PasswordStoreInterface>
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index b51a7d6..8e2958c 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -53,7 +53,6 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/test_utils.h"
-#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -170,13 +169,9 @@
     session_type_ = extensions::ScopedCurrentFeatureSessionType(
         extensions::GetCurrentFeatureSessionType());
 #endif
-
-    in_process_data_decoder_ =
-        std::make_unique<data_decoder::test::InProcessDataDecoder>();
   }
 
   void TearDown() override {
-    in_process_data_decoder_.reset();
     TestingBrowserProcess::GetGlobal()->SetProfileManager(nullptr);
     content::RunAllTasksUntilIdle();
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -320,9 +315,6 @@
   base::ScopedTempDir temp_dir_;
   ScopedTestingLocalState local_state_;
 
-  std::unique_ptr<data_decoder::test::InProcessDataDecoder>
-      in_process_data_decoder_;
-
   content::BrowserTaskEnvironment task_environment_;
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.html b/chrome/browser/resources/settings/site_settings/site_entry.html
index 556862a..655094b 100644
--- a/chrome/browser/resources/settings/site_settings/site_entry.html
+++ b/chrome/browser/resources/settings/site_settings/site_entry.html
@@ -72,12 +72,12 @@
               </span>
             </div>
           </div>
-          <template is="dom-if" if="[[shouldShowPolicyPrefIndicator_(
-                                          siteGroup.fpsEnterpriseManaged)]]">
+          <template is="dom-if" restamp if="[[shouldShowPolicyPrefIndicator_(
+                            siteGroup.fpsEnterpriseManaged)]]">
             <cr-policy-pref-indicator
                 id="fpsPolicy" pref="[[fpsEnterprisePref_]]"
-                icon-aria-label="[[label]]" on-mouseenter="onShowTooltip_"
-                on-focus="onShowTooltip_" focus-row-control focus-type="policy">
+                icon-aria-label="[[label]]"
+                focus-row-control focus-type="policy">
             </cr-policy-pref-indicator>
           </template>
           <cr-icon-button id="expandIcon" class="icon-expand-more"
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.ts b/chrome/browser/resources/settings/site_settings/site_entry.ts
index 41a4e2a7..8b276f7 100644
--- a/chrome/browser/resources/settings/site_settings/site_entry.ts
+++ b/chrome/browser/resources/settings/site_settings/site_entry.ts
@@ -359,11 +359,11 @@
 
   /**
    * Evaluates whether the policy icon should be shown.
-   * @returns False when `fpsEnterprisePref_` is undefined, otherwise true.
+   * @returns True when `this.siteGroup.fpsEnterpriseManaged` is true,
+   * otherwise false.
    */
   private shouldShowPolicyPrefIndicator_(): boolean {
-    this.updatePolicyPref_();
-    return !!this.fpsEnterprisePref_;
+    return !!this.siteGroup.fpsEnterpriseManaged;
   }
 
   /**
@@ -375,7 +375,10 @@
           enforcement: chrome.settingsPrivate.Enforcement.ENFORCED,
           controlledBy: chrome.settingsPrivate.ControlledBy.DEVICE_POLICY,
         }) :
-        undefined;
+        Object.assign({
+          enforcement: undefined,
+          controlledBy: undefined,
+        });
   }
 
   /**
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.cc b/chrome/browser/safe_browsing/user_interaction_observer.cc
index 3798d45..9f33e92a 100644
--- a/chrome/browser/safe_browsing/user_interaction_observer.cc
+++ b/chrome/browser/safe_browsing/user_interaction_observer.cc
@@ -245,7 +245,7 @@
   // DO NOT add code past this point. |this| is destroyed.
 }
 
-void SafeBrowsingUserInteractionObserver::OnBubbleAdded() {
+void SafeBrowsingUserInteractionObserver::OnPromptAdded() {
   // The page requested a permission that triggered a permission prompt. Deny
   // and show the interstitial.
   permissions::PermissionRequestManager* permission_request_manager =
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.h b/chrome/browser/safe_browsing/user_interaction_observer.h
index 096ea17..49d08fa4 100644
--- a/chrome/browser/safe_browsing/user_interaction_observer.h
+++ b/chrome/browser/safe_browsing/user_interaction_observer.h
@@ -99,7 +99,7 @@
   void OnPaste() override;
 
   // permissions::PermissionRequestManager::Observer methods:
-  void OnBubbleAdded() override;
+  void OnPromptAdded() override;
 
   // Called by the JavaScript dialog manager when the current page is about to
   // show a JavaScript dialog (alert, confirm or prompt). Shows the
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc
index 030cde00..a317e711 100644
--- a/chrome/browser/supervised_user/supervised_user_interstitial.cc
+++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -64,7 +64,20 @@
 namespace {
 
 // For use in histograms.
-enum Commands { PREVIEW, BACK, NTP, ACCESS_REQUEST, HISTOGRAM_BOUNDING_VALUE };
+//
+// The enum values should remain synchronized with the enum
+// ManagedModeBlockingCommand in tools/metrics/histograms/enums.xml.
+//
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class Commands {
+  // PREVIEW = 0,
+  BACK = 1,
+  // NTP = 2,
+  REMOTE_ACCESS_REQUEST = 3,
+  LOCAL_ACCESS_REQUEST = 4,
+  HISTOGRAM_BOUNDING_VALUE = 5
+};
 
 // For use in histograms.The enum values should remain synchronized with the
 // enum ManagedUserURLRequestPermissionSource in
@@ -250,8 +263,8 @@
   DCHECK_EQ(web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId(),
             frame_id());
 
-  UMA_HISTOGRAM_ENUMERATION("ManagedMode.BlockingInterstitialCommand", BACK,
-                            HISTOGRAM_BOUNDING_VALUE);
+  UMA_HISTOGRAM_ENUMERATION("ManagedMode.BlockingInterstitialCommand",
+                            Commands::BACK, Commands::HISTOGRAM_BOUNDING_VALUE);
   AttemptMoveAwayFromCurrentFrameURL();
   OnInterstitialDone();
 }
@@ -259,16 +272,9 @@
 void SupervisedUserInterstitial::RequestUrlAccessRemote(
     base::OnceCallback<void(bool)> callback) {
   UMA_HISTOGRAM_ENUMERATION("ManagedMode.BlockingInterstitialCommand",
-                            ACCESS_REQUEST, HISTOGRAM_BOUNDING_VALUE);
-
-  RequestPermissionSource source;
-  if (web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId() == frame_id())
-    source = RequestPermissionSource::MAIN_FRAME;
-  else
-    source = RequestPermissionSource::SUB_FRAME;
-
-  UMA_HISTOGRAM_ENUMERATION("ManagedUsers.RequestPermissionSource", source,
-                            RequestPermissionSource::HISTOGRAM_BOUNDING_VALUE);
+                            Commands::REMOTE_ACCESS_REQUEST,
+                            Commands::HISTOGRAM_BOUNDING_VALUE);
+  OutputRequestPermissionSourceMetric();
 
   SupervisedUserService* supervised_user_service =
       SupervisedUserServiceFactory::GetForProfile(profile_);
@@ -278,7 +284,10 @@
 
 void SupervisedUserInterstitial::RequestUrlAccessLocal(
     base::OnceCallback<void(bool)> callback) {
-  // TODO(b/195461480): Log metrics.
+  UMA_HISTOGRAM_ENUMERATION("ManagedMode.BlockingInterstitialCommand",
+                            Commands::LOCAL_ACCESS_REQUEST,
+                            Commands::HISTOGRAM_BOUNDING_VALUE);
+  OutputRequestPermissionSourceMetric();
 
   SupervisedUserService* supervised_user_service =
       SupervisedUserServiceFactory::GetForProfile(profile_);
@@ -338,3 +347,14 @@
   web_contents_ = nullptr;
   navigation_observer->OnInterstitialDone(frame_id_);
 }
+
+void SupervisedUserInterstitial::OutputRequestPermissionSourceMetric() {
+  RequestPermissionSource source;
+  if (web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId() == frame_id())
+    source = RequestPermissionSource::MAIN_FRAME;
+  else
+    source = RequestPermissionSource::SUB_FRAME;
+
+  UMA_HISTOGRAM_ENUMERATION("ManagedUsers.RequestPermissionSource", source,
+                            RequestPermissionSource::HISTOGRAM_BOUNDING_VALUE);
+}
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.h b/chrome/browser/supervised_user/supervised_user_interstitial.h
index 0c580de..30d98d92 100644
--- a/chrome/browser/supervised_user/supervised_user_interstitial.h
+++ b/chrome/browser/supervised_user/supervised_user_interstitial.h
@@ -76,6 +76,8 @@
 
   void OnInterstitialDone();
 
+  void OutputRequestPermissionSourceMetric();
+
   // Owns SupervisedUserNavigationObserver which owns us.
   raw_ptr<content::WebContents> web_contents_;
 
diff --git a/chrome/browser/supervised_user/web_approvals_manager.cc b/chrome/browser/supervised_user/web_approvals_manager.cc
index 290d7d7..0ebecbd 100644
--- a/chrome/browser/supervised_user/web_approvals_manager.cc
+++ b/chrome/browser/supervised_user/web_approvals_manager.cc
@@ -87,14 +87,14 @@
               parent_access_ui::mojom::WebApprovalsParams::New(
                   url.GetWithEmptyPath(), child_display_name, favicon_bytes)));
 
-  chromeos::ParentAccessDialog::ShowError result =
-      chromeos::ParentAccessDialog::Show(
-          std::move(params),
-          base::BindOnce(
-              [](std::unique_ptr<
-                  chromeos::ParentAccessDialog::ParentAccessDialog::Result>
-                     result) -> void {}));
-  if (result != chromeos::ParentAccessDialog::ShowError::kNone) {
+  chromeos::ParentAccessDialogProvider provider;
+  chromeos::ParentAccessDialogProvider::ShowError result = provider.Show(
+      std::move(params),
+      base::BindOnce(
+          [](std::unique_ptr<chromeos::ParentAccessDialog::Result> result)
+              -> void {}));
+
+  if (result != chromeos::ParentAccessDialogProvider::ShowError::kNone) {
     LOG(ERROR) << "Error showing ParentAccessDialog: " << result;
     std::move(callback).Run(false);
     return;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 4992c43..814de96 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -5542,7 +5542,6 @@
       "//chrome/common/extensions/api",
       "//components/drive",
       "//components/guest_view/browser",
-      "//components/services/app_service/public/cpp:icon_loader",
       "//extensions/browser",
       "//extensions/browser/api/management",
       "//extensions/common:mojom",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxFeatures.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxFeatures.java
index a4ac350..4e95927 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxFeatures.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxFeatures.java
@@ -55,4 +55,11 @@
     private static boolean enabledModernizeVisualUpdateOnTablet() {
         return ENABLE_MODERNIZE_VISUAL_UPDATE_ON_TABLET.getValue();
     }
+
+    /**
+     * Returns whether excessive calls to RecycledViewPool#clear should be removed.
+     */
+    public static boolean shouldRemoveExcessiveRecycledViewClearCalls() {
+        return ChromeFeatureList.sOmniboxRemoveExcessiveRecycledViewClearCalls.isEnabled();
+    }
 }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
index b2b96e1..0a311b7 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
@@ -22,6 +22,7 @@
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.omnibox.LocationBarDataProvider;
+import org.chromium.chrome.browser.omnibox.OmniboxFeatures;
 import org.chromium.chrome.browser.omnibox.R;
 import org.chromium.chrome.browser.omnibox.UrlBar.UrlTextChangeListener;
 import org.chromium.chrome.browser.omnibox.UrlBarEditingTextStateProvider;
@@ -148,7 +149,9 @@
 
                 // Start with visibility GONE to ensure that show() is called.
                 // http://crbug.com/517438
-                dropdown.getViewGroup().setVisibility(View.GONE);
+                if (!OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+                    dropdown.getViewGroup().setVisibility(View.GONE);
+                }
                 dropdown.getViewGroup().setClipToPadding(false);
 
                 OmniboxSuggestionsDropdownAdapter adapter =
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
index 263e6a2..71f43c6 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -29,6 +29,7 @@
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.omnibox.LocationBarDataProvider;
+import org.chromium.chrome.browser.omnibox.OmniboxFeatures;
 import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
 import org.chromium.chrome.browser.omnibox.R;
 import org.chromium.chrome.browser.omnibox.UrlBarEditingTextStateProvider;
@@ -101,6 +102,9 @@
     private boolean mClearFocusAfterNavigation;
     private boolean mClearFocusAfterNavigationAsynchronously;
 
+    // TODO(crbug.com/1373795): Remove interface SuggestionVisibilityState and
+    // mSuggestionVisibilityState after feature OmniboxRemoveExcessiveRecycledViewClearCalls is
+    // released to stable and ready to be removed.
     @IntDef({SuggestionVisibilityState.DISALLOWED, SuggestionVisibilityState.PENDING_ALLOW,
             SuggestionVisibilityState.ALLOWED})
     @Retention(RetentionPolicy.SOURCE)
@@ -202,11 +206,15 @@
         mDropdownViewInfoListBuilder.destroy();
     }
 
+    // TODO(crbug.com/1373795): Remove this function after feature
+    // OmniboxRemoveExcessiveRecycledViewClearCalls is released to stable and ready to be removed.
     @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
     void setSuggestionVisibilityState(@SuggestionVisibilityState int state) {
         mSuggestionVisibilityState = state;
     }
 
+    // TODO(crbug.com/1373795): Remove this function after feature
+    // OmniboxRemoveExcessiveRecycledViewClearCalls is released to stable and ready to be removed.
     private @SuggestionVisibilityState int getSuggestionVisibilityState() {
         return mSuggestionVisibilityState;
     }
@@ -307,7 +315,9 @@
             mUrlFocusTime = System.currentTimeMillis();
             mJankTracker.startTrackingScenario(JankScenario.OMNIBOX_FOCUS);
 
-            setSuggestionVisibilityState(SuggestionVisibilityState.PENDING_ALLOW);
+            if (!OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+                setSuggestionVisibilityState(SuggestionVisibilityState.PENDING_ALLOW);
+            }
 
             // Ask directly for zero-suggestions related to current input, unless the user is
             // currently visiting SearchActivity and the input is populated from the launch intent.
@@ -336,7 +346,9 @@
                             mDelegate.didFocusUrlFromFakebox(), /*isPrefetch=*/false),
                     mSuggestionsListScrolled);
 
-            setSuggestionVisibilityState(SuggestionVisibilityState.DISALLOWED);
+            if (!OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+                setSuggestionVisibilityState(SuggestionVisibilityState.DISALLOWED);
+            }
             mEditSessionState = EditSessionState.INACTIVE;
             mNewOmniboxEditSessionTimestamp = -1;
             // Prevent any upcoming omnibox suggestions from showing once a URL is loaded (and as
@@ -352,9 +364,13 @@
      * org.chromium.chrome.browser.omnibox.UrlFocusChangeListener#onUrlAnimationFinished(boolean)
      */
     void onUrlAnimationFinished(boolean hasFocus) {
-        setSuggestionVisibilityState(hasFocus ? SuggestionVisibilityState.ALLOWED
-                                              : SuggestionVisibilityState.DISALLOWED);
-        updateOmniboxSuggestionsVisibility();
+        if (OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+            updateOmniboxSuggestionsVisibility(hasFocus);
+        } else {
+            setSuggestionVisibilityState(hasFocus ? SuggestionVisibilityState.ALLOWED
+                                                  : SuggestionVisibilityState.DISALLOWED);
+            updateOmniboxSuggestionsVisibility();
+        }
     }
 
     /**
@@ -703,9 +719,11 @@
     @Override
     public void onSuggestionsReceived(
             AutocompleteResult autocompleteResult, String inlineAutocompleteText, boolean isFinal) {
-        if (mShouldPreventOmniboxAutocomplete
-                || getSuggestionVisibilityState() == SuggestionVisibilityState.DISALLOWED) {
-            return;
+        if (!OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+            if (mShouldPreventOmniboxAutocomplete
+                    || getSuggestionVisibilityState() == SuggestionVisibilityState.DISALLOWED) {
+                return;
+            }
         }
 
         if (mShouldCacheSuggestions) {
@@ -728,7 +746,9 @@
                 defaultMatchIsSearch = newSuggestions.get(0).isSearchSuggestion();
             }
             mDelegate.onSuggestionsChanged(inlineAutocompleteText, defaultMatchIsSearch);
-            updateOmniboxSuggestionsVisibility();
+            if (!OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+                updateOmniboxSuggestionsVisibility();
+            }
         }
 
         mListPropertyModel.set(SuggestionListProperties.LIST_IS_FINAL, isFinal);
@@ -907,6 +927,8 @@
         }
     }
 
+    // TODO(crbug.com/1373795): Remove this function after feature
+    // OmniboxRemoveExcessiveRecycledViewClearCalls is released to stable and ready to be removed.
     /**
      * Update whether the omnibox suggestions are visible.
      */
@@ -914,6 +936,15 @@
         boolean shouldBeVisible =
                 getSuggestionVisibilityState() == SuggestionVisibilityState.ALLOWED
                 && getSuggestionCount() > 0;
+        updateOmniboxSuggestionsVisibility(shouldBeVisible);
+    }
+
+    /**
+     * Update whether the omnibox suggestions are visible.
+     *
+     * @param shouldBeVisible whether the omnibox suggestions are visible
+     */
+    private void updateOmniboxSuggestionsVisibility(boolean shouldBeVisible) {
         boolean wasVisible = mListPropertyModel.get(SuggestionListProperties.VISIBLE);
         mListPropertyModel.set(SuggestionListProperties.VISIBLE, shouldBeVisible);
         if (shouldBeVisible && !wasVisible) {
@@ -936,7 +967,10 @@
 
         mDropdownViewInfoListManager.clear();
         mAutocompleteResult = AutocompleteResult.EMPTY_RESULT;
-        updateOmniboxSuggestionsVisibility();
+
+        if (!OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+            updateOmniboxSuggestionsVisibility();
+        }
     }
 
     /**
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java
index 7d8573c..c93d1be 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java
@@ -186,7 +186,12 @@
             setMaxRecycledViews(OmniboxSuggestionUiType.DEFAULT, 20);
             setMaxRecycledViews(OmniboxSuggestionUiType.EDIT_URL_SUGGESTION, 1);
             setMaxRecycledViews(OmniboxSuggestionUiType.ANSWER_SUGGESTION, 1);
-            setMaxRecycledViews(OmniboxSuggestionUiType.ENTITY_SUGGESTION, 5);
+            if (OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+                setMaxRecycledViews(OmniboxSuggestionUiType.ENTITY_SUGGESTION, 8);
+            } else {
+                setMaxRecycledViews(OmniboxSuggestionUiType.ENTITY_SUGGESTION, 5);
+            }
+
             setMaxRecycledViews(OmniboxSuggestionUiType.TAIL_SUGGESTION, 15);
             setMaxRecycledViews(OmniboxSuggestionUiType.CLIPBOARD_SUGGESTION, 1);
             setMaxRecycledViews(OmniboxSuggestionUiType.HEADER, 4);
@@ -285,8 +290,12 @@
         return manager.findViewByPosition(index);
     }
 
+    // TODO(crbug.com/1373795): Remove this function after feature
+    // OmniboxRemoveExcessiveRecycledViewClearCalls is released to stable and ready to be removed.
     /** Show (and properly size) the suggestions list. */
     public void show() {
+        if (OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) return;
+
         if (getVisibility() == VISIBLE) return;
 
         setVisibility(VISIBLE);
@@ -297,8 +306,12 @@
         mLayoutScrollListener.resetKeyboardShowState();
     }
 
+    // TODO(crbug.com/1373795): Remove this function after feature
+    // OmniboxRemoveExcessiveRecycledViewClearCalls is released to stable and ready to be removed.
     /** Hide the suggestions list and release any cached resources. */
     public void hide() {
+        if (OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) return;
+
         if (getVisibility() != VISIBLE) return;
         setVisibility(GONE);
         getRecycledViewPool().clear();
@@ -339,6 +352,10 @@
             adjustSidePadding();
             mAlignmentView.addOnLayoutChangeListener(mAlignmentViewLayoutListener);
         }
+
+        if (OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+            resetSelection();
+        }
     }
 
     @Override
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java
index 4dbd093a..e43a941 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java
@@ -9,8 +9,10 @@
 
 import androidx.annotation.Nullable;
 
+import org.chromium.chrome.browser.omnibox.OmniboxFeatures;
 import org.chromium.ui.UiUtils;
 import org.chromium.ui.modelutil.ListObservable;
+import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
 
@@ -41,13 +43,27 @@
             // Actual View showing the dropdown.
             View dropdownView = view.dropdown.getViewGroup();
             if (visible) {
-                view.container.setVisibility(View.VISIBLE);
-                if (dropdownView.getParent() == null) view.container.addView(dropdownView);
-                view.dropdown.show();
+                if (OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+                    if (dropdownView.getParent() == null) {
+                        view.container.addView(dropdownView);
+                        // When showing the suggestions list for the first time, make sure to apply
+                        // appropriate visibility to freshly inflated container.
+                        // This is later handled by subsequent calls to updateContainerVisibility()
+                        // performed whenever the suggestion model list changes.
+                        updateContainerVisibility(model, view.container);
+                    }
+                } else {
+                    view.container.setVisibility(View.VISIBLE);
+                    if (dropdownView.getParent() == null) view.container.addView(dropdownView);
+                    view.dropdown.show();
+                }
             } else {
-                view.dropdown.hide();
                 UiUtils.removeViewFromParent(dropdownView);
-                view.container.setVisibility(View.INVISIBLE);
+
+                if (!OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+                    view.dropdown.hide();
+                    view.container.setVisibility(View.INVISIBLE);
+                }
             }
         } else if (SuggestionListProperties.EMBEDDER.equals(propertyKey)) {
             view.dropdown.setEmbedder(model.get(SuggestionListProperties.EMBEDDER));
@@ -58,17 +74,43 @@
                 view.dropdown.emitWindowContentChanged();
             }
         } else if (SuggestionListProperties.SUGGESTION_MODELS.equals(propertyKey)) {
-            // This should only ever be bound once.
-            model.get(SuggestionListProperties.SUGGESTION_MODELS)
-                    .addObserver(new ListObservable.ListObserver<Void>() {
-                        @Override
-                        public void onItemRangeChanged(ListObservable<Void> source, int index,
-                                int count, @Nullable Void payload) {
-                            view.dropdown.resetSelection();
-                        }
-                    });
+            if (OmniboxFeatures.shouldRemoveExcessiveRecycledViewClearCalls()) {
+                ModelList listItems = model.get(SuggestionListProperties.SUGGESTION_MODELS);
+                listItems.addObserver(new ListObservable.ListObserver<Void>() {
+                    @Override
+                    public void onItemRangeChanged(ListObservable<Void> source, int index,
+                            int count, @Nullable Void payload) {
+                        view.dropdown.resetSelection();
+                    }
+
+                    @Override
+                    public void onItemRangeInserted(ListObservable source, int index, int count) {
+                        updateContainerVisibility(model, view.container);
+                    }
+
+                    @Override
+                    public void onItemRangeRemoved(ListObservable source, int index, int count) {
+                        updateContainerVisibility(model, view.container);
+                    }
+                });
+            } else {
+                // This should only ever be bound once.
+                model.get(SuggestionListProperties.SUGGESTION_MODELS)
+                        .addObserver(new ListObservable.ListObserver<Void>() {
+                            @Override
+                            public void onItemRangeChanged(ListObservable<Void> source, int index,
+                                    int count, @Nullable Void payload) {
+                                view.dropdown.resetSelection();
+                            }
+                        });
+            }
         } else if (SuggestionListProperties.COLOR_SCHEME.equals(propertyKey)) {
             view.dropdown.refreshPopupBackground(model.get(SuggestionListProperties.COLOR_SCHEME));
         }
     }
+
+    private static void updateContainerVisibility(PropertyModel model, ViewGroup container) {
+        ModelList listItems = model.get(SuggestionListProperties.SUGGESTION_MODELS);
+        container.setVisibility(listItems.size() == 0 ? View.GONE : View.VISIBLE);
+    }
 }
diff --git a/chrome/browser/ui/permission_bubble/permission_bubble_browser_test_util.h b/chrome/browser/ui/permission_bubble/permission_bubble_browser_test_util.h
index ec78c4d..5709a801c 100644
--- a/chrome/browser/ui/permission_bubble/permission_bubble_browser_test_util.h
+++ b/chrome/browser/ui/permission_bubble/permission_bubble_browser_test_util.h
@@ -58,7 +58,7 @@
   bool ShouldDropCurrentRequestIfCannotShowQuietly() const override;
   bool WasCurrentRequestAlreadyDisplayed() override;
   void SetDismissOnTabClose() override {}
-  void SetBubbleShown() override {}
+  void SetPromptShown() override {}
   void SetDecisionTime() override {}
   bool RecreateView() override;
 
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc
index 2547f59..c75227c3 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc
@@ -4,13 +4,11 @@
 
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h"
 
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.h"
-#include "components/keyed_service/core/keyed_service.h"
 #include "components/saved_tab_groups/saved_tab_group_model.h"
 
-class Profile;
-
 SavedTabGroupKeyedService::SavedTabGroupKeyedService(Profile* profile)
-    : model_(profile), listener_(&model_), profile_(profile) {}
+    : profile_(profile), listener_(model(), profile) {}
 
 SavedTabGroupKeyedService::~SavedTabGroupKeyedService() = default;
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h
index 5f10867..1382c07 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h
@@ -5,13 +5,14 @@
 #ifndef CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_KEYED_SERVICE_H_
 #define CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_KEYED_SERVICE_H_
 
-#include "base/memory/raw_ptr.h"
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/saved_tab_groups/saved_tab_group_model.h"
 
 class Profile;
 
+// Serves to instantiate and own the SavedTabGroup infrastructure for the
+// browser.
 class SavedTabGroupKeyedService : public KeyedService {
  public:
   explicit SavedTabGroupKeyedService(Profile* profile);
@@ -25,9 +26,15 @@
   Profile* profile() { return profile_; }
 
  private:
-  SavedTabGroupModel model_;
-  SavedTabGroupModelListener listener_;
+  // The profile used to instantiate the keyed service.
   raw_ptr<Profile> profile_ = nullptr;
+
+  // The current representation of this profiles saved tab groups.
+  SavedTabGroupModel model_;
+
+  // Listens to and observers all tabstrip models; updating the
+  // SavedTabGroupModel when necessary.
+  SavedTabGroupModelListener listener_;
 };
 
 #endif  // CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_KEYED_SERVICE_H_
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.cc
index 726a400..24e6b0c 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.cc
@@ -18,8 +18,11 @@
 SavedTabGroupModelListener::SavedTabGroupModelListener() = default;
 
 SavedTabGroupModelListener::SavedTabGroupModelListener(
-    SavedTabGroupModel* model)
-    : model_(model) {
+    SavedTabGroupModel* model,
+    Profile* profile)
+    : model_(model), profile_(profile) {
+  DCHECK(model);
+  DCHECK(profile);
   BrowserList::GetInstance()->AddObserver(this);
   for (Browser* browser : *BrowserList::GetInstance())
     OnBrowserAdded(browser);
@@ -47,7 +50,7 @@
 }
 
 void SavedTabGroupModelListener::OnBrowserAdded(Browser* browser) {
-  if (model_->profile() != browser->profile())
+  if (profile_ != browser->profile())
     return;
   if (observed_browsers_.count(browser)) {
     // TODO(crbug.com/1345680): Investigate the root cause of duplicate calls.
@@ -58,7 +61,7 @@
 }
 
 void SavedTabGroupModelListener::OnBrowserRemoved(Browser* browser) {
-  if (model_->profile() != browser->profile())
+  if (profile_ != browser->profile())
     return;
   observed_browsers_.erase(browser);
   browser->tab_strip_model()->RemoveObserver(this);
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.h
index 2da0a11..b874270 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.h
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_listener.h
@@ -14,6 +14,7 @@
 class Browser;
 class SavedTabGroupModel;
 class TabStripModel;
+class Profile;
 
 // Serves to maintain and listen to browsers who contain saved tab groups and
 // update the model if a saved tab group was changed.
@@ -22,7 +23,8 @@
  public:
   // Used for testing.
   SavedTabGroupModelListener();
-  explicit SavedTabGroupModelListener(SavedTabGroupModel* model);
+  explicit SavedTabGroupModelListener(SavedTabGroupModel* model,
+                                      Profile* profile);
   SavedTabGroupModelListener(const SavedTabGroupModelListener&) = delete;
   SavedTabGroupModelListener& operator=(
       const SavedTabGroupModelListener& other) = delete;
@@ -41,6 +43,7 @@
  private:
   base::flat_set<raw_ptr<Browser>> observed_browsers_;
   raw_ptr<SavedTabGroupModel> model_ = nullptr;
+  raw_ptr<Profile> profile_;
 };
 
 #endif  // CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_MODEL_LISTENER_H_
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.cc
index 4744ecfd..7c2b1c53 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.cc
@@ -17,8 +17,9 @@
 // static
 SavedTabGroupKeyedService* SavedTabGroupServiceFactory::GetForProfile(
     Profile* profile) {
+  DCHECK(profile);
   return static_cast<SavedTabGroupKeyedService*>(
-      GetInstance().GetServiceForBrowserContext(profile, true /* create */));
+      GetInstance().GetServiceForBrowserContext(profile, /*create=*/true));
 }
 
 SavedTabGroupServiceFactory::SavedTabGroupServiceFactory()
@@ -28,6 +29,7 @@
 
 KeyedService* SavedTabGroupServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
+  DCHECK(context);
   Profile* profile = Profile::FromBrowserContext(context);
   return new SavedTabGroupKeyedService(profile);
 }
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
index 1c15014..aaa2c65 100644
--- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
+++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
@@ -12,21 +12,27 @@
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h"
 #include "chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/saved_tab_groups/saved_tab_group_tab.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/view_utils.h"
 
 namespace {
 SavedTabGroupModel* GetSavedTabGroupModelFromBrowser(Browser* browser) {
+  DCHECK(browser);
   SavedTabGroupKeyedService* keyed_service =
       SavedTabGroupServiceFactory::GetForProfile(browser->profile());
   return keyed_service ? keyed_service->model() : nullptr;
 }
 }  // namespace
 
+// TODO(crbug/1372008): Prevent `SavedTabGroupBar` from instantiating if the
+// corresponding feature flag is disabled.
 SavedTabGroupBar::SavedTabGroupBar(Browser* browser,
                                    SavedTabGroupModel* saved_tab_group_model,
                                    bool animations_enabled = true)
@@ -39,14 +45,11 @@
           GetLayoutConstant(TOOLBAR_ELEMENT_PADDING));
   SetLayoutManager(std::move(layout_manager));
 
-  if (saved_tab_group_model_) {
-    saved_tab_group_model_->AddObserver(this);
-    const std::vector<SavedTabGroup>& saved_tab_groups =
-        saved_tab_group_model_->saved_tab_groups();
-    for (size_t index = 0; index < saved_tab_groups.size(); index++) {
-      AddTabGroupButton(saved_tab_groups[index], index);
-    }
-  }
+  if (!saved_tab_group_model_)
+    return;
+
+  saved_tab_group_model_->AddObserver(this);
+  AddAllButtons();
 }
 
 SavedTabGroupBar::SavedTabGroupBar(Browser* browser,
@@ -69,29 +72,54 @@
       l10n_util::GetStringUTF8(IDS_ACCNAME_SAVED_TAB_GROUPS));
 }
 
-void SavedTabGroupBar::SavedTabGroupAdded(const SavedTabGroup& group,
-                                          int index) {
-  AddTabGroupButton(group, index);
+void SavedTabGroupBar::SavedTabGroupAddedLocally(const base::GUID& guid) {
+  SavedTabGroupAdded(guid);
+}
+
+void SavedTabGroupBar::SavedTabGroupRemovedLocally(
+    const SavedTabGroup* removed_group) {
+  SavedTabGroupRemoved(removed_group->saved_guid());
+}
+
+void SavedTabGroupBar::SavedTabGroupUpdatedLocally(const base::GUID& guid) {
+  SavedTabGroupUpdated(guid);
+}
+
+void SavedTabGroupBar::SavedTabGroupReorderedLocally() {
+  for (views::View* child : children()) {
+    const absl::optional<int> model_index = saved_tab_group_model_->GetIndexOf(
+        views::AsViewClass<SavedTabGroupButton>(child)->guid());
+    ReorderChildView(child, model_index.value());
+  }
+
   PreferredSizeChanged();
 }
 
-void SavedTabGroupBar::SavedTabGroupRemoved(int index) {
-  RemoveTabGroupButton(index);
-  PreferredSizeChanged();
+void SavedTabGroupBar::SavedTabGroupAddedFromSync(const base::GUID& guid) {
+  SavedTabGroupAdded(guid);
 }
 
-void SavedTabGroupBar::SavedTabGroupUpdated(const SavedTabGroup& group,
-                                            int index) {
-  RemoveTabGroupButton(index);
-  AddTabGroupButton(group, index);
-  PreferredSizeChanged();
+void SavedTabGroupBar::SavedTabGroupRemovedFromSync(
+    const SavedTabGroup* removed_group) {
+  SavedTabGroupRemoved(removed_group->saved_guid());
 }
 
-void SavedTabGroupBar::SavedTabGroupMoved(const SavedTabGroup& group,
-                                          int old_index,
-                                          int new_index) {
-  ReorderChildView(children().at(old_index), new_index);
-  PreferredSizeChanged();
+void SavedTabGroupBar::SavedTabGroupUpdatedFromSync(const base::GUID& guid) {
+  SavedTabGroupUpdated(guid);
+}
+
+int SavedTabGroupBar::CalculatePreferredWidthRestrictedBy(int max_x) {
+  const int button_padding = GetLayoutConstant(TOOLBAR_ELEMENT_PADDING);
+  int current_x = 0;
+  // iterate through the list of buttons in the child views
+  for (auto* button : children()) {
+    gfx::Size preferred_size = button->GetPreferredSize();
+    int next_x = current_x + preferred_size.width() + button_padding;
+    if (next_x > max_x)
+      return current_x;
+    current_x = next_x;
+  }
+  return current_x;
 }
 
 void SavedTabGroupBar::AddTabGroupButton(const SavedTabGroup& group,
@@ -113,11 +141,43 @@
       index);
 }
 
-void SavedTabGroupBar::RemoveTabGroupButton(int index) {
-  // Check that the index is valid for buttons
-  DCHECK_LT(index, static_cast<int>(children().size()));
+void SavedTabGroupBar::SavedTabGroupAdded(const base::GUID& guid) {
+  absl::optional<int> index = saved_tab_group_model_->GetIndexOf(guid);
+  if (!index.has_value())
+    return;
+  AddTabGroupButton(*saved_tab_group_model_->Get(guid), index.value());
+  PreferredSizeChanged();
+}
 
-  RemoveChildViewT(children().at(index));
+void SavedTabGroupBar::SavedTabGroupRemoved(const base::GUID& guid) {
+  RemoveTabGroupButton(guid);
+  PreferredSizeChanged();
+}
+
+void SavedTabGroupBar::SavedTabGroupUpdated(const base::GUID& guid) {
+  absl::optional<int> index = saved_tab_group_model_->GetIndexOf(guid);
+  if (!index.has_value())
+    return;
+  const SavedTabGroup* group = saved_tab_group_model_->Get(guid);
+  RemoveTabGroupButton(guid);
+  AddTabGroupButton(*group, index.value());
+  PreferredSizeChanged();
+}
+
+void SavedTabGroupBar::AddAllButtons() {
+  const std::vector<SavedTabGroup>& saved_tab_groups =
+      saved_tab_group_model_->saved_tab_groups();
+
+  for (size_t index = 0; index < saved_tab_groups.size(); index++)
+    AddTabGroupButton(saved_tab_groups[index], index);
+}
+
+void SavedTabGroupBar::RemoveTabGroupButton(const base::GUID& guid) {
+  // Make sure we have a valid button before trying to remove it.
+  views::View* button = GetButton(guid);
+  DCHECK(button);
+
+  RemoveChildViewT(button);
 }
 
 void SavedTabGroupBar::RemoveAllButtons() {
@@ -125,6 +185,16 @@
     RemoveChildViewT(children().at(index));
 }
 
+views::View* SavedTabGroupBar::GetButton(const base::GUID& guid) {
+  for (views::View* child : children()) {
+    if (views::IsViewClass<SavedTabGroupButton>(child) &&
+        views::AsViewClass<SavedTabGroupButton>(child)->guid() == guid)
+      return child;
+  }
+
+  return nullptr;
+}
+
 void SavedTabGroupBar::OnTabGroupButtonPressed(const base::GUID& id,
                                                const ui::Event& event) {
   DCHECK(saved_tab_group_model_ && saved_tab_group_model_->Contains(id));
@@ -140,17 +210,3 @@
                               group->saved_tabs().size());
   }
 }
-
-int SavedTabGroupBar::CalculatePreferredWidthRestrictedBy(int max_x) {
-  const int button_padding = GetLayoutConstant(TOOLBAR_ELEMENT_PADDING);
-  int current_x = 0;
-  // iterate through the list of buttons in the child views
-  for (auto* button : children()) {
-    gfx::Size preferred_size = button->GetPreferredSize();
-    int next_x = current_x + preferred_size.width() + button_padding;
-    if (next_x > max_x)
-      return current_x;
-    current_x = next_x;
-  }
-  return current_x;
-}
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h
index ee21051e..0b05cf8d 100644
--- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h
+++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h
@@ -7,12 +7,14 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.h"
 #include "components/saved_tab_groups/saved_tab_group_model.h"
 #include "components/saved_tab_groups/saved_tab_group_model_observer.h"
 #include "content/public/browser/page.h"
 #include "ui/views/accessible_pane_view.h"
 
 class Browser;
+class SavedTabGroupButton;
 
 namespace content {
 class PageNavigator;
@@ -43,39 +45,59 @@
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
 
   // SavedTabGroupModelObserver
-  void SavedTabGroupAdded(const SavedTabGroup& group, int index) override;
-  void SavedTabGroupRemoved(int index) override;
-  void SavedTabGroupUpdated(const SavedTabGroup& group, int index) override;
-  void SavedTabGroupMoved(const SavedTabGroup& group,
-                          int old_index,
-                          int new_index) override;
+  void SavedTabGroupAddedLocally(const base::GUID& guid) override;
+  void SavedTabGroupRemovedLocally(const SavedTabGroup* removed_group) override;
+  void SavedTabGroupUpdatedLocally(const base::GUID& guid) override;
+  void SavedTabGroupReorderedLocally() override;
+  void SavedTabGroupAddedFromSync(const base::GUID& guid) override;
+  void SavedTabGroupRemovedFromSync(
+      const SavedTabGroup* removed_group) override;
+  void SavedTabGroupUpdatedFromSync(const base::GUID& guid) override;
 
   // Calculates what the visible width would be when a restriction on width is
   // placed on the bar.
   int CalculatePreferredWidthRestrictedBy(int width_restriction);
 
  private:
+  // Adds the saved group denoted by `guid` as a button in the
+  // `SavedTabGroupBar` if the `guid` exists in `saved_tab_group_model_`.
+  void SavedTabGroupAdded(const base::GUID& guid);
+
+  // Removes the button denoted by `removed_group`'s guid from the
+  // `SavedTabGroupBar`.
+  void SavedTabGroupRemoved(const base::GUID& guid);
+
+  // Updates the button (color, name, tab list) denoted by `guid` in the
+  // `SavedTabGroupBar` if the `guid` exists in `saved_tab_group_model_`.
+  void SavedTabGroupUpdated(const base::GUID& guid);
+
   // Adds the button to the child views for a new tab group at a specific index.
   // Also adds a button ptr to the tab_group_buttons_ list.
   void AddTabGroupButton(const SavedTabGroup& group, int index);
 
+  // Adds all buttons currently stored in `saved_tab_group_model_`.
+  void AddAllButtons();
+
   // Removes the button from the child views at a specific index. Also removes
   // the button ptr from the tab_group_buttons_ list.
-  void RemoveTabGroupButton(int index);
+  void RemoveTabGroupButton(const base::GUID& guid);
 
   // Remove all buttons currently in the bar.
   void RemoveAllButtons();
 
-  // the callback that the button calls when clicked by a user.
+  // Find the button that matches `guid`.
+  views::View* GetButton(const base::GUID& guid);
+
+  // The callback that the button calls when clicked by a user.
   void OnTabGroupButtonPressed(const base::GUID& id, const ui::Event& event);
 
   // Provides a callback that returns the page navigator
   base::RepeatingCallback<content::PageNavigator*()> GetPageNavigatorGetter();
 
-  // the model this tab group bar listens to.
+  // The model this tab group bar listens to.
   raw_ptr<SavedTabGroupModel> saved_tab_group_model_;
 
-  // the page navigator used to create tab groups
+  // The page navigator used to create tab groups
   raw_ptr<content::PageNavigator> page_navigator_ = nullptr;
 
   raw_ptr<Browser> browser_;
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc
index ac5a434..27420d7 100644
--- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc
@@ -94,6 +94,9 @@
 
   saved_tab_group_model()->Add(kSavedTabGroup1);
   EXPECT_EQ(1u, saved_tab_group_bar()->children().size());
+
+  saved_tab_group_model()->AddedFromSync(kSavedTabGroup2);
+  EXPECT_EQ(2u, saved_tab_group_bar()->children().size());
 }
 
 TEST_F(SavedTabGroupBarUnitTest, BarsWithSameModelsHaveSameButtons) {
@@ -112,11 +115,17 @@
   // Remove the group and expect no buttons.
   saved_tab_group_model()->Remove(kSavedTabGroup1.saved_guid());
   EXPECT_EQ(0u, saved_tab_group_bar()->children().size());
+
+  saved_tab_group_model()->AddedFromSync(kSavedTabGroup1);
+
+  // Remove the group and expect no buttons.
+  saved_tab_group_model()->RemovedFromSync(kSavedTabGroup1.saved_guid());
+  EXPECT_EQ(0u, saved_tab_group_bar()->children().size());
 }
 
 TEST_F(SavedTabGroupBarUnitTest, UpdatedVisualDataMakesChangeToSpecificView) {
   saved_tab_group_model()->Add(kSavedTabGroup1);
-  saved_tab_group_model()->Add(kSavedTabGroup2);
+  saved_tab_group_model()->AddedFromSync(kSavedTabGroup2);
 
   tab_groups::TabGroupVisualData saved_tab_group_visual_data(kNewTitle,
                                                              kNewColor);
@@ -125,13 +134,21 @@
   // second button to stay the same.
   saved_tab_group_model()->UpdateVisualData(kSavedTabGroup1.saved_guid(),
                                             &saved_tab_group_visual_data);
+  saved_tab_group_model()->UpdatedVisualDataFromSync(
+      kSavedTabGroup2.saved_guid(), &saved_tab_group_visual_data);
 
   SavedTabGroupButton* new_button_1 = views::AsViewClass<SavedTabGroupButton>(
       saved_tab_group_bar()->children()[0]);
+  SavedTabGroupButton* new_button_2 = views::AsViewClass<SavedTabGroupButton>(
+      saved_tab_group_bar()->children()[1]);
+
   ASSERT_TRUE(!!new_button_1);
+  ASSERT_TRUE(!!new_button_2);
 
   EXPECT_EQ(new_button_1->GetText(), kNewTitle);
   EXPECT_EQ(new_button_1->tab_group_color_id(), kNewColor);
+  EXPECT_EQ(new_button_2->GetText(), kNewTitle);
+  EXPECT_EQ(new_button_2->tab_group_color_id(), kNewColor);
 }
 
 TEST_F(SavedTabGroupBarUnitTest, MoveButtonFromModelMove) {
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
index fd78b66..b6f9d4d 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -129,7 +129,8 @@
               : nullptr),
       display_mode_(display_mode),
       action_hover_card_controller_(
-          std::make_unique<ToolbarActionHoverCardController>(this)) {
+          std::make_unique<ToolbarActionHoverCardController>(browser->profile(),
+                                                             this)) {
   // The container shouldn't show unless / until we have extensions available.
   SetVisible(false);
 
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.cc
index 53b41e74..de52759 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.cc
@@ -6,6 +6,7 @@
 
 #include "base/containers/cxx20_erase.h"
 #include "base/path_service.h"
+#include "base/strings/stringprintf.h"
 #include "chrome/browser/extensions/chrome_test_extension_loader.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
@@ -49,10 +50,24 @@
 }
 
 scoped_refptr<const extensions::Extension>
+ExtensionsToolbarUITest::InstallExtension(const std::string& name) {
+  return InstallExtensionWithHostPermissions(name, std::string());
+}
+
+scoped_refptr<const extensions::Extension>
 ExtensionsToolbarUITest::InstallExtensionWithHostPermissions(
     const std::string& name,
     const std::string& host_permission,
     const std::string& content_script_run_location) {
+  std::string host_permissions_entry;
+  if (!host_permission.empty()) {
+    host_permissions_entry = base::StringPrintf(
+        R"(
+        "host_permissions": ["%s"],
+      )",
+        host_permission.c_str());
+  }
+
   extensions::TestExtensionDir extension_dir;
   std::string content_script_entry;
   if (!content_script_run_location.empty()) {
@@ -74,11 +89,12 @@
       R"({
             "name": "%s",
             "manifest_version": 3,
-            "version": "0.1",
             %s
-            "host_permissions": ["%s"]
+            %s
+            "version": "0.1"
           })",
-      name.c_str(), content_script_entry.c_str(), host_permission.c_str()));
+      name.c_str(), content_script_entry.c_str(),
+      host_permissions_entry.c_str()));
   scoped_refptr<const extensions::Extension> extension =
       extensions::ChromeTestExtensionLoader(profile()).LoadExtension(
           extension_dir.UnpackedPath());
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.h b/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.h
index bb7a9c2..fba08495 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.h
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.h
@@ -55,6 +55,10 @@
       const std::string& path,
       bool allow_incognito = false);
 
+  // Loads and returns a extension given a `name`.
+  scoped_refptr<const extensions::Extension> InstallExtension(
+      const std::string& name);
+
   // Loads and returns a extension given a `name`, `host_permission` and
   // optional `content_script_run_location`.
   scoped_refptr<const extensions::Extension>
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
index d7c0928b..5f0966bf 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
@@ -229,7 +229,7 @@
   }
 
   // PermissionRequestManager::Observer:
-  void OnBubbleAdded() override {
+  void OnPromptAdded() override {
     UpdateBrowserControlsStateShown(/*animate=*/true);
   }
 
diff --git a/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view.cc b/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view.cc
index 15ba7d47..507cc92 100644
--- a/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view.cc
+++ b/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view.cc
@@ -211,7 +211,7 @@
   std::move(close_callback_).Run(action_taken_);
 }
 
-void AccuracyTipBubbleView::OnBubbleAdded() {
+void AccuracyTipBubbleView::OnPromptAdded() {
   // The page requested a permission that triggered a permission prompt.
   // Accuracy tips have lower priority and have to be closed.
   action_taken_ = AccuracyTipInteraction::kPermissionRequested;
diff --git a/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view.h b/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view.h
index de0e382..f6bfa64 100644
--- a/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view.h
+++ b/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view.h
@@ -58,7 +58,7 @@
   void OnWidgetDestroying(views::Widget* widget) override;
 
   // permissions::PermissionRequestManager::Observer:
-  void OnBubbleAdded() override;
+  void OnPromptAdded() override;
 
  private:
   void OpenHelpCenter();
diff --git a/chrome/browser/ui/views/permissions/chip_controller.cc b/chrome/browser/ui/views/permissions/chip_controller.cc
index c59554e3..1599bd7 100644
--- a/chrome/browser/ui/views/permissions/chip_controller.cc
+++ b/chrome/browser/ui/views/permissions/chip_controller.cc
@@ -88,7 +88,7 @@
     ResetPermissionPromptChip();
   }
 }
-void ChipController::OnBubbleRemoved() {
+void ChipController::OnPromptRemoved() {
   bool is_tab_hidden = active_chip_permission_request_manager_.value()
                            ->GetWebContents()
                            .GetVisibility() == content::Visibility::HIDDEN;
@@ -433,7 +433,7 @@
   // displayed.
   if (permission_prompt_model_ && IsBubbleShowing()) {
     GetBubbleWidget()->AddObserver(this);
-    permission_prompt_model_->GetDelegate().value()->SetBubbleShown();
+    permission_prompt_model_->GetDelegate().value()->SetPromptShown();
   }
 }
 
diff --git a/chrome/browser/ui/views/permissions/chip_controller.h b/chrome/browser/ui/views/permissions/chip_controller.h
index f5c467b..b19632e 100644
--- a/chrome/browser/ui/views/permissions/chip_controller.h
+++ b/chrome/browser/ui/views/permissions/chip_controller.h
@@ -46,7 +46,7 @@
   // PermissionRequestManager::Observer:
   void OnPermissionRequestManagerDestructed() override;
 
-  void OnBubbleRemoved() override;
+  void OnPromptRemoved() override;
 
   // OnBubbleRemoved only triggers when a request chip (bubble) is removed, when
   // the user navigates while a confirmation chip is showing, the request is
diff --git a/chrome/browser/ui/views/permissions/permission_chip_unittest.cc b/chrome/browser/ui/views/permissions/permission_chip_unittest.cc
index b13bcdd..81b4ec7 100644
--- a/chrome/browser/ui/views/permissions/permission_chip_unittest.cc
+++ b/chrome/browser/ui/views/permissions/permission_chip_unittest.cc
@@ -80,7 +80,7 @@
     return quiet_ui_reason_;
   }
   void SetDismissOnTabClose() override {}
-  void SetBubbleShown() override {}
+  void SetPromptShown() override {}
   void SetDecisionTime() override {}
 
   base::WeakPtr<permissions::PermissionPrompt::Delegate> GetWeakPtr() override {
diff --git a/chrome/browser/ui/views/permissions/permission_prompt_bubble_view_unittest.cc b/chrome/browser/ui/views/permissions/permission_prompt_bubble_view_unittest.cc
index 705d1a8..f22aec05 100644
--- a/chrome/browser/ui/views/permissions/permission_prompt_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/permissions/permission_prompt_bubble_view_unittest.cc
@@ -63,7 +63,7 @@
     return absl::nullopt;
   }
   void SetDismissOnTabClose() override {}
-  void SetBubbleShown() override {}
+  void SetPromptShown() override {}
   void SetDecisionTime() override {}
   bool RecreateView() override { return false; }
 
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.cc
index d640ec11..0c1d438 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.cc
@@ -20,8 +20,10 @@
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/color/color_id.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/insets.h"
 #include "ui/views/accessibility/view_accessibility.h"
-#include "ui/views/layout/box_layout.h"
+#include "ui/views/border.h"
+#include "ui/views/controls/separator.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/layout/flex_layout.h"
 
@@ -43,8 +45,6 @@
 constexpr int kFootnoteVerticalMargin = 8;
 constexpr auto kTitleMargins =
     gfx::Insets::VH(kVerticalMargin, kHorizontalMargin);
-constexpr auto kFootnoteMargins =
-    gfx::Insets::VH(kFootnoteVerticalMargin, kHorizontalMargin);
 
 bool CustomShadowsSupported() {
 #if BUILDFLAG(IS_WIN)
@@ -227,51 +227,102 @@
 class ToolbarActionHoverCardBubbleView::FootnoteView : public views::View {
  public:
   FootnoteView() {
-    SetLayoutManager(std::make_unique<views::BoxLayout>(
-        views::BoxLayout::Orientation::kVertical));
+    auto* layout = SetLayoutManager(std::make_unique<views::FlexLayout>());
+    layout->SetOrientation(views::LayoutOrientation::kVertical);
+    // We only add vertical margin to the view, since horizontal margins are
+    // handled by each child.
+    layout->SetInteriorMargin(gfx::Insets::VH(kFootnoteVerticalMargin, 0));
+
     title_label_ =
         AddChildView(std::make_unique<FadeLabel>(CONTEXT_TAB_HOVER_CARD_TITLE));
     description_label_ = AddChildView(
         std::make_unique<FadeLabel>(views::style::CONTEXT_DIALOG_BODY_TEXT));
 
-    title_label_->SetBackgroundColorId(ui::kColorBubbleFooterBackground);
-    description_label_->SetBackgroundColorId(ui::kColorBubbleFooterBackground);
+    separator_ = AddChildView(std::make_unique<views::Separator>());
+    separator_->SetProperty(views::kMarginsKey,
+                            gfx::Insets::VH(kVerticalMargin, 0));
+
+    policy_label_ = AddChildView(
+        std::make_unique<FadeLabel>(views::style::CONTEXT_DIALOG_BODY_TEXT));
+    policy_label_->SetText(l10n_util::GetStringUTF16(
+        IDS_EXTENSIONS_TOOLBAR_ACTION_HOVER_CARD_FOOTER_POLICY_LABEL_TEXT));
+
+    // Separator doesn't need margin to span the dialog width.
+    auto style_label = [](FadeLabel* label) {
+      label->SetBackgroundColorId(ui::kColorBubbleFooterBackground);
+      label->SetBorder(
+          views::CreateEmptyBorder(gfx::Insets::VH(0, kHorizontalMargin)));
+    };
+    style_label(title_label_);
+    style_label(description_label_);
+    style_label(policy_label_);
   }
 
   ~FootnoteView() override = default;
 
-  void SetContent(ToolbarActionViewController::HoverCardState state,
-                  std::u16string host) {
-    DCHECK_NE(state, ToolbarActionViewController::HoverCardState::
-                         kExtensionDoesNotWantAccess);
-    title_label_->SetText(GetFootnoteTitle(state));
-    description_label_->SetText(GetFootnoteDescription(state, host));
+  void OnThemeChanged() override {
+    views::View::OnThemeChanged();
+
+    // Simulate the same look as the bubble footnote view.
+    const auto* color_provider = GetColorProvider();
+    SetBackground(views::CreateSolidBackground(
+        color_provider->GetColor(ui::kColorBubbleFooterBackground)));
+    SetBorder(views::CreateSolidSidedBorder(
+        gfx::Insets::TLBR(1, 0, 0, 0),
+        color_provider->GetColor(ui::kColorBubbleFooterBorder)));
+  }
+
+  void UpdateContent(ToolbarActionViewController::HoverCardState state,
+                     bool show_policy_label,
+                     std::u16string host) {
+    bool show_site_access_labels = state !=
+                                   ToolbarActionViewController::HoverCardState::
+                                       kExtensionDoesNotWantAccess;
+    bool footer_visible = show_site_access_labels || show_policy_label;
+    SetVisible(footer_visible);
+
+    if (!footer_visible)
+      return;
+
+    title_label_->SetVisible(show_site_access_labels);
+    description_label_->SetVisible(show_site_access_labels);
+    policy_label_->SetVisible(show_policy_label);
+    separator_->SetVisible(show_site_access_labels && show_policy_label);
+
+    if (show_site_access_labels) {
+      title_label_->SetText(GetFootnoteTitle(state));
+      description_label_->SetText(GetFootnoteDescription(state, host));
+    }
   }
 
   void SetFade(double percent) {
     title_label_->SetFade(percent);
     description_label_->SetFade(percent);
+    policy_label_->SetFade(percent);
   }
 
-  std::u16string GetTitleText() const { return title_label_->GetText(); }
-
-  std::u16string GetDescriptionText() const {
-    return description_label_->GetText();
-  }
+  bool IsTitleVisible() const { return title_label_->GetVisible(); }
+  bool IsDescriptionVisible() const { return description_label_->GetVisible(); }
+  bool IsPolicyVisible() const { return policy_label_->GetVisible(); }
+  bool IsSeparatorVisible() const { return separator_->GetVisible(); }
 
  private:
   raw_ptr<FadeLabel> title_label_;
   raw_ptr<FadeLabel> description_label_;
+  raw_ptr<FadeLabel> policy_label_;
+  raw_ptr<views::Separator> separator_;
 };
 
 // ToolbarActionHoverCardBubbleView:
 // ----------------------------------------------------------
 
 ToolbarActionHoverCardBubbleView::ToolbarActionHoverCardBubbleView(
-    ToolbarActionView* action_view)
+    ToolbarActionView* action_view,
+    Profile* profile)
     : BubbleDialogDelegateView(action_view,
                                views::BubbleBorder::TOP_LEFT,
-                               views::BubbleBorder::STANDARD_SHADOW) {
+                               views::BubbleBorder::STANDARD_SHADOW),
+      model_(ToolbarActionsModel::Get(profile)) {
   DCHECK(base::FeatureList::IsEnabled(
       extensions_features::kExtensionsMenuAccessControl));
 
@@ -304,10 +355,6 @@
   // same for multiple anchor points.
   set_highlight_button_when_shown(false);
 
-  // Set up content.
-  title_label_ =
-      AddChildView(std::make_unique<FadeLabel>(CONTEXT_TAB_HOVER_CARD_TITLE));
-
   // Set up layout.
   views::FlexLayout* const layout =
       SetLayoutManager(std::make_unique<views::FlexLayout>());
@@ -316,12 +363,16 @@
   layout->SetCrossAxisAlignment(views::LayoutAlignment::kStretch);
   layout->SetCollapseMargins(true);
 
+  // Set up content.
+  title_label_ =
+      AddChildView(std::make_unique<FadeLabel>(CONTEXT_TAB_HOVER_CARD_TITLE));
   title_label_->SetProperty(views::kMarginsKey, kTitleMargins);
   title_label_->SetProperty(
       views::kFlexBehaviorKey,
       views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum,
                                views::MaximumFlexSizeRule::kScaleToMaximum)
           .WithOrder(2));
+  footnote_view_ = AddChildView(std::make_unique<FootnoteView>());
 
   if (CustomShadowsSupported()) {
     corner_radius_ = ChromeLayoutProvider::Get()->GetCornerRadiusMetric(
@@ -339,13 +390,6 @@
   if (using_rounded_corners())
     GetBubbleFrameView()->SetCornerRadius(corner_radius_.value());
 
-  // Set up footer.
-  auto footnote_view = std::make_unique<FootnoteView>();
-  footnote_view_ = footnote_view.get();
-  footnote_view_->SetVisible(false);
-  GetBubbleFrameView()->SetFootnoteView(std::move(footnote_view));
-  GetBubbleFrameView()->SetFootnoteMargins(kFootnoteMargins);
-
   // Start in the fully "faded-in" position so that whatever text we initially
   // display is visible.
   SetTextFade(1.0);
@@ -355,21 +399,10 @@
     const ToolbarActionViewController* action_controller,
     content::WebContents* web_contents) {
   title_label_->SetText(action_controller->GetActionName());
-
-  DCHECK(GetBubbleFrameView());
-  ToolbarActionViewController::HoverCardState state =
-      action_controller->GetHoverCardState(web_contents);
-  if (state_ == state)
-    return;
-
-  state_ = state;
-  if (state_ == ToolbarActionViewController::HoverCardState::
-                    kExtensionDoesNotWantAccess) {
-    footnote_view_->SetVisible(false);
-  } else {
-    footnote_view_->SetContent(state, GetCurrentHost(web_contents));
-    footnote_view_->SetVisible(true);
-  }
+  footnote_view_->UpdateContent(
+      action_controller->GetHoverCardState(web_contents),
+      model_->IsActionForcePinned(action_controller->GetId()),
+      GetCurrentHost(web_contents));
 }
 
 void ToolbarActionHoverCardBubbleView::SetTextFade(double percent) {
@@ -382,15 +415,24 @@
   return title_label_->GetText();
 }
 
-std::u16string
-ToolbarActionHoverCardBubbleView::GetFootnoteTitleTextForTesting() const {
-  return footnote_view_->GetVisible() ? footnote_view_->GetTitleText() : u"";
+bool ToolbarActionHoverCardBubbleView::IsFooterVisible() const {
+  return footnote_view_->GetVisible();
 }
 
-std::u16string
-ToolbarActionHoverCardBubbleView::GetFootnoteDescriptionTextForTesting() const {
-  return footnote_view_->GetVisible() ? footnote_view_->GetDescriptionText()
-                                      : u"";
+bool ToolbarActionHoverCardBubbleView::IsFooterTitleLabelVisible() const {
+  return footnote_view_->IsTitleVisible();
+}
+
+bool ToolbarActionHoverCardBubbleView::IsFooterDescriptionLabelVisible() const {
+  return footnote_view_->IsDescriptionVisible();
+}
+
+bool ToolbarActionHoverCardBubbleView::IsFooterSeparatorVisible() const {
+  return footnote_view_->IsSeparatorVisible();
+}
+
+bool ToolbarActionHoverCardBubbleView::IsFooterPolicyLabelVisible() const {
+  return footnote_view_->IsPolicyVisible();
 }
 
 void ToolbarActionHoverCardBubbleView::OnThemeChanged() {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.h b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.h
index fba57c81d..320e4db 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.h
@@ -18,7 +18,8 @@
     : public views::BubbleDialogDelegateView {
  public:
   METADATA_HEADER(ToolbarActionHoverCardBubbleView);
-  explicit ToolbarActionHoverCardBubbleView(ToolbarActionView* action_view);
+  explicit ToolbarActionHoverCardBubbleView(ToolbarActionView* action_view,
+                                            Profile* profile);
   ToolbarActionHoverCardBubbleView(const ToolbarActionHoverCardBubbleView&) =
       delete;
   ToolbarActionHoverCardBubbleView& operator=(
@@ -34,8 +35,11 @@
 
   // Accessors used by tests.
   std::u16string GetTitleTextForTesting() const;
-  std::u16string GetFootnoteTitleTextForTesting() const;
-  std::u16string GetFootnoteDescriptionTextForTesting() const;
+  bool IsFooterVisible() const;
+  bool IsFooterTitleLabelVisible() const;
+  bool IsFooterDescriptionLabelVisible() const;
+  bool IsFooterSeparatorVisible() const;
+  bool IsFooterPolicyLabelVisible() const;
 
  private:
   friend class ToolbarActionHoverCardBubbleViewUITest;
@@ -48,12 +52,12 @@
   // views::BubbleDialogDelegateView:
   void OnThemeChanged() override;
 
+  // The associated ToolbarActionsModel. Not owned.
+  raw_ptr<ToolbarActionsModel> model_;
+
   raw_ptr<FadeLabel> title_label_ = nullptr;
   raw_ptr<FootnoteView> footnote_view_ = nullptr;
 
-  ToolbarActionViewController::HoverCardState state_ =
-      ToolbarActionViewController::HoverCardState::kExtensionDoesNotWantAccess;
-
   absl::optional<int> corner_radius_;
 };
 
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view_interactive_uitest.cc b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view_interactive_uitest.cc
index 57328819..4c38814 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view_interactive_uitest.cc
@@ -11,13 +11,14 @@
 #include "chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.h"
-#include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/policy/core/browser/browser_policy_connector.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/policy/core/common/policy_map.h"
+#include "components/policy/policy_constants.h"
 #include "content/public/test/browser_test.h"
 #include "extensions/common/extension_features.h"
-#include "net/base/url_util.h"
-#include "ui/base/l10n/l10n_util.h"
 #include "ui/events/types/event_type.h"
 #include "ui/gfx/animation/animation_test_api.h"
 #include "ui/views/test/widget_test.h"
@@ -78,6 +79,15 @@
         ->action_hover_card_controller_->hover_card_;
   }
 
+  void SetUpInProcessBrowserTestFixture() override {
+    ExtensionsToolbarUITest::SetUpInProcessBrowserTestFixture();
+    policy_provider_.SetDefaultReturns(
+        /*is_initialization_complete_return=*/true,
+        /*is_first_policy_load_complete_return=*/true);
+    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
+        &policy_provider_);
+  }
+
   void HoverMouseOverActionView(ToolbarActionView* action_view) {
     // We don't use ToolbarActionView::OnMouseEntered here to invoke the hover
     // card because that path is disabled in browser tests. If we enabled it,
@@ -119,6 +129,42 @@
     GetExtensionsToolbarContainer()->GetWidget()->LayoutRootViewIfNecessary();
   }
 
+  // Make `extension_id` force-pinned, as if it was controlled by the
+  // ExtensionSettings policy.
+  void ForcePinExtension(const extensions::ExtensionId& extension_id) {
+    std::string policy_item_key =
+        base::StringPrintf("%s", extension_id.c_str());
+    base::Value::Dict policy_item_value;
+    policy_item_value.Set("toolbar_pin", "force_pinned");
+
+    policy::PolicyMap policy_map =
+        policy_provider_.policies()
+            .Get(policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME,
+                                         /*component_id=*/std::string()))
+            .Clone();
+    policy::PolicyMap::Entry* const existing_entry =
+        policy_map.GetMutable(policy::key::kExtensionSettings);
+
+    if (existing_entry && existing_entry->value(base::Value::Type::DICT)) {
+      // Append to the existing policy.
+      existing_entry->value(base::Value::Type::DICT)
+          ->SetKey(policy_item_key, base::Value(std::move(policy_item_value)));
+    } else {
+      // Set the new policy value.
+      base::Value::Dict policy_value;
+      policy_value.Set(policy_item_key, std::move(policy_item_value));
+      policy_map.Set(policy::key::kExtensionSettings,
+                     policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
+                     policy::POLICY_SOURCE_CLOUD,
+                     base::Value(std::move(policy_value)),
+                     /*external_data_fetcher=*/nullptr);
+    }
+
+    policy_provider_.UpdateChromePolicy(policy_map);
+
+    GetExtensionsToolbarContainer()->GetWidget()->LayoutRootViewIfNecessary();
+  }
+
   // DialogBrowserTest:
   void ShowUi(const std::string& name) override {
     LoadExtensionAndPinIt("extensions/simple_with_popup");
@@ -135,6 +181,8 @@
  private:
   std::unique_ptr<base::AutoReset<gfx::Animation::RichAnimationRenderMode>>
       animation_mode_reset_;
+
+  testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_;
 };
 
 IN_PROC_BROWSER_TEST_F(ToolbarActionHoverCardBubbleViewUITest, InvokeUi) {
@@ -162,57 +210,102 @@
                        WidgetUpdatedWhenHoveringBetweenActionViews) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
-  // Install and pin one extension with host permissions and one without.
-  auto extensionA = LoadExtensionAndPinIt("extensions/simple_with_popup");
-  auto extensionB =
-      InstallExtensionWithHostPermissions("All Urls Extension", "<all_urls>");
-  PinExtension(extensionB->id());
-  auto action_views = GetVisibleToolbarActionViews();
-  ASSERT_EQ(action_views.size(), 2u);
+  // Add two extensions with no host permissions, and two with them.
+  auto simple_extension_A = InstallExtension("Simple extension A");
+  auto simple_extension_B = InstallExtension("Simple extension B");
+  auto extension_with_permissions_A = InstallExtensionWithHostPermissions(
+      "Extension with host permissions A", "<all_urls>");
+  auto extension_with_permissions_B = InstallExtensionWithHostPermissions(
+      "Extension with host permissions B", "<all_urls>");
 
-  // Navigate to a url extension B requests.
+  // Pin extensions "A" and force pin extensions "B" in order to test all
+  // possible footer combinations.
+  PinExtension(simple_extension_A->id());
+  ForcePinExtension(simple_extension_B->id());
+  PinExtension(extension_with_permissions_A->id());
+  ForcePinExtension(extension_with_permissions_B->id());
+
+  auto action_views = GetVisibleToolbarActionViews();
+  ASSERT_EQ(action_views.size(), 4u);
+
+  // Navigate to a url that the extensions with host permissions request.
   GURL url = embedded_test_server()->GetURL("example.com", "/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
-  // Hover over extension A and verify card anchors to its action.
-  ToolbarActionView* actionA =
-      GetExtensionsToolbarContainer()->GetViewForId(extensionA->id());
-  HoverMouseOverActionView(actionA);
+  // Hover over the simple extension pinned by the user.
+  // Verify card anchors to its action, and it contains the extension's name and
+  // no footnote.
+  ToolbarActionView* simple_action_A =
+      GetExtensionsToolbarContainer()->GetViewForId(simple_extension_A->id());
+  HoverMouseOverActionView(simple_action_A);
   views::Widget* const widget = hover_card()->GetWidget();
   views::test::WidgetVisibleWaiter(widget).Wait();
   ASSERT_TRUE(widget);
   EXPECT_TRUE(widget->IsVisible());
-  EXPECT_EQ(hover_card()->GetAnchorView(), actionA);
-  // Hover card should have the extension's name and no footnote since the
-  // extension doesn't have access.
+  EXPECT_EQ(hover_card()->GetAnchorView(), simple_action_A);
   EXPECT_EQ(hover_card()->GetTitleTextForTesting(),
-            actionA->view_controller()->GetActionName());
-  EXPECT_EQ(hover_card()->GetFootnoteTitleTextForTesting(), u"");
-  EXPECT_EQ(hover_card()->GetFootnoteDescriptionTextForTesting(), u"");
+            simple_action_A->view_controller()->GetActionName());
+  EXPECT_FALSE(hover_card()->IsFooterVisible());
 
-  // Hover over extension A and verify card anchors to its action. Note that the
-  // widget is the same because it transitions from one action view to the
-  // other.
-  ToolbarActionView* actionB =
-      GetExtensionsToolbarContainer()->GetViewForId(extensionB->id());
-  HoverMouseOverActionView(actionB);
+  // Hover over the simple extension pinned by policy.
+  // Verify card anchors to its action using the same widget, because it
+  // transitions from one action view to the other, and it contains contains the
+  // extension's name and a footnote with only policy label.
+  ToolbarActionView* simple_action_B =
+      GetExtensionsToolbarContainer()->GetViewForId(simple_extension_B->id());
+  HoverMouseOverActionView(simple_action_B);
   views::test::WidgetVisibleWaiter(widget).Wait();
   ASSERT_TRUE(widget);
   EXPECT_TRUE(widget->IsVisible());
-  EXPECT_EQ(hover_card()->GetAnchorView(), actionB);
-  // Hover card should have the extension's name and footnote since the
-  // extension has site access (by default).
+  EXPECT_EQ(hover_card()->GetAnchorView(), simple_action_B);
   EXPECT_EQ(hover_card()->GetTitleTextForTesting(),
-            actionB->view_controller()->GetActionName());
-  EXPECT_EQ(
-      hover_card()->GetFootnoteTitleTextForTesting(),
-      l10n_util::GetStringUTF16(
-          IDS_EXTENSIONS_TOOLBAR_ACTION_HOVER_CARD_FOOTER_TITLE_HAS_ACCESS));
-  EXPECT_EQ(
-      hover_card()->GetFootnoteDescriptionTextForTesting(),
-      l10n_util::GetStringFUTF16(
-          IDS_EXTENSIONS_TOOLBAR_ACTION_HOVER_CARD_FOOTER_DESCRIPTION_EXTENSION_HAS_ACESSS,
-          base::UTF8ToUTF16(net::GetHostAndPort(url))));
+            simple_action_B->view_controller()->GetActionName());
+  EXPECT_TRUE(hover_card()->IsFooterVisible());
+  EXPECT_FALSE(hover_card()->IsFooterTitleLabelVisible());
+  EXPECT_FALSE(hover_card()->IsFooterDescriptionLabelVisible());
+  EXPECT_TRUE(hover_card()->IsFooterPolicyLabelVisible());
+  EXPECT_FALSE(hover_card()->IsFooterSeparatorVisible());
+
+  // Hover over the extension with host permissions pinned by the user.
+  // Verify card anchors to its action using the same widget, and it contains
+  // contains the extension's name and a footnote with only title and
+  // description labels.
+  ToolbarActionView* action_with_permissions_A =
+      GetExtensionsToolbarContainer()->GetViewForId(
+          extension_with_permissions_A->id());
+  HoverMouseOverActionView(action_with_permissions_A);
+  views::test::WidgetVisibleWaiter(widget).Wait();
+  ASSERT_TRUE(widget);
+  EXPECT_TRUE(widget->IsVisible());
+  EXPECT_EQ(hover_card()->GetAnchorView(), action_with_permissions_A);
+  EXPECT_EQ(hover_card()->GetTitleTextForTesting(),
+            action_with_permissions_A->view_controller()->GetActionName());
+  EXPECT_TRUE(hover_card()->IsFooterVisible());
+  EXPECT_TRUE(hover_card()->IsFooterTitleLabelVisible());
+  EXPECT_TRUE(hover_card()->IsFooterDescriptionLabelVisible());
+  EXPECT_FALSE(hover_card()->IsFooterPolicyLabelVisible());
+  EXPECT_FALSE(hover_card()->IsFooterSeparatorVisible());
+
+  // Hover over the extension with host permission pinned by policy.
+  // Verify card anchors to its action using the same widget, and it contains
+  // contains the extension's name and a footnote with both title and
+  // description labels, and policy label. Since all labels are visible,
+  // separator should also be visible to distinct between them.
+  ToolbarActionView* action_with_permissions_B =
+      GetExtensionsToolbarContainer()->GetViewForId(
+          extension_with_permissions_B->id());
+  HoverMouseOverActionView(action_with_permissions_B);
+  views::test::WidgetVisibleWaiter(widget).Wait();
+  ASSERT_TRUE(widget);
+  EXPECT_TRUE(widget->IsVisible());
+  EXPECT_EQ(hover_card()->GetAnchorView(), action_with_permissions_B);
+  EXPECT_EQ(hover_card()->GetTitleTextForTesting(),
+            action_with_permissions_B->view_controller()->GetActionName());
+  EXPECT_TRUE(hover_card()->IsFooterVisible());
+  EXPECT_TRUE(hover_card()->IsFooterTitleLabelVisible());
+  EXPECT_TRUE(hover_card()->IsFooterDescriptionLabelVisible());
+  EXPECT_TRUE(hover_card()->IsFooterPolicyLabelVisible());
+  EXPECT_TRUE(hover_card()->IsFooterSeparatorVisible());
 }
 
 // Verify hover card is not visible when mouse moves inside the extensions
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.cc b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.cc
index af963b5..4930157 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.cc
@@ -10,6 +10,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/toolbar/toolbar_action_hover_card_types.h"
 #include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_action_hover_card_bubble_view.h"
@@ -70,8 +71,9 @@
 // ToolbarActionHoverCardController
 
 ToolbarActionHoverCardController::ToolbarActionHoverCardController(
+    Profile* profile,
     ExtensionsToolbarContainer* extensions_container)
-    : extensions_container_(extensions_container) {}
+    : profile_(profile), extensions_container_(extensions_container) {}
 
 ToolbarActionHoverCardController::~ToolbarActionHoverCardController() = default;
 
@@ -212,7 +214,7 @@
     ToolbarActionView* action_view) {
   DCHECK(action_view);
 
-  hover_card_ = new ToolbarActionHoverCardBubbleView(action_view);
+  hover_card_ = new ToolbarActionHoverCardBubbleView(action_view, profile_);
   hover_card_observation_.Observe(hover_card_.get());
   event_sniffer_ = std::make_unique<EventSniffer>(this);
 
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.h b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.h
index ca77c6a..18d8ef7 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.h
@@ -8,8 +8,6 @@
 #include <memory>
 
 #include "base/callback_list.h"
-#include "base/gtest_prod_util.h"
-#include "base/memory/memory_pressure_listener.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
@@ -24,11 +22,13 @@
 class ToolbarActionHoverCardBubbleView;
 class ExtensionsToolbarContainer;
 class ToolbarActionView;
+class Profile;
 
 // Controls how hover cards are shown and hidden for toolbar actions.
 class ToolbarActionHoverCardController : public views::ViewObserver {
  public:
   explicit ToolbarActionHoverCardController(
+      Profile* profile,
       ExtensionsToolbarContainer* extensions_container);
   ~ToolbarActionHoverCardController() override;
 
@@ -74,6 +74,8 @@
   void OnViewVisibilityChanged(views::View* observed_view,
                                views::View* starting_view) override;
 
+  raw_ptr<Profile> profile_;
+
   // Timestamp of the last time the hover card is hidden by the mouse leaving
   // the tab strip. This is used for reshowing the hover card without delay if
   // the mouse reenters within a given amount of time.
diff --git a/chrome/browser/ui/web_applications/diagnostics/web_app_icon_diagnostic.cc b/chrome/browser/ui/web_applications/diagnostics/web_app_icon_diagnostic.cc
index 4e60ed7b..37065447 100644
--- a/chrome/browser/ui/web_applications/diagnostics/web_app_icon_diagnostic.cc
+++ b/chrome/browser/ui/web_applications/diagnostics/web_app_icon_diagnostic.cc
@@ -5,10 +5,7 @@
 #include "chrome/browser/ui/web_applications/diagnostics/web_app_icon_diagnostic.h"
 
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/apps/app_service/app_service_proxy.h"
-#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/ui/web_applications/diagnostics/callback_utils.h"
-#include "chrome/browser/web_applications/app_service/web_app_publisher_helper.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_icon_generator.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
@@ -45,17 +42,14 @@
 
   RunChainedCallbacks(
       base::BindOnce(&WebAppIconDiagnostic::LoadIconFromProvider, GetWeakPtr()),
+
       base::BindOnce(&WebAppIconDiagnostic::DiagnoseGeneratedOrEmptyIconBitmap,
                      GetWeakPtr()),
 
       base::BindOnce(&WebAppIconDiagnostic::CheckForEmptyOrMissingIconFiles,
                      GetWeakPtr()),
-      base::BindOnce(&WebAppIconDiagnostic::DiagnoseEmptyOrMissingIconFiles,
-                     GetWeakPtr()),
 
-      base::BindOnce(&WebAppIconDiagnostic::LoadIconFromAppService,
-                     GetWeakPtr()),
-      base::BindOnce(&WebAppIconDiagnostic::DiagnoseAppServiceIcon,
+      base::BindOnce(&WebAppIconDiagnostic::DiagnoseEmptyOrMissingIconFiles,
                      GetWeakPtr()),
 
       base::BindOnce(&WebAppIconDiagnostic::CallResultCallback, GetWeakPtr()));
@@ -124,29 +118,4 @@
   std::move(done_callback).Run();
 }
 
-void WebAppIconDiagnostic::LoadIconFromAppService(
-    apps::LoadIconCallback callback) {
-  if (!icon_size_) {
-    std::move(callback).Run(nullptr);
-    return;
-  }
-
-  auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile_.get());
-  app_service_icon_loading_ =
-      proxy->LoadIcon(WebAppPublisherHelper::GetWebAppType(), app_id_,
-                      apps::IconType::kStandard, *icon_size_,
-                      /*allow_placeholder_icon=*/false, std::move(callback));
-}
-
-void WebAppIconDiagnostic::DiagnoseAppServiceIcon(
-    base::OnceClosure done_callback,
-    apps::IconValuePtr icon_value) {
-  if (!icon_value)
-    result_->has_app_service_missing_icon = true;
-  else if (icon_value->is_fallback_icon)
-    result_->has_app_service_fallback_icon = true;
-
-  std::move(done_callback).Run();
-}
-
 }  // namespace web_app
diff --git a/chrome/browser/ui/web_applications/diagnostics/web_app_icon_diagnostic.h b/chrome/browser/ui/web_applications/diagnostics/web_app_icon_diagnostic.h
index 1ca952a..fe17c42 100644
--- a/chrome/browser/ui/web_applications/diagnostics/web_app_icon_diagnostic.h
+++ b/chrome/browser/ui/web_applications/diagnostics/web_app_icon_diagnostic.h
@@ -10,7 +10,6 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
 #include "chrome/browser/web_applications/web_app_id.h"
-#include "components/services/app_service/public/cpp/icon_loader.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
@@ -31,8 +30,7 @@
     bool has_empty_icon_bitmap = false;
     bool has_empty_icon_file = false;
     bool has_missing_icon_file = false;
-    bool has_app_service_missing_icon = false;
-    bool has_app_service_fallback_icon = false;
+    // TODO(https://crbug.com/1353659): Add more checks.
   };
 
   WebAppIconDiagnostic(Profile* profile, AppId app_id);
@@ -58,10 +56,6 @@
       base::OnceClosure done_callback,
       WebAppIconManager::IconFilesCheck icon_files_check);
 
-  void LoadIconFromAppService(apps::LoadIconCallback callback);
-  void DiagnoseAppServiceIcon(base::OnceClosure done_callback,
-                              apps::IconValuePtr icon_value);
-
   const raw_ptr<Profile> profile_;
   const AppId app_id_;
 
@@ -70,8 +64,6 @@
 
   absl::optional<SquareSizePx> icon_size_;
 
-  std::unique_ptr<apps::IconLoader::Releaser> app_service_icon_loading_;
-
   absl::optional<Result> result_;
   base::OnceCallback<void(absl::optional<Result>)> result_callback_;
 
diff --git a/chrome/browser/ui/web_applications/diagnostics/web_app_icon_health_checks.cc b/chrome/browser/ui/web_applications/diagnostics/web_app_icon_health_checks.cc
index ecff195..21a9e9a 100644
--- a/chrome/browser/ui/web_applications/diagnostics/web_app_icon_health_checks.cc
+++ b/chrome/browser/ui/web_applications/diagnostics/web_app_icon_health_checks.cc
@@ -101,10 +101,6 @@
                               count(&Result::has_empty_icon_file));
   base::UmaHistogramCounts100("WebApp.Icon.AppsWithMissingIconFile",
                               count(&Result::has_missing_icon_file));
-  base::UmaHistogramCounts100("WebApp.Icon.AppsWithAppServiceMissingIcon",
-                              count(&Result::has_app_service_missing_icon));
-  base::UmaHistogramCounts100("WebApp.Icon.AppsWithAppServiceFallbackIcon",
-                              count(&Result::has_app_service_fallback_icon));
   // TODO(https://crbug.com/1353659):
   // Measure:
   // - Bitmap:
diff --git a/chrome/browser/ui/web_applications/diagnostics/web_app_icon_health_checks_browsertest.cc b/chrome/browser/ui/web_applications/diagnostics/web_app_icon_health_checks_browsertest.cc
index 5c7b9a40..fa0ea548 100644
--- a/chrome/browser/ui/web_applications/diagnostics/web_app_icon_health_checks_browsertest.cc
+++ b/chrome/browser/ui/web_applications/diagnostics/web_app_icon_health_checks_browsertest.cc
@@ -78,10 +78,6 @@
                     expected_result.has_empty_icon_file);
     check_histogram("WebApp.Icon.AppsWithMissingIconFile",
                     expected_result.has_missing_icon_file);
-    check_histogram("WebApp.Icon.AppsWithAppServiceMissingIcon",
-                    expected_result.has_app_service_missing_icon);
-    check_histogram("WebApp.Icon.AppsWithAppServiceFallbackIcon",
-                    expected_result.has_app_service_fallback_icon);
   }
 
   AppId InstallWebAppAndAwaitAppService(const char* path) {
@@ -122,9 +118,8 @@
   AppId app_id = InstallWebAppAndAwaitAppService("/web_apps/basic.html");
   CreateUpdateScope()->UpdateApp(app_id)->SetDownloadedIconSizes(
       IconPurpose::ANY, {});
-  RunIconChecksWithMetricExpectations({.has_empty_downloaded_icon_sizes = true,
-                                       .has_empty_icon_bitmap = true,
-                                       .has_app_service_missing_icon = true});
+  RunIconChecksWithMetricExpectations(
+      {.has_empty_downloaded_icon_sizes = true, .has_empty_icon_bitmap = true});
 }
 
 IN_PROC_BROWSER_TEST_F(WebAppIconHealthChecksBrowserTest, GeneratedIcon) {
@@ -160,9 +155,8 @@
   // Restart to reload the app.
 }
 IN_PROC_BROWSER_TEST_F(WebAppIconHealthChecksBrowserTest, DeletedIconFiles) {
-  RunIconChecksWithMetricExpectations({.has_empty_icon_bitmap = true,
-                                       .has_missing_icon_file = true,
-                                       .has_app_service_fallback_icon = true});
+  RunIconChecksWithMetricExpectations(
+      {.has_empty_icon_bitmap = true, .has_missing_icon_file = true});
 }
 
 IN_PROC_BROWSER_TEST_F(WebAppIconHealthChecksBrowserTest, PRE_EmptyIconFile) {
diff --git a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog.cc b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog.cc
index d50b99b..fa9c4c61 100644
--- a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog.cc
+++ b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog.cc
@@ -23,25 +23,26 @@
 
 }  // namespace
 
-// static
-ParentAccessDialog::ShowError ParentAccessDialog::Show(
+ParentAccessDialogProvider::ShowError ParentAccessDialogProvider::Show(
     parent_access_ui::mojom::ParentAccessParamsPtr params,
-    ParentAccessDialogCallback callback) {
-  ParentAccessDialog* current_instance = GetInstance();
-  if (current_instance) {
-    return ShowError::kDialogAlreadyVisible;
-  }
+    ParentAccessDialog::Callback callback) {
   Profile* profile = ProfileManager::GetPrimaryUserProfile();
   if (!profile->IsChild()) {
-    return ShowError::kNotAChildUser;
+    return ParentAccessDialogProvider::ShowError::kNotAChildUser;
   }
 
-  // Note:  |current_instance|'s memory is freed when
+  if (ParentAccessDialog::GetInstance()) {
+    return ParentAccessDialogProvider::ShowError::kDialogAlreadyVisible;
+  }
+
+  DCHECK(ParentAccessDialog::GetInstance() == nullptr);
+  // Note:  |dialog_|'s memory is freed when
   // SystemWebDialogDelegate::OnDialogClosed() is called.
-  current_instance =
+  ParentAccessDialog* dialog =
       new ParentAccessDialog(std::move(params), std::move(callback));
-  current_instance->ShowSystemDialogForBrowserContext(profile);
-  return ShowError::kNone;
+
+  dialog->ShowSystemDialogForBrowserContext(profile);
+  return ParentAccessDialogProvider::ShowError::kNone;
 }
 
 // static
@@ -83,7 +84,7 @@
 
 ParentAccessDialog::ParentAccessDialog(
     parent_access_ui::mojom::ParentAccessParamsPtr params,
-    ParentAccessDialogCallback callback)
+    ParentAccessDialog::Callback callback)
     : SystemWebDialogDelegate(GURL(chrome::kChromeUIParentAccessURL),
                               /*title=*/std::u16string()),
       parent_access_params_(std::move(params)),
diff --git a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog.h b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog.h
index d0b4af3..090f1545 100644
--- a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog.h
+++ b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog.h
@@ -19,9 +19,6 @@
 // a child session.
 class ParentAccessDialog : public SystemWebDialogDelegate {
  public:
-  // Error state returned by the Show() function.
-  enum ShowError { kNone, kDialogAlreadyVisible, kNotAChildUser };
-
   // The result of the parent access request, passed back to the caller.
   struct Result {
     // The status of the result.
@@ -37,17 +34,11 @@
     std::string parent_access_token = "";
 
     // The UTC timestamp at which the token expires.
-    base::Time parent_access_token_expire_timestamp_;
+    base::Time parent_access_token_expire_timestamp;
   };
 
   // Callback for the result of the dialog.
-  using ParentAccessDialogCallback =
-      base::OnceCallback<void(std::unique_ptr<Result>)>;
-
-  // Shows the dialog; if the dialog is already displayed, this returns an
-  // error.
-  static ShowError Show(parent_access_ui::mojom::ParentAccessParamsPtr params,
-                        ParentAccessDialogCallback callback);
+  using Callback = base::OnceCallback<void(std::unique_ptr<Result>)>;
 
   static ParentAccessDialog* GetInstance();
 
@@ -70,20 +61,48 @@
 
   parent_access_ui::mojom::ParentAccessParams* GetParentAccessParamsForTest();
 
- protected:
   explicit ParentAccessDialog(
       parent_access_ui::mojom::ParentAccessParamsPtr params,
-      ParentAccessDialogCallback callback);
+      Callback callback);
+
+ protected:
   ~ParentAccessDialog() override;
 
  private:
   parent_access_ui::mojom::ParentAccessParamsPtr parent_access_params_;
-  ParentAccessDialogCallback callback_;
+  Callback callback_;
 
   // The Parent Access result.  Set by the ParentAccessUI
   std::unique_ptr<Result> result_;
 };
 
+// Interface that provides the ParentAccessDialog. The provider
+// should be used to show the dialog.  The default implementation
+// is can be overridden by tests to provide a fake implementation like this:
+//
+// class FakeParentAccessDialogProvider
+//    : public chromeos::ParentAccessDialogProvider {
+// public:
+//  ParentAccessDialogProvider::ShowError Show(
+//      parent_access_ui::mojom::ParentAccessParamsPtr params,
+//      chromeos::ParentAccessDialog::Callback callback) override {}
+class ParentAccessDialogProvider {
+ public:
+  // Error state returned by the Show() function.
+  enum ShowError { kNone, kDialogAlreadyVisible, kNotAChildUser };
+
+  ParentAccessDialogProvider() = default;
+  ParentAccessDialogProvider(const ParentAccessDialogProvider& other) = delete;
+  ParentAccessDialogProvider& operator=(
+      const ParentAccessDialogProvider& other) = delete;
+  virtual ~ParentAccessDialogProvider() = default;
+
+  // Shows the dialog. If the dialog is already displayed, this returns an
+  // error.  virtual so it can be overridden for tests to fake dialog behavior.
+  virtual ShowError Show(parent_access_ui::mojom::ParentAccessParamsPtr params,
+                         ParentAccessDialog::Callback callback);
+};
+
 }  // namespace chromeos
 
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_PARENT_ACCESS_PARENT_ACCESS_DIALOG_H_
diff --git a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog_browsertest.cc b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog_browsertest.cc
index 952f15dd..8f5ad835 100644
--- a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog_browsertest.cc
+++ b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_dialog_browsertest.cc
@@ -39,19 +39,18 @@
   base::RunLoop run_loop;
 
   // Create the callback.
-  ParentAccessDialog::ParentAccessDialogCallback callback = base::BindOnce(
+  ParentAccessDialog::Callback callback = base::BindOnce(
       [](base::OnceClosure closure,
-         std::unique_ptr<
-             chromeos::ParentAccessDialog::ParentAccessDialog::Result> result)
-          -> void {
+         std::unique_ptr<ParentAccessDialog::Result> result) -> void {
         EXPECT_EQ(result->status,
-                  chromeos::ParentAccessDialog::Result::Status::kCancelled);
+                  ParentAccessDialog::Result::Status::kCancelled);
         std::move(closure).Run();
       },
       run_loop.QuitClosure());
 
   // Show the dialog.
-  ParentAccessDialog::ShowError error = ParentAccessDialog::Show(
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error = provider.Show(
       parent_access_ui::mojom::ParentAccessParams::New(
           parent_access_ui::mojom::ParentAccessParams::FlowType::kWebsiteAccess,
           parent_access_ui::mojom::FlowTypeParams::NewWebApprovalsParams(
@@ -59,7 +58,7 @@
       std::move(callback));
 
   // Verify it is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
   ASSERT_NE(ParentAccessDialog::GetInstance(), nullptr);
   parent_access_ui::mojom::ParentAccessParams* params =
       ParentAccessDialog::GetInstance()->GetParentAccessParamsForTest();
@@ -89,26 +88,23 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessDialogBrowserTest, SetResultAndClose) {
   base::RunLoop run_loop;
 
-  auto expected_result = std::make_unique<
-      chromeos::ParentAccessDialog::ParentAccessDialog::Result>();
-  expected_result->status =
-      chromeos::ParentAccessDialog::Result::Status::kApproved;
+  auto expected_result = std::make_unique<ParentAccessDialog::Result>();
+  expected_result->status = ParentAccessDialog::Result::Status::kApproved;
   expected_result->parent_access_token = "TEST_TOKEN";
 
   // Create the callback.
-  ParentAccessDialog::ParentAccessDialogCallback callback = base::BindOnce(
+  ParentAccessDialog::Callback callback = base::BindOnce(
       [](base::OnceClosure closure,
-         const chromeos::ParentAccessDialog::Result* expected_result,
-         std::unique_ptr<
-             chromeos::ParentAccessDialog::ParentAccessDialog::Result> result)
-          -> void {
+         const ParentAccessDialog::Result* expected_result,
+         std::unique_ptr<ParentAccessDialog::Result> result) -> void {
         EXPECT_TRUE(DialogResultsEqual(*result, *expected_result));
         std::move(closure).Run();
       },
       run_loop.QuitClosure(), expected_result.get());
 
   // Show the dialog.
-  ParentAccessDialog::Show(
+  ParentAccessDialogProvider provider;
+  provider.Show(
       parent_access_ui::mojom::ParentAccessParams::New(
           parent_access_ui::mojom::ParentAccessParams::FlowType::kWebsiteAccess,
           parent_access_ui::mojom::FlowTypeParams::NewWebApprovalsParams(
@@ -128,18 +124,17 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessDialogBrowserTest,
                        ErrorOnDialogAlreadyVisible) {
   // Show the dialog.
-  ParentAccessDialog::ShowError error = ParentAccessDialog::Show(
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error = provider.Show(
       parent_access_ui::mojom::ParentAccessParams::New(
           parent_access_ui::mojom::ParentAccessParams::FlowType::kWebsiteAccess,
           parent_access_ui::mojom::FlowTypeParams::NewWebApprovalsParams(
               parent_access_ui::mojom::WebApprovalsParams::New())),
       base::BindOnce(
-          [](std::unique_ptr<
-              chromeos::ParentAccessDialog::ParentAccessDialog::Result> result)
-              -> void {}));
+          [](std::unique_ptr<ParentAccessDialog::Result> result) -> void {}));
 
   // Verify it is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
   ASSERT_NE(ParentAccessDialog::GetInstance(), nullptr);
   parent_access_ui::mojom::ParentAccessParams* params =
       ParentAccessDialog::GetInstance()->GetParentAccessParamsForTest();
@@ -147,18 +142,17 @@
       params->flow_type,
       parent_access_ui::mojom::ParentAccessParams::FlowType::kWebsiteAccess);
 
-  error = ParentAccessDialog::Show(
+  error = provider.Show(
       parent_access_ui::mojom::ParentAccessParams::New(
           parent_access_ui::mojom::ParentAccessParams::FlowType::kWebsiteAccess,
           parent_access_ui::mojom::FlowTypeParams::NewWebApprovalsParams(
               parent_access_ui::mojom::WebApprovalsParams::New())),
       base::BindOnce(
-          [](std::unique_ptr<
-              chromeos::ParentAccessDialog::ParentAccessDialog::Result> result)
-              -> void {}));
+          [](std::unique_ptr<ParentAccessDialog::Result> result) -> void {}));
 
   // Verify an error was returned indicating it can't be shown again.
-  EXPECT_EQ(error, ParentAccessDialog::ShowError::kDialogAlreadyVisible);
+  EXPECT_EQ(error,
+            ParentAccessDialogProvider::ShowError::kDialogAlreadyVisible);
   EXPECT_NE(ParentAccessDialog::GetInstance(), nullptr);
 }
 
@@ -169,22 +163,21 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessDialogRegularUserBrowserTest,
                        ErrorForNonChildUser) {
   // Show the dialog.
-  ParentAccessDialog::ShowError error = ParentAccessDialog::Show(
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error = provider.Show(
       parent_access_ui::mojom::ParentAccessParams::New(
           parent_access_ui::mojom::ParentAccessParams::FlowType::kWebsiteAccess,
           parent_access_ui::mojom::FlowTypeParams::NewWebApprovalsParams(
               parent_access_ui::mojom::WebApprovalsParams::New())),
       base::BindOnce(
-          [](std::unique_ptr<
-              chromeos::ParentAccessDialog::ParentAccessDialog::Result> result)
-              -> void {}));
+          [](std::unique_ptr<ParentAccessDialog::Result> result) -> void {}));
 
   // Verify it is not showing.
-  EXPECT_EQ(error, ParentAccessDialog::ShowError::kNotAChildUser);
+  EXPECT_EQ(error, ParentAccessDialogProvider::ShowError::kNotAChildUser);
   EXPECT_EQ(ParentAccessDialog::GetInstance(), nullptr);
 }
 
 // TODO(b/241166361) Add test to ensure PAT is communicated back to caller via
-// the the ParentAccessDialogCallback.
+// the the ParentAccessDialog::Callback.
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_browsertest.cc b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_browsertest.cc
index 00b3266d..f1f64bc 100644
--- a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_browsertest.cc
@@ -24,7 +24,8 @@
 // Test cases for ParentAccessUI class
 IN_PROC_BROWSER_TEST_F(ParentAccessUIBrowserTest, URLParameters) {
   // Show the parent access dialog.
-  ParentAccessDialog::ShowError error = ParentAccessDialog::Show(
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error = provider.Show(
       parent_access_ui::mojom::ParentAccessParams::New(
           parent_access_ui::mojom::ParentAccessParams::FlowType::kWebsiteAccess,
           parent_access_ui::mojom::FlowTypeParams::NewWebApprovalsParams(
@@ -32,7 +33,7 @@
       base::DoNothing());
 
   // Verify dialog is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
   EXPECT_TRUE(content::WaitForLoadStop(GetContents()));
 
   GURL webview_url = GetParentAccessUI()->GetWebContentURLForTesting();
diff --git a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_handler_impl.cc b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_handler_impl.cc
index 30a2c79..38172ec6 100644
--- a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_handler_impl.cc
+++ b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_handler_impl.cc
@@ -92,7 +92,7 @@
       dialog_result->status = ParentAccessDialog::Result::Status::kApproved;
       dialog_result->parent_access_token = parent_access_token_->token();
       // Only keep the seconds, not the nanoseconds.
-      dialog_result->parent_access_token_expire_timestamp_ =
+      dialog_result->parent_access_token_expire_timestamp =
           base::Time::FromDoubleT(
               parent_access_token_->expire_time().seconds());
       break;
diff --git a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_handler_impl_browsertest.cc b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_handler_impl_browsertest.cc
index 8721d954..5edebe6 100644
--- a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_handler_impl_browsertest.cc
+++ b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui_handler_impl_browsertest.cc
@@ -39,11 +39,12 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessUIHandlerImplBrowserTest,
                        GetOAuthTokenSuccess) {
   // Show the parent access dialog.
-  ParentAccessDialog::ShowError error =
-      ParentAccessDialog::Show(GetParamsForWebApprovals(), base::DoNothing());
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error =
+      provider.Show(GetParamsForWebApprovals(), base::DoNothing());
 
   // Verify dialog is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
 
   EXPECT_TRUE(content::WaitForLoadStop(GetContents()));
 
@@ -65,11 +66,12 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessUIHandlerImplBrowserTest,
                        GetOAuthTokenError) {
   // Show the parent access dialog.
-  ParentAccessDialog::ShowError error =
-      ParentAccessDialog::Show(GetParamsForWebApprovals(), base::DoNothing());
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error =
+      provider.Show(GetParamsForWebApprovals(), base::DoNothing());
 
   // Verify dialog is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
 
   EXPECT_TRUE(content::WaitForLoadStop(GetContents()));
 
@@ -93,11 +95,12 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessUIHandlerImplBrowserTest,
                        GetOAuthTokenOnlyOneFetchAtATimeError) {
   // Show the parent access dialog.
-  ParentAccessDialog::ShowError error =
-      ParentAccessDialog::Show(GetParamsForWebApprovals(), base::DoNothing());
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error =
+      provider.Show(GetParamsForWebApprovals(), base::DoNothing());
 
   // Verify dialog is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
 
   EXPECT_TRUE(content::WaitForLoadStop(GetContents()));
 
@@ -150,7 +153,9 @@
 
   // Show the parent access dialog.
   base::RunLoop show_dialog_run_loop;
-  ParentAccessDialog::ShowError error = ParentAccessDialog::Show(
+  // Show the parent access dialog.
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error = provider.Show(
       GetParamsForWebApprovals(),
       base::BindOnce(
           [](base::OnceClosure quit_closure,
@@ -160,13 +165,13 @@
             // timestamp.
             EXPECT_EQ("TEST_TOKEN", result->parent_access_token);
             EXPECT_EQ(base::Time::FromDoubleT(123456),
-                      result->parent_access_token_expire_timestamp_);
+                      result->parent_access_token_expire_timestamp);
             std::move(quit_closure).Run();
           },
           show_dialog_run_loop.QuitClosure()));
 
   // Verify dialog is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
 
   EXPECT_TRUE(content::WaitForLoadStop(GetContents()));
 
@@ -223,7 +228,8 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessUIHandlerImplBrowserTest, OnParentDeclined) {
   // Show the parent access dialog.
   base::RunLoop show_dialog_run_loop;
-  ParentAccessDialog::ShowError error = ParentAccessDialog::Show(
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error = provider.Show(
       GetParamsForWebApprovals(),
       base::BindOnce(
           [](base::OnceClosure quit_closure,
@@ -237,7 +243,7 @@
           show_dialog_run_loop.QuitClosure()));
 
   // Verify dialog is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
 
   EXPECT_TRUE(content::WaitForLoadStop(GetContents()));
 
@@ -269,11 +275,12 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessUIHandlerImplBrowserTest,
                        ConsentDeclinedParsed) {
   // Show the parent access dialog.
-  ParentAccessDialog::ShowError error =
-      ParentAccessDialog::Show(GetParamsForWebApprovals(), base::DoNothing());
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error =
+      provider.Show(GetParamsForWebApprovals(), base::DoNothing());
 
   // Verify dialog is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
 
   EXPECT_TRUE(content::WaitForLoadStop(GetContents()));
 
@@ -309,11 +316,12 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessUIHandlerImplBrowserTest,
                        OnPageSizeChangedIgnored) {
   // Show the parent access dialog.
-  ParentAccessDialog::ShowError error =
-      ParentAccessDialog::Show(GetParamsForWebApprovals(), base::DoNothing());
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error =
+      provider.Show(GetParamsForWebApprovals(), base::DoNothing());
 
   // Verify dialog is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
 
   EXPECT_TRUE(content::WaitForLoadStop(GetContents()));
 
@@ -349,11 +357,12 @@
 IN_PROC_BROWSER_TEST_F(ParentAccessUIHandlerImplBrowserTest,
                        OnCommunicationEstablishedIgnored) {
   // Show the parent access dialog.
-  ParentAccessDialog::ShowError error =
-      ParentAccessDialog::Show(GetParamsForWebApprovals(), base::DoNothing());
+  ParentAccessDialogProvider provider;
+  ParentAccessDialogProvider::ShowError error =
+      provider.Show(GetParamsForWebApprovals(), base::DoNothing());
 
   // Verify dialog is showing.
-  ASSERT_EQ(error, ParentAccessDialog::ShowError::kNone);
+  ASSERT_EQ(error, ParentAccessDialogProvider::ShowError::kNone);
   EXPECT_TRUE(content::WaitForLoadStop(GetContents()));
 
   ParentAccessUIHandlerImpl* handler = static_cast<ParentAccessUIHandlerImpl*>(
diff --git a/chrome/browser/ui/webui/chromeos/user_image_source.cc b/chrome/browser/ui/webui/chromeos/user_image_source.cc
index 705fa24..7afcfe1 100644
--- a/chrome/browser/ui/webui/chromeos/user_image_source.cc
+++ b/chrome/browser/ui/webui/chromeos/user_image_source.cc
@@ -140,8 +140,7 @@
           !user->HasDefaultImage() || user->has_image_bytes());
 
     if (user->has_image_bytes()) {
-      if (user->image_format() == user_manager::UserImage::FORMAT_PNG ||
-          user->image_format() == user_manager::UserImage::FORMAT_WEBP) {
+      if (user->image_format() == user_manager::UserImage::FORMAT_PNG) {
         return GetUserImageFrame(user->image_bytes(), user->image_format(),
                                  frame);
       } else {
diff --git a/chrome/browser/vr/ui_host/vr_ui_host_impl.cc b/chrome/browser/vr/ui_host/vr_ui_host_impl.cc
index 3e9da25..ef4d5b3 100644
--- a/chrome/browser/vr/ui_host/vr_ui_host_impl.cc
+++ b/chrome/browser/vr/ui_host/vr_ui_host_impl.cc
@@ -217,7 +217,7 @@
       // There might already be a visible permission bubble from before
       // we registered the observer, show the HMD message now in that case.
       if (permission_request_manager->IsRequestInProgress()) {
-        OnBubbleAdded();
+        OnPromptAdded();
       }
     }
   }
@@ -291,11 +291,11 @@
   ui_rendering_thread_->SetLocationInfo(gurl);
 }
 
-void VRUiHostImpl::OnBubbleAdded() {
+void VRUiHostImpl::OnPromptAdded() {
   ShowExternalNotificationPrompt();
 }
 
-void VRUiHostImpl::OnBubbleRemoved() {
+void VRUiHostImpl::OnPromptRemoved() {
   RemoveHeadsetNotificationPrompt();
 }
 
diff --git a/chrome/browser/vr/ui_host/vr_ui_host_impl.h b/chrome/browser/vr/ui_host/vr_ui_host_impl.h
index 90494ab6..14af65c 100644
--- a/chrome/browser/vr/ui_host/vr_ui_host_impl.h
+++ b/chrome/browser/vr/ui_host/vr_ui_host_impl.h
@@ -83,8 +83,8 @@
   void StopUiRendering();
 
   // PermissionRequestManager::Observer
-  void OnBubbleAdded() override;
-  void OnBubbleRemoved() override;
+  void OnPromptAdded() override;
+  void OnPromptRemoved() override;
 
   // DesktopMediaPickerManager::DialogObserver
   // These are dialogs displayed in response to getDisplayMedia()
diff --git a/chrome/browser/vr/webxr_vr_permission_browser_test.cc b/chrome/browser/vr/webxr_vr_permission_browser_test.cc
index ce1b2f1..ea542b2d 100644
--- a/chrome/browser/vr/webxr_vr_permission_browser_test.cc
+++ b/chrome/browser/vr/webxr_vr_permission_browser_test.cc
@@ -27,7 +27,7 @@
   uint32_t ShownCount() { return shown_count_; }
 
  private:
-  void OnBubbleAdded() override { shown_count_++; }
+  void OnPromptAdded() override { shown_count_++; }
 
   uint32_t shown_count_ = 0u;
 };
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.cc
index eac82900..cf2b848 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.cc
@@ -82,8 +82,7 @@
 
 base::expected<web_package::SignedWebBundleId, std::string>
 IsolatedWebAppUrlInfo::ParseSignedWebBundleId() const {
-  auto web_bundle_id =
-      web_package::SignedWebBundleId::Create(url_.host_piece());
+  auto web_bundle_id = web_package::SignedWebBundleId::Create(origin().host());
   if (!web_bundle_id.has_value()) {
     return base::unexpected(
         base::StringPrintf("The host of isolated-app:// URLs must be a valid "
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_loader_factory_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_loader_factory_browsertest.cc
index 7dd63ba5..39837755 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_loader_factory_browsertest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_loader_factory_browsertest.cc
@@ -318,6 +318,11 @@
             "Bundle ID (got "
             "9erugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaac): The "
             "signed web bundle ID must only contain lowercase ASCII characters "
-            "and digits between 2 and 7 (without any padding).")));
+            "and digits between 2 and 7 (without any padding)."),
+        std::make_pair(
+            GURL("isolated-app://"
+                 "aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaac"),
+            "Failed to read response from Signed Web Bundle: Failed to parse "
+            "integrity block: FILE_ERROR_NOT_FOUND")));
 
 }  // namespace web_app
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
index d95b0c5..30c0e377 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -1107,13 +1107,14 @@
     priority_transport = AuthenticatorTransport::kInternal;
   }
 
-  std::vector<AuthenticatorTransport> transports_to_list_if_active;
+  std::vector<AuthenticatorTransport> transports_to_list_if_active = {
+      AuthenticatorTransport::kUsbHumanInterfaceDevice,
+  };
+
   if (!use_conditional_mediation_) {
     // Conditional requests offer platform credentials through the autofill UI.
     transports_to_list_if_active.push_back(AuthenticatorTransport::kInternal);
   }
-  transports_to_list_if_active.push_back(
-      AuthenticatorTransport::kUsbHumanInterfaceDevice);
 
   const auto kCable = AuthenticatorTransport::kHybrid;
   bool include_add_phone_option = false;
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
index 625f092..aa82edc 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
@@ -208,19 +208,19 @@
       {ga, {usb, cable}, {}, {}, {t(usb), add}, mss},
 
       // If the platform authenticator has a credential it should activate.
-      {ga, {usb, internal}, {has_plat}, {}, {t(internal), t(usb)}, plat_ui},
+      {ga, {usb, internal}, {has_plat}, {}, {t(usb), t(internal)}, plat_ui},
       // ... but with an empty allow list the user should be prompted first.
       {ga,
        {usb, internal},
        {has_plat, one_cred, empty_al},
        {},
-       {t(internal), t(usb)},
+       {t(usb), t(internal)},
        use_pk},
       {ga,
        {usb, internal},
        {has_plat, two_cred, empty_al},
        {},
-       {t(internal), t(usb)},
+       {t(usb), t(internal)},
        use_pk_multi},
 
       // MakeCredential with attachment=platform shows the 'Create a passkey'
@@ -242,7 +242,7 @@
        {usb, internal},
        {},
        {},
-       {t(internal), t(usb)},
+       {t(usb), t(internal)},
 #if BUILDFLAG(IS_MAC)
        create_pk
 #else
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index d816e01..e14e391 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1665597506-38a49e6c5f2d58a0a4894c1acd49bcb7b8d3fb60.profdata
+chrome-mac-main-1665640345-7aae5a6ef97cd0f884177c1d0893e813e0a16e91.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 0ff0e1b..26344f9 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1665608401-142598f65ff3db4c2e10fcbbda472a1687f04ae5.profdata
+chrome-win32-main-1665640345-0f7aca86f9cb934c3bb27c161f0d793e588daa1b.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 69d21ed..e51b306b 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1665619171-129809cf0c5d17cfbe48fe83724001d688021aa0.profdata
+chrome-win64-main-1665640345-096b66c76b1c76dfea76c4d7b4fb245eae406525.profdata
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index c070181d..3f763a9 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -885,8 +885,7 @@
       "58B0C2968C335964D5433E89CA4D86628A0E3D4B",  // Secure Shell App (dev)
       "3BC1ED0B3E6EFDC7BD4D3D1D75D44B52DEE0A226",  // Secure Shell Ext (stable)
       "38C361D4A0726CE45D3572D65071B6BDB3092371"   // Secure Shell Ext (dev)
-    ],
-    "disallow_for_service_workers": true
+    ]
   },
   "topSites": {
     "channel": "stable",
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index d1c1a1e2..226296c 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -19627,7 +19627,7 @@
         "policies": {},
         "prefs": {
           "ash.calendar_integration_enabled": {
-            "value": false
+            "default_value": true
         }
       }
     },
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 9bb5cba..b0eedbb 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-15167.0.0
\ No newline at end of file
+15180.0.0
\ No newline at end of file
diff --git a/chromeos/crosapi/mojom/app_service_types.mojom b/chromeos/crosapi/mojom/app_service_types.mojom
index 86790e46..4c721a25 100644
--- a/chromeos/crosapi/mojom/app_service_types.mojom
+++ b/chromeos/crosapi/mojom/app_service_types.mojom
@@ -299,8 +299,6 @@
   array<uint8>? compressed;
   // Whether this icon data is a placeholder icon.
   bool is_placeholder_icon;
-  // Whether this icon data is a fallback icon.
-  [MinVersion=1]bool is_fallback_icon;
 };
 
 // MenuItems are used to populate context menus.
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
index 04909ae..bc1b287 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
@@ -831,7 +831,6 @@
   icon_value->uncompressed = std::move(uncompressed);
   icon_value->compressed = std::move(compressed);
   icon_value->is_placeholder_icon = data.is_placeholder_icon();
-  icon_value->is_fallback_icon = data.is_fallback_icon();
   *out = std::move(icon_value);
   return true;
 }
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits.h b/chromeos/crosapi/mojom/app_service_types_mojom_traits.h
index 3ea2a8b..d8f70bc8 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits.h
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits.h
@@ -277,10 +277,6 @@
     return r->is_placeholder_icon;
   }
 
-  static bool is_fallback_icon(const apps::IconValuePtr& r) {
-    return r->is_fallback_icon;
-  }
-
   static bool Read(crosapi::mojom::IconValueDataView, apps::IconValuePtr* out);
 };
 
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom
index 40c6218..c47f9c6 100644
--- a/chromeos/crosapi/mojom/crosapi.mojom
+++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -64,6 +64,7 @@
 import "chromeos/crosapi/mojom/networking_private.mojom";
 import "chromeos/crosapi/mojom/power.mojom";
 import "chromeos/crosapi/mojom/network_settings_service.mojom";
+import "chromeos/crosapi/mojom/parent_access.mojom";
 import "chromeos/crosapi/mojom/prefs.mojom";
 import "chromeos/crosapi/mojom/printing_metrics.mojom";
 import "chromeos/crosapi/mojom/probe_service.mojom";
@@ -127,8 +128,8 @@
 // please note the milestone when you added it, to help us reason about
 // compatibility between the client applications and older ash-chrome binaries.
 //
-// Next version: 97
-// Next method id: 101
+// Next version: 98
+// Next method id: 102
 [Stable, Uuid="8b79c34f-2bf8-4499-979a-b17cac522c1e",
  RenamedFrom="crosapi.mojom.AshChromeService"]
 interface Crosapi {
@@ -427,6 +428,11 @@
   [MinVersion=39]
   BindNetworkingAttributes@44(pending_receiver<NetworkingAttributes> receiver);
 
+  // Binds the Parent Access UI to allow Lacros to request parent access
+  // from Ash when needed.
+  [MinVersion=97]
+  BindParentAccess@101(pending_receiver<ParentAccess> receiver);
+
   // Binds the Policy service to allow Lacros request policy data from Ash when
   // needed.
   [MinVersion=56] BindPolicyService@60(
diff --git a/chromeos/services/network_config/BUILD.gn b/chromeos/services/network_config/BUILD.gn
index a84eec0..4480746f 100644
--- a/chromeos/services/network_config/BUILD.gn
+++ b/chromeos/services/network_config/BUILD.gn
@@ -30,8 +30,6 @@
 }
 
 component("in_process_instance") {
-  output_name = "network_config_in_process_instance"
-
   sources = [
     "in_process_instance.cc",
     "in_process_instance.h",
diff --git a/chromeos/services/network_health/BUILD.gn b/chromeos/services/network_health/BUILD.gn
index a934c8f..82e9d254 100644
--- a/chromeos/services/network_health/BUILD.gn
+++ b/chromeos/services/network_health/BUILD.gn
@@ -15,29 +15,6 @@
     "//chromeos/services/network_config/public/cpp",
     "//chromeos/services/network_config/public/mojom",
     "//chromeos/services/network_health/public/mojom",
-    "//components/device_event_log",
-    "//mojo/public/cpp/bindings",
-  ]
-}
-
-component("in_process_instance") {
-  output_name = "network_health_in_process_instance"
-
-  sources = [
-    "in_process_instance.cc",
-    "in_process_instance.h",
-  ]
-
-  defines = [ "IS_IN_PROCESS_NETWORK_HEALTH_IMPL" ]
-
-  public_deps = [
-    "//chromeos/services/network_health/public/mojom",
-    "//mojo/public/cpp/bindings",
-  ]
-
-  deps = [
-    ":network_health",
-    "//chromeos/services/network_health/public/mojom",
     "//mojo/public/cpp/bindings",
   ]
 }
diff --git a/chromeos/services/network_health/in_process_instance.cc b/chromeos/services/network_health/in_process_instance.cc
deleted file mode 100644
index 1e69455..0000000
--- a/chromeos/services/network_health/in_process_instance.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/services/network_health/in_process_instance.h"
-
-#include "base/no_destructor.h"
-#include "chromeos/services/network_health/network_health_service.h"
-
-namespace chromeos::network_health {
-
-NetworkHealthService* GetInProcessInstance() {
-  static base::NoDestructor<NetworkHealthService> instance;
-  return instance.get();
-}
-
-}  // namespace chromeos::network_health
diff --git a/chromeos/services/network_health/in_process_instance.h b/chromeos/services/network_health/in_process_instance.h
deleted file mode 100644
index 7cfc0d3..0000000
--- a/chromeos/services/network_health/in_process_instance.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_SERVICES_NETWORK_HEALTH_IN_PROCESS_INSTANCE_H_
-#define CHROMEOS_SERVICES_NETWORK_HEALTH_IN_PROCESS_INSTANCE_H_
-
-#include "base/component_export.h"
-
-namespace chromeos::network_health {
-
-class NetworkHealthService;
-
-COMPONENT_EXPORT(IN_PROCESS_NETWORK_HEALTH)
-NetworkHealthService* GetInProcessInstance();
-
-}  // namespace chromeos::network_health
-
-#endif  // CHROMEOS_SERVICES_NETWORK_HEALTH_IN_PROCESS_INSTANCE_H_
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 3864abe8..4738d4a2 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -150,9 +150,8 @@
     const int password_symbol_vote,
     AutofillUploadContents* upload) {
   switch (password_attributes_vote.first) {
-    case PasswordAttribute::kHasLowercaseLetter:
-      upload->set_password_has_lowercase_letter(
-          password_attributes_vote.second);
+    case PasswordAttribute::kHasLetter:
+      upload->set_password_has_letter(password_attributes_vote.second);
       break;
     case PasswordAttribute::kHasSpecialSymbol:
       upload->set_password_has_special_symbol(password_attributes_vote.second);
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index fc930741..5fef59a 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -46,7 +46,7 @@
 
 // Password attributes (whether a password has special symbols, numeric, etc.)
 enum class PasswordAttribute {
-  kHasLowercaseLetter,
+  kHasLetter,
   kHasSpecialSymbol,
   kPasswordAttributesCount
 };
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 900c183..b90569f7 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -2530,7 +2530,7 @@
 
   form_structure = std::make_unique<FormStructure>(form);
   form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLowercaseLetter, true));
+      std::make_pair(PasswordAttribute::kHasLetter, true));
   form_structure->set_password_length_vote(10u);
   for (auto& fs_field : *form_structure)
     fs_field->host_form_signature = form_structure->form_signature();
@@ -2561,7 +2561,7 @@
   upload.set_autofill_used(false);
   upload.set_data_present("1442000308");
   upload.set_passwords_revealed(false);
-  upload.set_password_has_lowercase_letter(true);
+  upload.set_password_has_letter(true);
   upload.set_password_length(10u);
   upload.set_action_signature(15724779818122431245U);
   upload.set_submission_event(
@@ -2610,7 +2610,7 @@
 
   form_structure = std::make_unique<FormStructure>(form);
   form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLowercaseLetter, true));
+      std::make_pair(PasswordAttribute::kHasLetter, true));
   form_structure->set_password_length_vote(10u);
   for (auto& fs_field : *form_structure)
     fs_field->host_form_signature = form_structure->form_signature();
@@ -2709,7 +2709,7 @@
 
   form_structure = std::make_unique<FormStructure>(form);
   form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLowercaseLetter, true));
+      std::make_pair(PasswordAttribute::kHasLetter, true));
   form_structure->set_password_length_vote(10u);
   for (auto& fs_field : *form_structure)
     fs_field->host_form_signature = form_structure->form_signature();
@@ -2740,7 +2740,7 @@
   upload.set_autofill_used(false);
   upload.set_data_present("1442000308");
   upload.set_passwords_revealed(false);
-  upload.set_password_has_lowercase_letter(true);
+  upload.set_password_has_letter(true);
   upload.set_password_length(10u);
   upload.set_action_signature(15724779818122431245U);
 
@@ -2833,7 +2833,7 @@
 
   form_structure = std::make_unique<FormStructure>(form);
   form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLowercaseLetter, true));
+      std::make_pair(PasswordAttribute::kHasLetter, true));
   form_structure->set_password_length_vote(10u);
   for (auto& fs_field : *form_structure)
     fs_field->host_form_signature = form_structure->form_signature();
@@ -2864,7 +2864,7 @@
   upload.set_autofill_used(false);
   upload.set_data_present("1442000308");
   upload.set_passwords_revealed(false);
-  upload.set_password_has_lowercase_letter(true);
+  upload.set_password_has_letter(true);
   upload.set_password_length(10u);
   upload.set_action_signature(15724779818122431245U);
   upload.set_submission_event(
@@ -2952,7 +2952,7 @@
 
   form_structure = std::make_unique<FormStructure>(form);
   form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLowercaseLetter, true));
+      std::make_pair(PasswordAttribute::kHasLetter, true));
   form_structure->set_password_length_vote(10u);
   form_structure->set_submission_event(
       SubmissionIndicatorEvent::HTML_FORM_SUBMISSION);
@@ -2986,7 +2986,7 @@
   upload.set_autofill_used(false);
   upload.set_data_present("1442000308");
   upload.set_passwords_revealed(false);
-  upload.set_password_has_lowercase_letter(true);
+  upload.set_password_has_letter(true);
   upload.set_password_length(10u);
   upload.set_action_signature(15724779818122431245U);
   upload.set_has_form_tag(true);
@@ -3025,7 +3025,7 @@
 
   form_structure = std::make_unique<FormStructure>(form);
   form_structure->set_password_attributes_vote(
-      std::make_pair(PasswordAttribute::kHasLowercaseLetter, true));
+      std::make_pair(PasswordAttribute::kHasLetter, true));
   form_structure->set_password_length_vote(10u);
   form_structure->set_submission_event(
       SubmissionIndicatorEvent::HTML_FORM_SUBMISSION);
diff --git a/components/autofill/core/browser/proto/server.proto b/components/autofill/core/browser/proto/server.proto
index 8aada120..aff4c66 100644
--- a/components/autofill/core/browser/proto/server.proto
+++ b/components/autofill/core/browser/proto/server.proto
@@ -391,8 +391,8 @@
   // Upload only when a password is saved.
   // Used to adjust the password generator's settings to site's requirements.
 
-  // Whether the password has any lowercase letter.
-  optional bool password_has_lowercase_letter = 25;
+  // Whether the password has any letter.
+  optional bool password_has_letter = 25;
 
   // Deprecated since M80: Whether the password has any uppercase letter.
   optional bool password_has_uppercase_letter = 26 [deprecated = true];
diff --git a/components/autofill/core/common/save_password_progress_logger.cc b/components/autofill/core/common/save_password_progress_logger.cc
index 37d2e905..0cdd18b 100644
--- a/components/autofill/core/common/save_password_progress_logger.cc
+++ b/components/autofill/core/common/save_password_progress_logger.cc
@@ -404,8 +404,8 @@
     case STRING_LEAK_DETECTION_QUOTA_LIMIT:
       return "Leak detection failed: quota limit";
     case SavePasswordProgressLogger::
-        STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_LOWERCASE:
-      return "Uploading password requirements vote for using lowercase letters";
+        STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_LETTER:
+      return "Uploading password requirements vote for using letters";
     case SavePasswordProgressLogger::
         STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_SPECIAL_SYMBOL:
       return "Uploading password requirements vote for using special symbols";
diff --git a/components/autofill/core/common/save_password_progress_logger.h b/components/autofill/core/common/save_password_progress_logger.h
index 1684a2d..10540b4 100644
--- a/components/autofill/core/common/save_password_progress_logger.h
+++ b/components/autofill/core/common/save_password_progress_logger.h
@@ -144,7 +144,7 @@
     STRING_LEAK_DETECTION_TOKEN_REQUEST_ERROR,
     STRING_LEAK_DETECTION_NETWORK_ERROR,
     STRING_LEAK_DETECTION_QUOTA_LIMIT,
-    STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_LOWERCASE,
+    STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_LETTER,
     STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_SPECIAL_SYMBOL,
     STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_SPECIFIC_SPECIAL_SYMBOL,
     STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_PASSWORD_LENGTH,
diff --git a/components/autofill_assistant/android/BUILD.gn b/components/autofill_assistant/android/BUILD.gn
index 3ed86d0..b1073e4 100644
--- a/components/autofill_assistant/android/BUILD.gn
+++ b/components/autofill_assistant/android/BUILD.gn
@@ -128,6 +128,11 @@
     "java/src/org/chromium/components/autofill_assistant/infobox/AssistantInfoBoxCoordinator.java",
     "java/src/org/chromium/components/autofill_assistant/infobox/AssistantInfoBoxModel.java",
     "java/src/org/chromium/components/autofill_assistant/infobox/AssistantInfoBoxViewBinder.java",
+    "java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimer.java",
+    "java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerCoordinator.java",
+    "java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerDelegate.java",
+    "java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerModel.java",
+    "java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerViewBinder.java",
     "java/src/org/chromium/components/autofill_assistant/onboarding/BaseOnboardingCoordinator.java",
     "java/src/org/chromium/components/autofill_assistant/onboarding/BottomSheetOnboardingCoordinator.java",
     "java/src/org/chromium/components/autofill_assistant/onboarding/BottomSheetOnboardingWithPopupAndBubbleCoordinator.java",
@@ -311,6 +316,7 @@
     "java/src/org/chromium/components/autofill_assistant/header/AssistantHeaderModel.java",
     "java/src/org/chromium/components/autofill_assistant/infobox/AssistantInfoBox.java",
     "java/src/org/chromium/components/autofill_assistant/infobox/AssistantInfoBoxModel.java",
+    "java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerModel.java",
     "java/src/org/chromium/components/autofill_assistant/onboarding/BaseOnboardingCoordinator.java",
     "java/src/org/chromium/components/autofill_assistant/overlay/AssistantOverlayDelegate.java",
     "java/src/org/chromium/components/autofill_assistant/overlay/AssistantOverlayModel.java",
@@ -440,6 +446,7 @@
     "internal/java/res/layout/autofill_assistant_form_selection_input.xml",
     "internal/java/res/layout/autofill_assistant_header.xml",
     "internal/java/res/layout/autofill_assistant_info_box.xml",
+    "internal/java/res/layout/autofill_assistant_legal_disclaimer.xml",
     "internal/java/res/layout/autofill_assistant_loading_spinner.xml",
     "internal/java/res/layout/autofill_assistant_login.xml",
     "internal/java/res/layout/autofill_assistant_onboarding_no_button.xml",
diff --git a/components/autofill_assistant/android/internal/java/res/layout/autofill_assistant_legal_disclaimer.xml b/components/autofill_assistant/android/internal/java/res/layout/autofill_assistant_legal_disclaimer.xml
new file mode 100644
index 0000000..666a47d
--- /dev/null
+++ b/components/autofill_assistant/android/internal/java/res/layout/autofill_assistant_legal_disclaimer.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2022 The Chromium Authors.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/legal_disclaimer_view"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:visibility="gone"
+    android:layout_marginTop="@dimen/autofill_assistant_legal_disclaimer_view_vertical_padding"
+    android:paddingTop="@dimen/autofill_assistant_legal_disclaimer_view_vertical_padding"
+    android:paddingStart="@dimen/autofill_assistant_legal_disclaimer_view_left_padding"
+    android:paddingEnd="@dimen/autofill_assistant_legal_disclaimer_view_right_padding"
+    android:paddingBottom="@dimen/autofill_assistant_legal_disclaimer_view_vertical_padding">
+    <TextView
+        android:id="@+id/legal_disclaimer_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="@style/TextAppearance.AssistantBlackCaption" />
+</LinearLayout>
diff --git a/components/autofill_assistant/android/internal/java/res/values-v17/dimens.xml b/components/autofill_assistant/android/internal/java/res/values-v17/dimens.xml
index dcb8671..9e761b2 100644
--- a/components/autofill_assistant/android/internal/java/res/values-v17/dimens.xml
+++ b/components/autofill_assistant/android/internal/java/res/values-v17/dimens.xml
@@ -59,6 +59,11 @@
 
     <dimen name="autofill_assistant_root_view_top_padding">12dp</dimen>
 
+    <!-- TODO (b/253214983): Revisit the UX regarding the padding used for legal disclaimer. -->
+    <dimen name="autofill_assistant_legal_disclaimer_view_vertical_padding">12dp</dimen>
+    <dimen name="autofill_assistant_legal_disclaimer_view_left_padding">27dp</dimen>
+    <dimen name="autofill_assistant_legal_disclaimer_view_right_padding">18dp</dimen>
+
     <dimen name="autofill_assistant_loading_spinner_size">20dp</dimen>
     <dimen name="autofill_assistant_loading_spinner_padding">4dp</dimen>
 </resources>
diff --git a/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimer.java b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimer.java
new file mode 100644
index 0000000..280b55a9
--- /dev/null
+++ b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimer.java
@@ -0,0 +1,29 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.autofill_assistant.legal_disclaimer;
+
+import androidx.annotation.NonNull;
+
+public class AssistantLegalDisclaimer {
+    private final String mMessage;
+
+    private final AssistantLegalDisclaimerDelegate mDelegate;
+
+    public AssistantLegalDisclaimer(
+            @NonNull AssistantLegalDisclaimerDelegate delegate, @NonNull String message) {
+        this.mMessage = message;
+        this.mDelegate = delegate;
+    }
+
+    @NonNull
+    String getMessage() {
+        return mMessage;
+    }
+
+    @NonNull
+    AssistantLegalDisclaimerDelegate getDelegate() {
+        return mDelegate;
+    }
+}
diff --git a/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerCoordinator.java b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerCoordinator.java
new file mode 100644
index 0000000..2c24c09
--- /dev/null
+++ b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerCoordinator.java
@@ -0,0 +1,33 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.autofill_assistant.legal_disclaimer;
+
+import android.content.Context;
+import android.view.View;
+
+import org.chromium.components.autofill_assistant.LayoutUtils;
+import org.chromium.components.autofill_assistant.R;
+import org.chromium.components.autofill_assistant.legal_disclaimer.AssistantLegalDisclaimerViewBinder.ViewHolder;
+import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
+
+/** Coordinator responsible for showing the LegalDisclaimer. */
+public class AssistantLegalDisclaimerCoordinator {
+    private final View mRootView;
+    private AssistantLegalDisclaimerViewBinder mViewBinder;
+
+    public AssistantLegalDisclaimerCoordinator(
+            Context context, AssistantLegalDisclaimerModel model) {
+        mRootView = LayoutUtils.createInflater(context).inflate(
+                R.layout.autofill_assistant_legal_disclaimer, /* root= */ null);
+        ViewHolder viewHolder = new ViewHolder(mRootView);
+        mViewBinder = new AssistantLegalDisclaimerViewBinder();
+        PropertyModelChangeProcessor.create(model, viewHolder, mViewBinder);
+    }
+
+    /** Return the view containing the legal disclaimer message. */
+    public View getView() {
+        return mRootView;
+    }
+}
diff --git a/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerDelegate.java b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerDelegate.java
new file mode 100644
index 0000000..4893da2
--- /dev/null
+++ b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerDelegate.java
@@ -0,0 +1,15 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.autofill_assistant.legal_disclaimer;
+
+/**
+ * Common interface for autofill assistant legal disclaimer delegates.
+ */
+public interface AssistantLegalDisclaimerDelegate {
+    /**
+     * Called when a text link of the legal disclaimer message <link0>text</link0> is clicked.
+     */
+    void onLinkClicked(int link);
+}
diff --git a/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerModel.java b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerModel.java
new file mode 100644
index 0000000..a243389
--- /dev/null
+++ b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerModel.java
@@ -0,0 +1,39 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.autofill_assistant.legal_disclaimer;
+
+import android.text.TextUtils;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.ui.modelutil.PropertyModel;
+
+/**
+ * State for the legal_disclaimer of the Autofill Assistant.
+ */
+@JNINamespace("autofill_assistant")
+public class AssistantLegalDisclaimerModel extends PropertyModel {
+    static final WritableObjectPropertyKey<AssistantLegalDisclaimer> LEGAL_DISCLAIMER =
+            new WritableObjectPropertyKey<>();
+
+    public AssistantLegalDisclaimerModel() {
+        super(LEGAL_DISCLAIMER);
+    }
+
+    /** The delegate and message can be set as null to clear the legal_disclaimer from the view. */
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    @CalledByNative
+    public void setLegalDisclaimer(
+            @Nullable AssistantLegalDisclaimerDelegate delegate, @Nullable String message) {
+        if (delegate == null || TextUtils.isEmpty(message)) {
+            set(LEGAL_DISCLAIMER, null);
+            return;
+        }
+        set(LEGAL_DISCLAIMER, new AssistantLegalDisclaimer(delegate, message));
+    }
+}
diff --git a/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerViewBinder.java b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerViewBinder.java
new file mode 100644
index 0000000..f073842
--- /dev/null
+++ b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/legal_disclaimer/AssistantLegalDisclaimerViewBinder.java
@@ -0,0 +1,50 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.autofill_assistant.legal_disclaimer;
+
+import android.view.View;
+import android.widget.TextView;
+
+import org.chromium.components.autofill_assistant.AssistantTextUtils;
+import org.chromium.components.autofill_assistant.R;
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
+
+/**
+ * This class is responsible for pushing updates to the Autofill Assistant Legal Disclaimer Message
+ * view. These updates are pulled from the {@link AssistantLegalDisclaimerModel} when a notification
+ * of an update is received.
+ */
+class AssistantLegalDisclaimerViewBinder
+        implements PropertyModelChangeProcessor.ViewBinder<AssistantLegalDisclaimerModel,
+                AssistantLegalDisclaimerViewBinder.ViewHolder, PropertyKey> {
+    /** A wrapper class that holds the different views of the legal disclaimer. */
+    static class ViewHolder {
+        final View mRootView;
+        final TextView mMessageView;
+
+        public ViewHolder(View rootView) {
+            mRootView = rootView;
+            mMessageView = mRootView.findViewById(R.id.legal_disclaimer_text);
+        }
+    }
+
+    @Override
+    public void bind(
+            AssistantLegalDisclaimerModel model, ViewHolder view, PropertyKey propertyKey) {
+        if (AssistantLegalDisclaimerModel.LEGAL_DISCLAIMER == propertyKey) {
+            AssistantLegalDisclaimer legalDisclaimer =
+                    model.get(AssistantLegalDisclaimerModel.LEGAL_DISCLAIMER);
+            if (legalDisclaimer == null) {
+                view.mRootView.setVisibility(View.GONE);
+                return;
+            }
+            AssistantLegalDisclaimerDelegate delegate = legalDisclaimer.getDelegate();
+            AssistantTextUtils.applyVisualAppearanceTags(
+                    view.mMessageView, legalDisclaimer.getMessage(), delegate::onLinkClicked);
+            view.mRootView.setVisibility(View.VISIBLE);
+        }
+    }
+}
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/GroupedWebsitesSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/GroupedWebsitesSettings.java
index 5eb8d19..0d72530 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/GroupedWebsitesSettings.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/GroupedWebsitesSettings.java
@@ -107,9 +107,9 @@
 
         if (shouldRelatedSitesPrefBeVisible) {
             var fpsInfo = mSiteGroup.getFPSInfo();
-            relatedSitesText.setTitle(getContext().getString(R.string.allsites_fps_summary,
-                    Integer.toString(fpsInfo.getMembersCount()), fpsInfo.getOwner(),
-                    mSiteGroup.getDomainAndRegistry()));
+            relatedSitesText.setTitle(getContext().getResources().getQuantityString(
+                    R.plurals.allsites_fps_summary, fpsInfo.getMembersCount(),
+                    Integer.toString(fpsInfo.getMembersCount()), fpsInfo.getOwner()));
             relatedSitesText.setManagedPreferenceDelegate(new ForwardingManagedPreferenceDelegate(
                     getSiteSettingsDelegate().getManagedPreferenceDelegate()) {
                 @Override
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
index 18e5ebc..85fb1f7 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
@@ -838,9 +838,9 @@
 
         if (shouldRelatedSitesPrefBeVisible) {
             var fpsInfo = mSite.getFPSCookieInfo();
-            relatedSitesText.setTitle(getContext().getString(R.string.allsites_fps_summary,
-                    Integer.toString(fpsInfo.getMembersCount()), fpsInfo.getOwner(),
-                    mSite.getAddress().getDomainAndRegistry()));
+            relatedSitesText.setTitle(getContext().getResources().getQuantityString(
+                    R.plurals.allsites_fps_summary, fpsInfo.getMembersCount(),
+                    Integer.toString(fpsInfo.getMembersCount()), fpsInfo.getOwner()));
             relatedSitesText.setManagedPreferenceDelegate(new ForwardingManagedPreferenceDelegate(
                     getSiteSettingsDelegate().getManagedPreferenceDelegate()) {
                 @Override
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteGroup.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteGroup.java
index daae413c..8776a2e1 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteGroup.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteGroup.java
@@ -64,9 +64,11 @@
         long totalUsage = 0;
         for (Website website : websites) {
             totalUsage += website.getTotalUsage();
-        }
-        if (websites.size() > 0) {
-            mFPSInfo = websites.get(0).getFPSCookieInfo();
+            // If there's more than 1 website with FPS info in the group it's fine to override it
+            // since websites are grouped by eTLD+1, and FPS info are at eTLD+1 level as well.
+            if (website.getFPSCookieInfo() != null) {
+                mFPSInfo = website.getFPSCookieInfo();
+            }
         }
         mTotalUsage = totalUsage;
 
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java
index 97c61f9..3fd415b3 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java
@@ -92,9 +92,9 @@
                 && mSiteSettingsDelegate.isFirstPartySetsDataAccessEnabled()
                 && mSite.getFPSCookieInfo() != null) {
             var fpsInfo = mSite.getFPSCookieInfo();
-            setSummary(getContext().getString(R.string.allsites_fps_summary,
-                    Integer.toString(fpsInfo.getMembersCount()), fpsInfo.getOwner(),
-                    mSite.getAddress().getDomainAndRegistry()));
+            setSummary(getContext().getResources().getQuantityString(
+                    R.plurals.allsites_fps_list_summary, fpsInfo.getMembersCount(),
+                    Integer.toString(fpsInfo.getMembersCount()), fpsInfo.getOwner()));
             return;
         }
 
diff --git a/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteGroupTest.java b/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteGroupTest.java
index c0b11cb9..67aea10 100644
--- a/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteGroupTest.java
+++ b/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteGroupTest.java
@@ -118,9 +118,10 @@
         var fpsInfo = new FPSCookieInfo("google.com", 5);
         Website origin1 = new Website(WebsiteAddress.create("maps.google.com"), null);
         Website origin2 = new Website(WebsiteAddress.create("mail.google.com"), null);
+        Website origin3 = new Website(WebsiteAddress.create("docs.google.com"), null);
         origin2.setFPSCookieInfo(fpsInfo);
         WebsiteGroup group = new WebsiteGroup(origin2.getAddress().getDomainAndRegistry(),
-                new ArrayList<>(Arrays.asList(origin2, origin1)));
+                new ArrayList<>(Arrays.asList(origin1, origin2, origin3)));
 
         Assert.assertEquals(fpsInfo, group.getFPSInfo());
     }
diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd
index e139505..d69b63cd 100644
--- a/components/browser_ui/strings/android/browser_ui_strings.grd
+++ b/components/browser_ui/strings/android/browser_ui_strings.grd
@@ -559,6 +559,9 @@
       <message name="IDS_PAGE_INFO_SITE_SETTINGS_BUTTON" desc="Text in the button that opens a website's Site Settings from the Page Info dialog.">
         Site settings
       </message>
+      <message name="IDS_PAGE_INFO_COOKIES_TITLE" desc="Page info Cookies subpage title.">
+        Cookies and site data
+      </message>
       <message name="IDS_PAGE_INFO_COOKIES_CLEAR" desc="Text on the button to clear cookies for a site.">
         Clear cookies?
       </message>
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_DESCRIPTION.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_DESCRIPTION.png.sha1
index 711a924..f9a54f5 100644
--- a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_DESCRIPTION.png.sha1
+++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_DESCRIPTION.png.sha1
@@ -1 +1 @@
-0cb81b39f83707f165dbd91808566d46dbb0e2d8
\ No newline at end of file
+2c8c5217f0989a2ae609b411ac639df6ba6155ac
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_TITLE.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_TITLE.png.sha1
new file mode 100644
index 0000000..0592c36
--- /dev/null
+++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_TITLE.png.sha1
@@ -0,0 +1 @@
+52f628ff83513425ec89f72e0d5b4044f6a3b968
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/site_settings.grdp b/components/browser_ui/strings/android/site_settings.grdp
index 3a95d57..80ef03c 100644
--- a/components/browser_ui/strings/android/site_settings.grdp
+++ b/components/browser_ui/strings/android/site_settings.grdp
@@ -373,7 +373,7 @@
     Features on some sites may not work
   </message>
   <message name="IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_BLOCK_THIRD_PARTY_FPS_ADDITION" desc="Additional text used to explain the block third-party cookies option in settings when First Party Sets are enables.">
-    Related sites may remember you across sites
+    Related sites can see your activity in the group
   </message>
   <message name="IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_BLOCK_ADDITION" desc="Additional text used to explain the block cookies option in settings">
     Features on many sites may not work
@@ -388,7 +388,7 @@
    Block cookies for a specific site.
   </message>
   <message name="IDS_WEBSITE_SETTINGS_COOKIE_INFO" desc="Text describing cookie and third-party cookie settings.">
-    Cookies are files created by websites you visit. Sites use them to remember your preferences. Third-party cookies are created by other sites. These sites own some of the content, like ads or images, that you see on the webpage you visit.
+    A site you visit can embed content from other sites, for example images, ads, and text. Any of these sites can save cookies and other data to personalize your experience.
   </message>
   <message name="IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_SUBPAGE_BULLET_ONE" desc="Description for the first bullet of cookie settings subpage.">
     Sites can use cookies to improve your browsing experience, for example, to keep you signed in or to remember items in your shopping cart
@@ -403,19 +403,26 @@
     Block third-party cookies:
   </message>
   <message name="IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_TITLE" desc="First Party Sets toggle title in the cookie site settings subpage.">
-    Allow related sites to remember you across sites
+    Allow related sites to see your activity in the group
   </message>
   <message name="IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_DESCRIPTION" desc="First Party Sets toggle description in the cookie site settings subpage.">
-    Related sites use cookies to help with things like keeping you signed in
+     A company can define a group of sites that can use cookies to share your activity in the group. This is off in Incognito.
   </message>
   <message name="IDS_ALLSITES_FPS_SUMMARY" desc="First Party Sets cookie info, shown as site summary in the all sites settings page.">
-    Cookies allowed for <ph name="FPS_MEMBERS_COUNT">%1$s<ex>9</ex></ph> sites in the <ph name="FPS_OWNER">%2$s<ex>gannette.com</ex></ph> group, including <ph name="FPS_MEMBER">%3$s<ex>freep.com</ex></ph>
+    {COUNT, plural,
+      =1 {<ph name="FPS_MEMBERS_COUNT">%1$s<ex>1</ex></ph> site in <ph name="FPS_OWNER">%2$s<ex>gannette.com</ex></ph>'s group of sites that can see your activity in the group}
+      other {<ph name="FPS_MEMBERS_COUNT">%1$s<ex>1</ex></ph> sites in <ph name="FPS_OWNER">%2$s<ex>gannette.com</ex></ph>'s group of sites that can see your activity in the group}}
+  </message>
+  <message name="IDS_ALLSITES_FPS_LIST_SUMMARY" desc="First Party Sets cookie info, shown as site summary in the all sites list settings page.">
+    {COUNT, plural,
+      =1 {Cookies allowed for <ph name="FPS_MEMBERS_COUNT">%1$s<ex>1</ex></ph> <ph name="FPS_OWNER">%2$s<ex>gannette.com</ex></ph> site}
+      other {Cookies allowed for <ph name="FPS_MEMBERS_COUNT">%1$s<ex>9</ex></ph> <ph name="FPS_OWNER">%2$s<ex>gannette.com</ex></ph> sites}}
   </message>
   <message name="IDS_COOKIE_INFO_FPS_TITLE" desc="First Party Sets title in the cookies info page.">
       Related sites
    </message>
   <message name="IDS_COOKIE_INFO_FPS_SUMMARY" desc="First Party Sets summary in the cookies info page.">
-    This site is in <ph name="FPS_OWNER">%1$s<ex>google.com</ex></ph>'s group of sites that can see your activity in the group
+    This site is in a group that can see your activity. The group is defined by <ph name="FPS_OWNER">%1$s<ex>google.com</ex></ph>
   </message>
 
   <!-- Desktop Site -->
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_ALLSITES_FPS_LIST_SUMMARY.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_ALLSITES_FPS_LIST_SUMMARY.png.sha1
new file mode 100644
index 0000000..ead21b0
--- /dev/null
+++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_ALLSITES_FPS_LIST_SUMMARY.png.sha1
@@ -0,0 +1 @@
+6385f9fe1ade09e61b6c12fc45937cbc7079b5c5
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_ALLSITES_FPS_SUMMARY.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_ALLSITES_FPS_SUMMARY.png.sha1
index 67a62c8..40c47c2 100644
--- a/components/browser_ui/strings/android/site_settings_grdp/IDS_ALLSITES_FPS_SUMMARY.png.sha1
+++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_ALLSITES_FPS_SUMMARY.png.sha1
@@ -1 +1 @@
-d7dffe5f895511e1812b818780e925e8f5969d77
\ No newline at end of file
+60a4a008fe0b3d1988c2f27ec7cdeffa9f2abd2d
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_COOKIE_INFO_FPS_SUMMARY.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_COOKIE_INFO_FPS_SUMMARY.png.sha1
index 1f10b85..d752bf8 100644
--- a/components/browser_ui/strings/android/site_settings_grdp/IDS_COOKIE_INFO_FPS_SUMMARY.png.sha1
+++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_COOKIE_INFO_FPS_SUMMARY.png.sha1
@@ -1 +1 @@
-c3a40ce9584341b3f388ebcf8426a1f817d9bf6f
\ No newline at end of file
+3129bffc63136357e6f57c115cc2b81030343d18
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_BLOCK_THIRD_PARTY_FPS_ADDITION.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_BLOCK_THIRD_PARTY_FPS_ADDITION.png.sha1
index a7a598ce..22a5223 100644
--- a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_BLOCK_THIRD_PARTY_FPS_ADDITION.png.sha1
+++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_BLOCK_THIRD_PARTY_FPS_ADDITION.png.sha1
@@ -1 +1 @@
-67eb4b4ee26aa029e8cdaf90e3c68ce2fa459e24
\ No newline at end of file
+3363e73ae46f74bd76a6dd1bdc406f2a35c15cd6
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_DESCRIPTION.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_DESCRIPTION.png.sha1
index 62fc6521..b026783 100644
--- a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_DESCRIPTION.png.sha1
+++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_DESCRIPTION.png.sha1
@@ -1 +1 @@
-162d79130016d905148d34a236ceea14697b0c35
\ No newline at end of file
+ba7bcc0732dbd4fa64699409b5f713f9177d8682
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_TITLE.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_TITLE.png.sha1
index 62fc6521..35ebfb8 100644
--- a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_TITLE.png.sha1
+++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_FPS_TOGGLE_TITLE.png.sha1
@@ -1 +1 @@
-162d79130016d905148d34a236ceea14697b0c35
\ No newline at end of file
+5cb2e6d7884b3181f7319a3a68d3a799206a0b18
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_COOKIE_INFO.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_COOKIE_INFO.png.sha1
index 31487d7..546727a 100644
--- a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_COOKIE_INFO.png.sha1
+++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_COOKIE_INFO.png.sha1
@@ -1 +1 @@
-fdf156f0bd4ccb46204cafbb8f4a753174acbd79
\ No newline at end of file
+9c8a315d36f487a907cb698322687319104ad9fd
\ No newline at end of file
diff --git a/components/file_access/scoped_file_access_delegate_unittest.cc b/components/file_access/scoped_file_access_delegate_unittest.cc
index 5e0f424..84be7ac3f 100644
--- a/components/file_access/scoped_file_access_delegate_unittest.cc
+++ b/components/file_access/scoped_file_access_delegate_unittest.cc
@@ -35,6 +35,9 @@
         nullptr;
     file_access::ScopedFileAccessDelegateTestInstance::instance_counter = 0;
   }
+  void TearDown() override {
+    file_access::ScopedFileAccessDelegate::DeleteInstance();
+  }
 };
 
 TEST_F(ScopedFileAccessDelegateTest, GetEmptySingleton) {
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc
index e6d82a5..16f9333 100644
--- a/components/omnibox/browser/autocomplete_controller.cc
+++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -959,13 +959,12 @@
     // This conditional needs to match the conditional in Start that invokes
     // StartExpireTimer.
     result_.TransferOldMatches(input_, &old_matches_to_reuse);
-    if (OmniboxFieldTrial::kAutocompleteStabilityPreserveDefaultAfterTransfer
-            .Get()) {
-      result_.SortAndCull(input_, template_url_service_,
-                          preserve_default_match);
-    } else {
-      result_.SortAndCull(input_, template_url_service_);
-    }
+    static bool preserve_default_after_transfer =
+        OmniboxFieldTrial::kAutocompleteStabilityPreserveDefaultAfterTransfer
+            .Get();
+    result_.SortAndCull(
+        input_, template_url_service_,
+        preserve_default_after_transfer ? preserve_default_match : nullptr);
   }
 
 #if DCHECK_IS_ON()
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc
index 0e0b66b..7203846 100644
--- a/components/omnibox/browser/autocomplete_result.cc
+++ b/components/omnibox/browser/autocomplete_result.cc
@@ -173,7 +173,9 @@
   // particularly noticeable when the user types the next char before the
   // copied matches are expired leading to outdated matches surviving multiple
   // input changes, e.g. 'gooooooooo[oogle.com]'.
-  if (OmniboxFieldTrial::kAutocompleteStabilityDontCopyDoneProviders.Get()) {
+  static bool dont_copy_done_providers =
+      OmniboxFieldTrial::kAutocompleteStabilityDontCopyDoneProviders.Get();
+  if (dont_copy_done_providers) {
     old_matches->matches_.erase(
         base::ranges::remove_if(*old_matches,
                                 [](const auto& old_match) {
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc
index ef2fd54..f39c987 100644
--- a/components/omnibox/browser/autocomplete_result_unittest.cc
+++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -672,66 +672,63 @@
 
 // Tests that transferred matches do not include the specialized match types.
 TEST_F(AutocompleteResultTest, TransferOldMatchesSkipDoneProviders) {
-  {
-    SCOPED_TRACE("kAutocompleteStabilityDontCopyDoneProviders enabled.");
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitAndEnableFeatureWithParameters(
-        omnibox::kAutocompleteStability,
-        {{OmniboxFieldTrial::kAutocompleteStabilityDontCopyDoneProviders.name,
-          "true"}});
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeatureWithParameters(
+      omnibox::kAutocompleteStability,
+      {{OmniboxFieldTrial::kAutocompleteStabilityDontCopyDoneProviders.name,
+        "true"}});
 
-    TestData last[] = {
-        {0, 1, 500},  // Suggestion from done provider
-        {1, 2, 400},  // Suggestion for not-done provider
-    };
-    TestData current[] = {
-        {2, 3, 700},  // Suggestion from done provider
-        {3, 4, 600},  // Suggestion for not-done provider
-    };
-    TestData result[] = {
-        {2, 3, 700},
-        {3, 4, 600},
-        {1, 2, 400},
-    };
+  TestData last[] = {
+      {0, 1, 500},  // Suggestion from done provider
+      {1, 2, 400},  // Suggestion for not-done provider
+  };
+  TestData current[] = {
+      {2, 3, 700},  // Suggestion from done provider
+      {3, 4, 600},  // Suggestion for not-done provider
+  };
+  TestData result[] = {
+      {2, 3, 700},
+      {3, 4, 600},
+      {1, 2, 400},
+  };
 
-    GetProvider(1)->done_ = true;
-    GetProvider(3)->done_ = true;
+  GetProvider(1)->done_ = true;
+  GetProvider(3)->done_ = true;
 
-    ASSERT_NO_FATAL_FAILURE(RunTransferOldMatchesTest(
-        last, std::size(last), current, std::size(current), result,
-        std::size(result)));
-  }
+  ASSERT_NO_FATAL_FAILURE(RunTransferOldMatchesTest(last, std::size(last),
+                                                    current, std::size(current),
+                                                    result, std::size(result)));
+}
 
-  {
-    SCOPED_TRACE("kAutocompleteStabilityDontCopyDoneProviders disabled.");
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitAndEnableFeatureWithParameters(
-        omnibox::kAutocompleteStability,
-        {{OmniboxFieldTrial::kAutocompleteStabilityDontCopyDoneProviders.name,
-          "false"}});
+TEST_F(AutocompleteResultTest,
+       TransferOldMatchesSkipDoneProviders_DontCopyDoneProviders) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeatureWithParameters(
+      omnibox::kAutocompleteStability,
+      {{OmniboxFieldTrial::kAutocompleteStabilityDontCopyDoneProviders.name,
+        "false"}});
 
-    TestData last[] = {
-        {0, 1, 500},  // Suggestion from done provider
-        {1, 2, 400},  // Suggestion for not-done provider
-    };
-    TestData current[] = {
-        {2, 3, 700},  // Suggestion from done provider
-        {3, 4, 600},  // Suggestion for not-done provider
-    };
-    TestData result[] = {
-        {2, 3, 700},
-        {3, 4, 600},
-        {0, 1, 500},  // Suggestion from done provider
-        {1, 2, 400},
-    };
+  TestData last[] = {
+      {0, 1, 500},  // Suggestion from done provider
+      {1, 2, 400},  // Suggestion for not-done provider
+  };
+  TestData current[] = {
+      {2, 3, 700},  // Suggestion from done provider
+      {3, 4, 600},  // Suggestion for not-done provider
+  };
+  TestData result[] = {
+      {2, 3, 700},
+      {3, 4, 600},
+      {0, 1, 500},  // Suggestion from done provider
+      {1, 2, 400},
+  };
 
-    GetProvider(1)->done_ = true;
-    GetProvider(3)->done_ = true;
+  GetProvider(1)->done_ = true;
+  GetProvider(3)->done_ = true;
 
-    ASSERT_NO_FATAL_FAILURE(RunTransferOldMatchesTest(
-        last, std::size(last), current, std::size(current), result,
-        std::size(result)));
-  }
+  ASSERT_NO_FATAL_FAILURE(RunTransferOldMatchesTest(last, std::size(last),
+                                                    current, std::size(current),
+                                                    result, std::size(result)));
 }
 
 // Tests that matches with empty destination URLs aren't treated as duplicates
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc
index 9c9c73c..f27d8ba 100644
--- a/components/omnibox/common/omnibox_features.cc
+++ b/components/omnibox/common/omnibox_features.cc
@@ -87,6 +87,13 @@
              "OmniboxDemoteByType",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// Remove Excessive Clear Calls on RecycledViewPool in Omnibox.
+// The feature improves efficiency of the RecycledViewPool by removing excessive
+// calls to RecycledViewPool#clear().
+BASE_FEATURE(kOmniboxRemoveExcessiveRecycledViewClearCalls,
+             "OmniboxRemoveExcessiveRecycledViewClearCalls",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Feature to enable memoizing URLs when replacing search terms in
 // `AutocompleteMatch::GURLToStrippedGURL()`.
 BASE_FEATURE(kStrippedGurlOptimization,
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h
index 7fbf469..b60987d 100644
--- a/components/omnibox/common/omnibox_features.h
+++ b/components/omnibox/common/omnibox_features.h
@@ -23,6 +23,7 @@
 BASE_DECLARE_FEATURE(kAutocompleteStability);
 BASE_DECLARE_FEATURE(kDocumentProviderDedupingOptimization);
 BASE_DECLARE_FEATURE(kOmniboxDemoteByType);
+BASE_DECLARE_FEATURE(kOmniboxRemoveExcessiveRecycledViewClearCalls);
 BASE_DECLARE_FEATURE(kPreserveDefault);
 BASE_DECLARE_FEATURE(kStrippedGurlOptimization);
 BASE_DECLARE_FEATURE(kUpdateResultDebounce);
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java
index 9b8f6c9c..b3ab550 100644
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java
@@ -46,7 +46,7 @@
         mMainController = mainController;
         mRowView = rowView;
         mFullUrl = mainController.getURL().getSpec();
-        mTitle = mRowView.getContext().getResources().getString(R.string.cookies_title);
+        mTitle = mRowView.getContext().getResources().getString(R.string.page_info_cookies_title);
         mBridge = delegate.createCookieControlsBridge(this);
 
         PageInfoRowView.ViewParams rowParams = new PageInfoRowView.ViewParams();
diff --git a/components/password_manager/core/browser/browser_save_password_progress_logger.cc b/components/password_manager/core/browser/browser_save_password_progress_logger.cc
index e8e9274..070a247 100644
--- a/components/password_manager/core/browser/browser_save_password_progress_logger.cc
+++ b/components/password_manager/core/browser/browser_save_password_progress_logger.cc
@@ -166,9 +166,9 @@
   const bool attribute_value = std::get<1>(attribute_vote.value());
 
   switch (attribute) {
-    case PasswordAttribute::kHasLowercaseLetter:
+    case PasswordAttribute::kHasLetter:
       message += BinaryPasswordAttributeLogString(
-          STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_LOWERCASE, attribute_value);
+          STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_LETTER, attribute_value);
       break;
 
     case PasswordAttribute::kHasSpecialSymbol:
diff --git a/components/password_manager/core/browser/votes_uploader.cc b/components/password_manager/core/browser/votes_uploader.cc
index 1c8a545..e56ab8323 100644
--- a/components/password_manager/core/browser/votes_uploader.cc
+++ b/components/password_manager/core/browser/votes_uploader.cc
@@ -173,11 +173,8 @@
 bool IsNumeric(int c) {
   return '0' <= c && c <= '9';
 }
-bool IsLowercaseLetter(int c) {
-  return 'a' <= c && c <= 'z';
-}
-bool IsUppercaseLetter(int c) {
-  return 'A' <= c && c <= 'Z';
+bool IsLetter(int c) {
+  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
 }
 
 // Checks if a supplied character |c| is a special symbol.
@@ -776,23 +773,19 @@
 
   // Don't crowdsource password attributes for non-ascii passwords.
   for (const auto& e : password_value) {
-    if (!(IsUppercaseLetter(e) || IsLowercaseLetter(e) || IsNumeric(e) ||
-          IsSpecialSymbol(e))) {
+    if (!(IsLetter(e) || IsNumeric(e) || IsSpecialSymbol(e))) {
       return;
     }
   }
 
   // Select a character class attribute to upload. Upload special symbols more
   // often (8 in 9 cases) as most issues are due to missing or wrong special
-  // symbols. Don't upload info about uppercase and numeric characters as all
-  // sites that allow lowercase letters also uppercase letters, and all sites
-  // allow numeric symbols in passwords.
+  // symbols. Upload info about letters existence otherwise.
   autofill::PasswordAttribute character_class_attribute;
   bool (*predicate)(int c) = nullptr;
   if (base::RandGenerator(9) == 0) {
-    predicate = &IsLowercaseLetter;
-    character_class_attribute =
-        autofill::PasswordAttribute::kHasLowercaseLetter;
+    predicate = &IsLetter;
+    character_class_attribute = autofill::PasswordAttribute::kHasLetter;
   } else {
     predicate = &IsSpecialSymbol;
     character_class_attribute = autofill::PasswordAttribute::kHasSpecialSymbol;
diff --git a/components/permissions/permission_prompt.h b/components/permissions/permission_prompt.h
index 0efc6f5..ff3a4bb6 100644
--- a/components/permissions/permission_prompt.h
+++ b/components/permissions/permission_prompt.h
@@ -89,7 +89,7 @@
 
     // Set whether the permission prompt bubble was shown for the current
     // request.
-    virtual void SetBubbleShown() = 0;
+    virtual void SetPromptShown() = 0;
 
     // Set when the user made any decision for the currentrequest.
     virtual void SetDecisionTime() = 0;
diff --git a/components/permissions/permission_request_manager.cc b/components/permissions/permission_request_manager.cc
index 56d0bf2..b1a0395 100644
--- a/components/permissions/permission_request_manager.cc
+++ b/components/permissions/permission_request_manager.cc
@@ -77,15 +77,6 @@
 
 namespace {
 
-// When there are multiple permissions requests in
-// `pending_permission_requests_`, we try to prioritize them based on the
-// acceptance rates. Notifications and Geolocations have one of the lowest
-// acceptance, hence they have the lowest priority and will be shown the last.
-bool IsLowPriorityRequest(PermissionRequest* request) {
-  return request->request_type() == RequestType::kNotifications ||
-         request->request_type() == RequestType::kGeolocation;
-}
-
 // In case of multiple permission requests that use chip UI, a newly added
 // request will preempt the currently showing request, which is put back to the
 // queue, and will be shown later. To reduce user annoyance, if a quiet chip
@@ -274,62 +265,113 @@
         base::UserMetricsAction("PermissionBubbleIFrameRequestQueued"));
   }
 
-  CurrentRequestFate current_request_fate =
-      GetCurrentRequestFateInFaceOfNewRequest(request);
-
-  if (current_request_fate == CurrentRequestFate::Preempt) {
-    PreemptAndRequeueCurrentRequest();
-  }
-
   QueueRequest(source_frame, request);
 
-  if (current_request_fate == CurrentRequestFate::Finalize) {
-    // FinalizeCurrentRequests will call ScheduleDequeueRequest on its own.
-    FinalizeCurrentRequests(PermissionAction::IGNORED);
-  } else {
+  if (!IsRequestInProgress()) {
     ScheduleDequeueRequestIfNeeded();
+    return;
   }
+
+  ReprioritizeCurrentRequestIfNeeded();
 }
 
-PermissionRequestManager::CurrentRequestFate
-PermissionRequestManager::GetCurrentRequestFateInFaceOfNewRequest(
-    PermissionRequest* new_request) {
+bool PermissionRequestManager::ReprioritizeCurrentRequestIfNeeded() {
+  if (pending_permission_requests_.IsEmpty() || !IsRequestInProgress())
+    return true;
+
+  auto current_request_fate = CurrentRequestFate::kKeepCurrent;
+
   if (base::FeatureList::IsEnabled(features::kPermissionQuietChip)) {
     if (ShouldCurrentRequestUseQuietUI() &&
         !ShouldShowQuietRequestAgainIfPreempted(
             current_request_first_display_time_)) {
-      return CurrentRequestFate::Finalize;
-    }
-
-    if (base::FeatureList::IsEnabled(features::kPermissionChip)) {
-      // Preempt current request if it is a quiet UI request or it is not
-      // Notifications or Geolocation.
-      if (ShouldCurrentRequestUseQuietUI() ||
-          !IsLowPriorityRequest(new_request)) {
-        return CurrentRequestFate::Preempt;
-      }
-    } else {
+      current_request_fate = CurrentRequestFate::kFinalize;
+    } else if (base::FeatureList::IsEnabled(features::kPermissionChip)) {
+      // Preempt current request if it is a quiet UI request.
       if (ShouldCurrentRequestUseQuietUI()) {
-        return CurrentRequestFate::Preempt;
+        current_request_fate = CurrentRequestFate::kPreempt;
+      } else {
+        // Pop out all invalid requests in front of the queue.
+        while (!pending_permission_requests_.IsEmpty() &&
+               !ValidateRequest(pending_permission_requests_.Peek())) {
+          pending_permission_requests_.Pop();
+        }
+
+        // Here we also try to prioritise the requests. If there's a valid high
+        // priority request (high acceptance rate request) in the pending queue,
+        // preempt the current request. The valid high priority request, if
+        // there's any, is always the front of the queue.
+        if (!pending_permission_requests_.IsEmpty() &&
+            !PermissionUtil::IsLowPriorityPermissionRequest(
+                pending_permission_requests_.Peek())) {
+          current_request_fate = CurrentRequestFate::kPreempt;
+        }
       }
+    } else if (ShouldCurrentRequestUseQuietUI()) {
+      current_request_fate = CurrentRequestFate::kPreempt;
     }
   } else {
     if (base::FeatureList::IsEnabled(features::kPermissionChip)) {
-      return CurrentRequestFate::Preempt;
+      current_request_fate = CurrentRequestFate::kPreempt;
     } else if (ShouldCurrentRequestUseQuietUI()) {
       // If we're displaying a quiet permission request, ignore it in favor of a
       // new permission request.
-      return CurrentRequestFate::Finalize;
+      current_request_fate = CurrentRequestFate::kFinalize;
     }
   }
 
-  return CurrentRequestFate::KeepCurrent;
+  switch (current_request_fate) {
+    case CurrentRequestFate::kKeepCurrent:
+      return true;
+    case CurrentRequestFate::kPreempt: {
+      DCHECK(!pending_permission_requests_.IsEmpty());
+      auto* next_candidate = pending_permission_requests_.Peek();
+
+      // Consider a case of infinite loop here (eg: 2 low priority requests can
+      // preempt each other, causing a loop). We only preempt the current
+      // request if the next candidate has just been added to pending queue but
+      // not validated yet.
+      if (validated_requests_set_.find(next_candidate) !=
+          validated_requests_set_.end()) {
+        return true;
+      }
+
+      pending_permission_requests_.Pop();
+      PreemptAndRequeueCurrentRequest();
+      pending_permission_requests_.Push(next_candidate);
+      ScheduleDequeueRequestIfNeeded();
+      return false;
+    }
+    case CurrentRequestFate::kFinalize:
+      // FinalizeCurrentRequests will call ScheduleDequeueRequestIfNeeded on its
+      // own.
+      FinalizeCurrentRequests(PermissionAction::IGNORED);
+      return false;
+  }
+
+  return true;
+}
+
+bool PermissionRequestManager::ValidateRequest(PermissionRequest* request) {
+  const auto iter = request_sources_map_.find(request);
+  if (iter == request_sources_map_.end())
+    return false;
+
+  if (!iter->second.IsSourceFrameInactiveAndDisallowActivation())
+    return true;
+
+  request->Cancelled();
+  request->RequestFinished();
+  validated_requests_set_.erase(request);
+  request_sources_map_.erase(request);
+  return false;
 }
 
 void PermissionRequestManager::QueueRequest(
     content::RenderFrameHost* source_frame,
     PermissionRequest* request) {
-  pending_permission_requests_.Push(request);
+  pending_permission_requests_.Push(request,
+                                    true /*reorder_based_on_priority*/);
   request_sources_map_.emplace(
       request, PermissionRequestSource({source_frame->GetProcess()->GetID(),
                                         source_frame->GetRoutingID()}));
@@ -437,7 +479,7 @@
       switch (view_->GetTabSwitchingBehavior()) {
         case PermissionPrompt::TabSwitchingBehavior::
             kDestroyPromptButKeepRequestPending:
-          DeleteBubble();
+          DeletePrompt();
           break;
         case PermissionPrompt::TabSwitchingBehavior::
             kDestroyPromptAndIgnoreRequest:
@@ -464,7 +506,7 @@
     DCHECK_EQ(view_->GetTabSwitchingBehavior(),
               PermissionPrompt::TabSwitchingBehavior::kKeepPromptAlive);
   } else if (current_request_ui_to_use_.has_value()) {
-    ShowBubble();
+    ShowPrompt();
   }
 }
 
@@ -580,8 +622,8 @@
   should_dismiss_current_request_ = true;
 }
 
-void PermissionRequestManager::SetBubbleShown() {
-  did_show_bubble_ = true;
+void PermissionRequestManager::SetPromptShown() {
+  did_show_prompt_ = true;
 }
 
 void PermissionRequestManager::SetDecisionTime() {
@@ -627,12 +669,6 @@
           PermissionsClient::Get()->CreatePermissionUiSelectors(
               web_contents->GetBrowserContext())) {}
 
-void PermissionRequestManager::ScheduleShowBubble() {
-  content::GetUIThreadTaskRunner({})->PostTask(
-      FROM_HERE, base::BindOnce(&PermissionRequestManager::ShowBubble,
-                                weak_factory_.GetWeakPtr()));
-}
-
 void PermissionRequestManager::DequeueRequestIfNeeded() {
   // TODO(olesiamarukhno): Media requests block other media requests from
   // pre-empting them. For example, when a camera request is pending and mic
@@ -648,15 +684,12 @@
 
   // Find first valid request.
   while (!pending_permission_requests_.IsEmpty()) {
-    PermissionRequest* next = pending_permission_requests_.Pop();
-    PermissionRequestSource& source = request_sources_map_.find(next)->second;
-    if (!source.IsSourceFrameInactiveAndDisallowActivation()) {
+    auto* next = pending_permission_requests_.Pop();
+    if (ValidateRequest(next)) {
+      validated_requests_set_.insert(next);
       requests_.push_back(next);
       break;
     }
-    next->Cancelled();
-    next->RequestFinished();
-    request_sources_map_.erase(request_sources_map_.find(next));
   }
 
   if (requests_.empty()) {
@@ -666,17 +699,23 @@
   // Find additional requests that can be grouped with the first one.
   for (; !pending_permission_requests_.IsEmpty();
        pending_permission_requests_.Pop()) {
-    PermissionRequest* front = pending_permission_requests_.Peek();
-    PermissionRequestSource& source = request_sources_map_.find(front)->second;
-    if (source.IsSourceFrameInactiveAndDisallowActivation()) {
-      front->Cancelled();
-      front->RequestFinished();
-      request_sources_map_.erase(request_sources_map_.find(front));
-    } else if (ShouldGroupRequests(requests_.front(), front)) {
-      requests_.push_back(front);
-    } else {
+    auto* front = pending_permission_requests_.Peek();
+    if (!ValidateRequest(front))
+      continue;
+
+    validated_requests_set_.insert(front);
+    if (!ShouldGroupRequests(requests_.front(), front))
       break;
-    }
+
+    requests_.push_back(front);
+  }
+
+  // Mark the remaining pending requests as validated, so only the "new and has
+  // not been validated" requests added to the queue could have effect to
+  // priority order
+  for (auto* request : pending_permission_requests_) {
+    if (ValidateRequest(request))
+      validated_requests_set_.insert(request);
   }
 
   if (!permission_ui_selectors_.empty()) {
@@ -704,7 +743,7 @@
   } else {
     current_request_ui_to_use_ =
         UiDecision(UiDecision::UseNormalUi(), UiDecision::ShowNoWarning());
-    ScheduleShowBubble();
+    ShowPrompt();
   }
 }
 
@@ -715,7 +754,7 @@
                      weak_factory_.GetWeakPtr()));
 }
 
-void PermissionRequestManager::ShowBubble() {
+void PermissionRequestManager::ShowPrompt() {
   // There is a race condition where the request might have been removed
   // already so double-checking that there is a request in progress.
   //
@@ -729,6 +768,9 @@
   if (tab_is_hidden_)
     return;
 
+  if (!ReprioritizeCurrentRequestIfNeeded())
+    return;
+
   if (!RecreateView())
     return;
 
@@ -760,19 +802,19 @@
   }
   current_request_already_displayed_ = true;
   current_request_first_display_time_ = base::Time::Now();
-  NotifyBubbleAdded();
+  NotifyPromptAdded();
   // If in testing mode, automatically respond to the bubble that was shown.
   if (auto_response_for_test_ != NONE)
     DoAutoResponseForTesting();
 }
 
-void PermissionRequestManager::DeleteBubble() {
+void PermissionRequestManager::DeletePrompt() {
   DCHECK(view_);
   {
     base::AutoReset<bool> deleting(&ignore_callbacks_from_prompt_, true);
     view_.reset();
   }
-  NotifyBubbleRemoved();
+  NotifyPromptRemoved();
 }
 
 void PermissionRequestManager::ResetViewStateForCurrentRequest() {
@@ -788,12 +830,12 @@
   was_decision_held_back_.reset();
   selector_decisions_.clear();
   should_dismiss_current_request_ = false;
-  did_show_bubble_ = false;
+  did_show_prompt_ = false;
   did_click_manage_ = false;
   did_click_learn_more_ = false;
 
   if (view_)
-    DeleteBubble();
+    DeletePrompt();
 }
 
 void PermissionRequestManager::FinalizeCurrentRequests(
@@ -818,7 +860,7 @@
       requests_, web_contents(), permission_action, time_to_decision,
       DetermineCurrentRequestUIDisposition(),
       DetermineCurrentRequestUIDispositionReasonForUMA(),
-      prediction_grant_likelihood_, was_decision_held_back_, did_show_bubble_,
+      prediction_grant_likelihood_, was_decision_held_back_, did_show_prompt_,
       did_click_manage_, did_click_learn_more_);
 
   content::BrowserContext* browser_context =
@@ -866,7 +908,8 @@
   for (requests_iter = requests_.begin(); requests_iter != requests_.end();
        requests_iter++) {
     RequestFinishedIncludingDuplicates(*requests_iter);
-    request_sources_map_.erase(request_sources_map_.find(*requests_iter));
+    validated_requests_set_.erase(*requests_iter);
+    request_sources_map_.erase(*requests_iter);
   }
   requests_.clear();
 
@@ -882,7 +925,8 @@
     auto* pending_request = pending_permission_requests_.Peek();
     CancelledIncludingDuplicates(pending_request);
     RequestFinishedIncludingDuplicates(pending_request);
-    request_sources_map_.erase(request_sources_map_.find(pending_request));
+    validated_requests_set_.erase(pending_request);
+    request_sources_map_.erase(pending_request);
   }
 
   if (IsRequestInProgress()) {
@@ -900,7 +944,7 @@
 }
 
 PermissionRequest* PermissionRequestManager::GetExistingRequest(
-    PermissionRequest* request) {
+    PermissionRequest* request) const {
   for (PermissionRequest* existing_request : requests_) {
     if (request->IsDuplicateOf(existing_request))
       return existing_request;
@@ -1004,14 +1048,14 @@
   return false;
 }
 
-void PermissionRequestManager::NotifyBubbleAdded() {
+void PermissionRequestManager::NotifyPromptAdded() {
   for (Observer& observer : observer_list_)
-    observer.OnBubbleAdded();
+    observer.OnPromptAdded();
 }
 
-void PermissionRequestManager::NotifyBubbleRemoved() {
+void PermissionRequestManager::NotifyPromptRemoved() {
   for (Observer& observer : observer_list_)
-    observer.OnBubbleRemoved();
+    observer.OnPromptRemoved();
 }
 
 void PermissionRequestManager::NotifyRequestDecided(
@@ -1075,7 +1119,7 @@
   }
 
   if (current_request_ui_to_use_.has_value()) {
-    ScheduleShowBubble();
+    ShowPrompt();
   }
 }
 
diff --git a/components/permissions/permission_request_manager.h b/components/permissions/permission_request_manager.h
index dc7910e..bc4973d9 100644
--- a/components/permissions/permission_request_manager.h
+++ b/components/permissions/permission_request_manager.h
@@ -71,14 +71,14 @@
  public:
   class Observer {
    public:
-    virtual void OnBubbleAdded() {}
-    virtual void OnBubbleRemoved() {}
+    virtual void OnPromptAdded() {}
+    virtual void OnPromptRemoved() {}
     // Called when the current batch of requests have been handled and the
-    // bubble is no longer visible. Note that there might be some queued
+    // prompt is no longer visible. Note that there might be some queued
     // permission requests that will get shown after this. This differs from
-    // OnBubbleRemoved() in that the bubble may disappear while there are still
-    // in-flight requests (e.g. when switching tabs while the bubble is still
-    // visible).
+    // OnPromptRemoved() in that the prompt may disappear while there are
+    // still in-flight requests (e.g. when switching tabs while the prompt is
+    // still visible).
     virtual void OnRequestsFinalized() {}
 
     virtual void OnPermissionRequestManagerDestructed() {}
@@ -150,7 +150,7 @@
   absl::optional<PermissionUiSelector::QuietUiReason> ReasonForUsingQuietUi()
       const override;
   void SetDismissOnTabClose() override;
-  void SetBubbleShown() override;
+  void SetPromptShown() override;
   void SetDecisionTime() override;
   void SetManageClicked() override;
   void SetLearnMoreClicked() override;
@@ -190,19 +190,19 @@
     view_factory_ = std::move(view_factory);
   }
 
-  PermissionPrompt* view_for_testing() { return view_.get(); }
+  PermissionPrompt* view_for_testing() const { return view_.get(); }
 
   void set_current_request_first_display_time_for_testing(base::Time time) {
     current_request_first_display_time_ = time;
   }
 
   absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
-  prediction_grant_likelihood_for_testing() {
+  prediction_grant_likelihood_for_testing() const {
     return prediction_grant_likelihood_;
   }
 
   absl::optional<permissions::PermissionPromptDisposition>
-  current_request_prompt_disposition_for_testing() {
+  current_request_prompt_disposition_for_testing() const {
     return current_request_prompt_disposition_;
   }
 
@@ -229,12 +229,33 @@
 
   explicit PermissionRequestManager(content::WebContents* web_contents);
 
-  enum class CurrentRequestFate { KeepCurrent, Preempt, Finalize };
+  // Defines how to handle the current request, when new requests arrive
+  enum class CurrentRequestFate {
+    // Keep showing the current request. The incoming requests should not take
+    // priority over the current request and will be pushed to pending requests
+    // queue.
+    kKeepCurrent,
 
-  // Returns `CurrentRequestFate` based on what type of UI has been shown for
-  // `requests_`.
-  CurrentRequestFate GetCurrentRequestFateInFaceOfNewRequest(
-      PermissionRequest* request);
+    // Put the current request back to the pending requests queue for displaying
+    // later when it returns to the front of the queue.
+    kPreempt,
+
+    // Finalize/ignore the current request and show the new request.
+    kFinalize
+  };
+
+  // Reprioritize the current requests (preempting, finalizing) based on what
+  // type of UI has been shown for `requests_` and current pending requests
+  // queue.
+  // Determine the next request candidate would be prompted later and push the
+  // candidate to front of the pending queue.
+  // Return true if we keep showing the current request, otherwise return false
+  bool ReprioritizeCurrentRequestIfNeeded();
+
+  // Validate the input request. If the request is invalid, cancel and remove it
+  // from *_map_ and *_set_.
+  // Return true if the request is valid, otherwise false.
+  bool ValidateRequest(PermissionRequest* request);
 
   // Adds `request` into `pending_permission_requests_`, and request's
   // `source_frame` into `request_sources_map_`.
@@ -246,26 +267,20 @@
   // process them after the new requests.
   void PreemptAndRequeueCurrentRequest();
 
-  // Posts a task which will allow the bubble to become visible.
-  void ScheduleShowBubble();
-
-  // If a request isn't already in progress, deque and schedule showing the
-  // request.
+  // If a request isn't already in progress, dequeue and show the request
+  // prompt.
   void DequeueRequestIfNeeded();
 
-  // Schedule a call to dequeue request. Is needed to ensure requests that can
-  // be grouped together have time to all be added to the queue.
+  // Schedule a call to |DequeueRequestIfNeeded|. Is needed to ensure requests
+  // that can be grouped together have time to all be added to the queue.
   void ScheduleDequeueRequestIfNeeded();
 
-  // Will determine if it's possible and necessary to dequeue a new request.
-  bool ShouldDequeueNewRequest();
-
-  // Shows the bubble for a request that has just been dequeued, or re-show a
-  // bubble after switching tabs away and back.
-  void ShowBubble();
+  // Shows the prompt for a request that has just been dequeued, or re-show a
+  // prompt after switching tabs away and back.
+  void ShowPrompt();
 
   // Delete the view object
-  void DeleteBubble();
+  void DeletePrompt();
 
   // Finalize request.
   void ResetViewStateForCurrentRequest();
@@ -283,7 +298,7 @@
   // |duplicate_requests_| - for a request matching |request|, and returns the
   // matching request, or |nullptr| if no match. Note that the matching request
   // may or may not be the same object as |request|.
-  PermissionRequest* GetExistingRequest(PermissionRequest* request);
+  PermissionRequest* GetExistingRequest(PermissionRequest* request) const;
 
   // Calls PermissionGranted on a request and all its duplicates.
   void PermissionGrantedIncludingDuplicates(PermissionRequest* request,
@@ -295,8 +310,8 @@
   // Calls RequestFinished on a request and all its duplicates.
   void RequestFinishedIncludingDuplicates(PermissionRequest* request);
 
-  void NotifyBubbleAdded();
-  void NotifyBubbleRemoved();
+  void NotifyPromptAdded();
+  void NotifyPromptRemoved();
   void NotifyRequestDecided(permissions::PermissionAction permission_action);
 
   void OnPermissionUiSelectorDone(size_t selector_index,
@@ -352,6 +367,12 @@
   // Note that no date is stored for |duplicate_requests_|.
   std::map<PermissionRequest*, PermissionRequestSource> request_sources_map_;
 
+  // Sequence of requests from pending queue will be marked as validated, when
+  // we are extracting a group of requests from the queue to show to user. This
+  // is an immature solution to avoid an infinitive loop of preempting, we would
+  // not prempt a request if the incoming request is already validated.
+  std::set<PermissionRequest*> validated_requests_set_;
+
   base::ObserverList<Observer>::Unchecked observer_list_;
   AutoResponseType auto_response_for_test_;
 
@@ -405,8 +426,8 @@
   // closed.
   bool should_dismiss_current_request_ = false;
 
-  // Whether the permission prompt bubble was shown for the current request.
-  bool did_show_bubble_ = false;
+  // Whether the permission prompt was shown for the current request.
+  bool did_show_prompt_ = false;
 
   // When the user made any decision for the current |requests_|, or zero if not
   // at all.
diff --git a/components/permissions/permission_request_manager_unittest.cc b/components/permissions/permission_request_manager_unittest.cc
index 7dca658b..193b528 100644
--- a/components/permissions/permission_request_manager_unittest.cc
+++ b/components/permissions/permission_request_manager_unittest.cc
@@ -38,7 +38,9 @@
       public ::testing::WithParamInterface<bool> {
  public:
   PermissionRequestManagerTest()
-      : request1_(RequestType::kGeolocation,
+      : RenderViewHostTestHarness(
+            base::test::TaskEnvironment::TimeSource::MOCK_TIME),
+        request1_(RequestType::kGeolocation,
                   PermissionRequestGestureType::GESTURE),
         request2_(RequestType::kMultipleDownloads,
                   PermissionRequestGestureType::NO_GESTURE),
@@ -88,28 +90,28 @@
 
   void Accept() {
     manager_->Accept();
-    base::RunLoop().RunUntilIdle();
+    task_environment()->RunUntilIdle();
   }
 
   void Deny() {
     manager_->Deny();
-    base::RunLoop().RunUntilIdle();
+    task_environment()->RunUntilIdle();
   }
 
   void Closing() {
     manager_->Dismiss();
-    base::RunLoop().RunUntilIdle();
+    task_environment()->RunUntilIdle();
   }
 
   void WaitForFrameLoad() {
     // PermissionRequestManager ignores all parameters. Yay?
     manager_->DOMContentLoaded(nullptr);
-    base::RunLoop().RunUntilIdle();
+    task_environment()->RunUntilIdle();
   }
 
   void WaitForBubbleToBeShown() {
     manager_->DocumentOnLoadCompletedInPrimaryMainFrame();
-    base::RunLoop().RunUntilIdle();
+    task_environment()->RunUntilIdle();
   }
 
   void MockTabSwitchAway() {
@@ -236,7 +238,7 @@
   manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
                        &iframe_request_other_domain_);
   manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
-  base::RunLoop().RunUntilIdle();
+  task_environment()->RunUntilIdle();
 
   EXPECT_TRUE(prompt_factory_->is_visible());
 }
@@ -510,7 +512,7 @@
   EXPECT_TRUE(prompt_factory_->is_visible());
   ASSERT_EQ(prompt_factory_->request_count(), 1);
   Accept();
-  base::RunLoop().RunUntilIdle();
+  task_environment()->RunUntilIdle();
   EXPECT_TRUE(request1_.granted());
   EXPECT_FALSE(prompt_factory_->is_visible());
 }
@@ -730,17 +732,18 @@
       absl::optional<QuietUiReason> quiet_ui_reason,
       absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
           prediction_likelihood,
-      bool async)
+      absl::optional<base::TimeDelta> async_delay)
       : quiet_ui_reason_(quiet_ui_reason),
         prediction_likelihood_(prediction_likelihood),
-        async_(async) {}
+        async_delay_(async_delay) {}
 
   void SelectUiToUse(PermissionRequest* request,
                      DecisionMadeCallback callback) override {
     Decision decision(quiet_ui_reason_, Decision::ShowNoWarning());
-    if (async_) {
-      base::SequencedTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::BindOnce(std::move(callback), decision));
+    if (async_delay_) {
+      base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+          FROM_HERE, base::BindOnce(std::move(callback), decision),
+          async_delay_.value());
     } else {
       std::move(callback).Run(decision);
     }
@@ -759,19 +762,19 @@
   static void CreateForManager(
       PermissionRequestManager* manager,
       absl::optional<QuietUiReason> quiet_ui_reason,
-      bool async,
+      absl::optional<base::TimeDelta> async_delay,
       absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
           prediction_likelihood = absl::nullopt) {
     manager->add_permission_ui_selector_for_testing(
         std::make_unique<MockNotificationPermissionUiSelector>(
-            quiet_ui_reason, prediction_likelihood, async));
+            quiet_ui_reason, prediction_likelihood, async_delay));
   }
 
  private:
   absl::optional<QuietUiReason> quiet_ui_reason_;
   absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
       prediction_likelihood_;
-  bool async_;
+  absl::optional<base::TimeDelta> async_delay_;
 };
 
 // Same as the MockNotificationPermissionUiSelector but handling only the
@@ -783,10 +786,10 @@
       absl::optional<QuietUiReason> quiet_ui_reason,
       absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
           prediction_likelihood,
-      bool async)
+      absl::optional<base::TimeDelta> async_delay)
       : MockNotificationPermissionUiSelector(quiet_ui_reason,
                                              prediction_likelihood,
-                                             async) {}
+                                             async_delay) {}
 
   bool IsPermissionRequestSupported(RequestType request_type) override {
     return request_type == RequestType::kCameraStream;
@@ -795,12 +798,12 @@
   static void CreateForManager(
       PermissionRequestManager* manager,
       absl::optional<QuietUiReason> quiet_ui_reason,
-      bool async,
+      absl::optional<base::TimeDelta> async_delay,
       absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
           prediction_likelihood = absl::nullopt) {
     manager->add_permission_ui_selector_for_testing(
         std::make_unique<MockCameraStreamPermissionUiSelector>(
-            quiet_ui_reason, prediction_likelihood, async));
+            quiet_ui_reason, prediction_likelihood, async_delay));
   }
 };
 
@@ -809,7 +812,7 @@
   manager_->clear_permission_ui_selector_for_testing();
   MockNotificationPermissionUiSelector::CreateForManager(
       manager_, PermissionUiSelector::QuietUiReason::kEnabledInPrefs,
-      false /* async */);
+      absl::nullopt /* async_delay */);
 
   manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
   WaitForBubbleToBeShown();
@@ -825,18 +828,19 @@
 TEST_P(PermissionRequestManagerTest, UiSelectorUsedForNotifications) {
   const struct {
     absl::optional<PermissionUiSelector::QuietUiReason> quiet_ui_reason;
-    bool async;
+    absl::optional<base::TimeDelta> async_delay;
   } kTests[] = {
-      {QuietUiReason::kEnabledInPrefs, true},
-      {PermissionUiSelector::Decision::UseNormalUi(), true},
-      {QuietUiReason::kEnabledInPrefs, false},
-      {PermissionUiSelector::Decision::UseNormalUi(), false},
+      {QuietUiReason::kEnabledInPrefs, absl::make_optional<base::TimeDelta>()},
+      {PermissionUiSelector::Decision::UseNormalUi(),
+       absl::make_optional<base::TimeDelta>()},
+      {QuietUiReason::kEnabledInPrefs, absl::nullopt},
+      {PermissionUiSelector::Decision::UseNormalUi(), absl::nullopt},
   };
 
   for (const auto& test : kTests) {
     manager_->clear_permission_ui_selector_for_testing();
     MockNotificationPermissionUiSelector::CreateForManager(
-        manager_, test.quiet_ui_reason, test.async);
+        manager_, test.quiet_ui_reason, test.async_delay);
 
     MockPermissionRequest request(RequestType::kNotifications,
                                   PermissionRequestGestureType::GESTURE);
@@ -858,7 +862,8 @@
        UiSelectionHappensSeparatelyForEachRequest) {
   manager_->clear_permission_ui_selector_for_testing();
   MockNotificationPermissionUiSelector::CreateForManager(
-      manager_, QuietUiReason::kEnabledInPrefs, true);
+      manager_, QuietUiReason::kEnabledInPrefs,
+      absl::make_optional<base::TimeDelta>());
   MockPermissionRequest request1(RequestType::kNotifications,
                                  PermissionRequestGestureType::GESTURE);
   manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1);
@@ -870,7 +875,8 @@
                                  PermissionRequestGestureType::GESTURE);
   manager_->clear_permission_ui_selector_for_testing();
   MockNotificationPermissionUiSelector::CreateForManager(
-      manager_, PermissionUiSelector::Decision::UseNormalUi(), true);
+      manager_, PermissionUiSelector::Decision::UseNormalUi(),
+      absl::make_optional<base::TimeDelta>());
   manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
@@ -927,7 +933,9 @@
     for (size_t i = 0; i < test.quiet_ui_reasons.size(); ++i) {
       MockNotificationPermissionUiSelector::CreateForManager(
           manager_, test.quiet_ui_reasons[i],
-          test.simulate_delayed_decision[i]);
+          test.simulate_delayed_decision[i]
+              ? absl::make_optional<base::TimeDelta>()
+              : absl::nullopt);
     }
 
     MockPermissionRequest request(RequestType::kNotifications,
@@ -984,7 +992,7 @@
           test.enable_quiet_uis[i]
               ? absl::optional<QuietUiReason>(QuietUiReason::kEnabledInPrefs)
               : absl::nullopt,
-          false /* async */, test.prediction_likelihoods[i]);
+          absl::nullopt /* async_delay */, test.prediction_likelihoods[i]);
     }
 
     MockPermissionRequest request(RequestType::kNotifications,
@@ -1014,7 +1022,8 @@
   };
   manager_->clear_permission_ui_selector_for_testing();
   MockNotificationPermissionUiSelector::CreateForManager(
-      manager_, QuietUiReason::kEnabledInPrefs, true);
+      manager_, QuietUiReason::kEnabledInPrefs,
+      absl::make_optional<base::TimeDelta>());
   for (const auto& test : kTests) {
     MockPermissionRequest request(test.request_type,
                                   PermissionRequestGestureType::GESTURE);
@@ -1026,7 +1035,8 @@
   }
   // Adding a mock PermissionUiSelector that handles Camera stream.
   MockCameraStreamPermissionUiSelector::CreateForManager(
-      manager_, QuietUiReason::kEnabledInPrefs, true);
+      manager_, QuietUiReason::kEnabledInPrefs,
+      absl::make_optional<base::TimeDelta>());
   // Now the RequestType::kCameraStream should show a quiet UI as well
   MockPermissionRequest request2(RequestType::kCameraStream,
                                  PermissionRequestGestureType::GESTURE);
@@ -1167,6 +1177,58 @@
   EXPECT_EQ(prompt_factory_->show_count(), 5);
 }
 
+// Verifies order of simultaneous requests, with quiet chip enabled.
+// Simultaneous new requests are coming while we are waiting for UI selector
+// decisions.
+//
+// Permissions requested in order:
+// 1. Geolocation, UI selector takes 2 seconds to decide.
+// 2. Notification then mic. Notification will preempt geolocation
+//
+// Prompt display order:
+// 1. Mic
+// 2. Notification
+// 3. Geolocation
+TEST_P(PermissionRequestManagerTest, NewHighPriorityRequestDuringUIDecision) {
+  if (!GetParam())
+    return;
+
+  manager_->clear_permission_ui_selector_for_testing();
+  MockNotificationPermissionUiSelector::CreateForManager(
+      manager_, QuietUiReason::kTriggeredDueToAbusiveRequests,
+      absl::make_optional<base::TimeDelta>(base::Seconds(2)));
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
+
+  task_environment()->FastForwardBy(base::Seconds(1));
+
+  MockPermissionRequest request(RequestType::kNotifications,
+                                PermissionRequestGestureType::GESTURE);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
+  WaitForBubbleToBeShown();
+  manager_->clear_permission_ui_selector_for_testing();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request_mic_.granted());
+  EXPECT_FALSE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request1_.granted());
+}
+
 class PermissionRequestManagerTestQuietChip
     : public PermissionRequestManagerTest {
  public:
@@ -1194,7 +1256,7 @@
   MockNotificationPermissionUiSelector::CreateForManager(
       manager_,
       PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
-      false /* async */);
+      absl::nullopt /* async_delay */);
 
   std::unique_ptr<MockPermissionRequest> request_notifications =
       CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
@@ -1229,7 +1291,7 @@
   MockNotificationPermissionUiSelector::CreateForManager(
       manager_,
       PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
-      false /* async */);
+      absl::nullopt /* async_delay */);
 
   std::unique_ptr<MockPermissionRequest> request_notifications =
       CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
@@ -1273,7 +1335,7 @@
   MockNotificationPermissionUiSelector::CreateForManager(
       manager_,
       PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
-      false /* async */);
+      absl::nullopt /* async_delay */);
 
   std::unique_ptr<MockPermissionRequest> request_notifications =
       CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
@@ -1319,7 +1381,7 @@
   MockNotificationPermissionUiSelector::CreateForManager(
       manager_,
       PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
-      false /* async */);
+      absl::nullopt /* async_delay */);
 
   std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
       RequestType::kCameraStream, /*should_be_seen=*/true, 1);
@@ -1374,7 +1436,7 @@
   MockNotificationPermissionUiSelector::CreateForManager(
       manager_,
       PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
-      false /* async */);
+      absl::nullopt /* async_delay */);
 
   std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
       RequestType::kCameraStream, /*should_be_seen=*/true, 1);
@@ -1490,4 +1552,326 @@
                          PermissionRequestManagerTestQuietChip,
                          ::testing::Values(false, true));
 
+// Verifies order of requests with mixed low-high priority requests input, with
+// both chip and quiet chip enabled. New permissions are added and accepted one
+// by one.
+//
+// Permissions requested in order:
+// 1. Multiple Download (high)
+// 2. Geolocation (low)
+// 3. Mic (high)
+//
+// Prompt display order:
+// 1. Mic
+// 2. Multiple Download
+// 3. Geolocation
+TEST_P(PermissionRequestManagerTestQuietChip, Mixed1Low2HighPriorityRequests) {
+  if (!GetParam())
+    return;
+
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
+  WaitForBubbleToBeShown();
+
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
+  WaitForBubbleToBeShown();
+
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request_mic_.granted());
+  EXPECT_FALSE(request2_.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request2_.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request1_.granted());
+}
+
+// Verifies order of requests with mixed low-high priority requests input, with
+// both chip and quiet chip enabled. New permissions are added and accepted one
+// by one.
+//
+// Permissions requested in order:
+// 1. Geolocation (low)
+// 2. Mic (high)
+// 3. Notification (low)
+//
+// Prompt display order:
+// 1. Mic
+// 2. Notification
+// 3. Geolocation
+TEST_P(PermissionRequestManagerTestQuietChip, Mixed2Low1HighRequests) {
+  if (!GetParam())
+    return;
+
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
+  WaitForBubbleToBeShown();
+
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
+  WaitForBubbleToBeShown();
+
+  MockPermissionRequest request(RequestType::kNotifications,
+                                PermissionRequestGestureType::GESTURE);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request_mic_.granted());
+  EXPECT_FALSE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request1_.granted());
+}
+
+// Verifies order of requests with mixed low-high priority requests input, added
+// simultaneously, with both chip and quiet chip enabled.
+//
+// Permissions requested in order:
+// 1. Geolocation (low)
+// 2. Mic (high)
+// 3. Notification (low)
+//
+// Prompt display order:
+// 1. Mic
+// 2. Notification
+// 3. Geolocation
+TEST_P(PermissionRequestManagerTestQuietChip,
+       MultipleSimultaneous2Low1HighRequests) {
+  if (!GetParam())
+    return;
+
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
+  MockPermissionRequest request(RequestType::kNotifications,
+                                PermissionRequestGestureType::GESTURE);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request_mic_.granted());
+  EXPECT_FALSE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request1_.granted());
+}
+
+// Verifies order of requests with mixed low-high priority requests input,
+// added simultaneously, with both chip and quiet chip enabled.
+//
+// Permissions requested in order:
+// 1. MIDI (high)
+// 2. Geolocation (low)
+// 3. Mic (high)
+// 4. Notification (low)
+// 5. Multiple Download (high)
+//
+// Prompt display order:
+// 1. Multiple Download
+// 2. Mic
+// 3. Midi
+// 4. Notification
+// 5. Geolocation
+TEST_P(PermissionRequestManagerTestQuietChip,
+       MultipleSimultaneous2Low3HighRequests) {
+  if (!GetParam())
+    return;
+  MockPermissionRequest request_midi(RequestType::kMidiSysex,
+                                     PermissionRequestGestureType::GESTURE);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_midi);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
+  MockPermissionRequest request_notification(
+      RequestType::kNotifications, PermissionRequestGestureType::GESTURE);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &request_notification);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_FALSE(request_mic_.granted());
+  EXPECT_TRUE(request2_.granted());
+  EXPECT_FALSE(request_notification.granted());
+  EXPECT_FALSE(request1_.granted());
+  EXPECT_FALSE(request_midi.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request_mic_.granted());
+  EXPECT_FALSE(request_notification.granted());
+  EXPECT_FALSE(request1_.granted());
+  EXPECT_FALSE(request_midi.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_FALSE(request_notification.granted());
+  EXPECT_FALSE(request1_.granted());
+  EXPECT_TRUE(request_midi.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request_notification.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request1_.granted());
+}
+
+// Verifies order of requests with mixed low-high priority requests input, added
+// simultaneously several times, with both chip and quiet chip enabled.
+//
+// Permissions requested in order:
+// 1. Geolocation(low) then Notification(low)
+// 2. Mic (high) then multiple downloads (high)
+// Prompt display order:
+// 1. Multiple Download
+// 2. Mic
+// 3. Notification
+// 4. Geolocation
+TEST_P(PermissionRequestManagerTestQuietChip,
+       MultipleSimultaneous2Low2HighRequests) {
+  if (!GetParam())
+    return;
+
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
+  MockPermissionRequest request(RequestType::kNotifications,
+                                PermissionRequestGestureType::GESTURE);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
+  WaitForBubbleToBeShown();
+
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request2_.granted());
+  EXPECT_FALSE(request_mic_.granted());
+  EXPECT_FALSE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request_mic_.granted());
+  EXPECT_FALSE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request1_.granted());
+}
+
+// Verifies order of requests with mixed low-high priority requests input, with
+// both chip and quiet chip enabled. Simultaneous new requests are coming while
+// we are waiting for UI selector decisions.
+//
+// Permissions requested in order:
+// 1. Geolocation (low), UI selector takes 2 seconds to decide.
+// 2. Notification(low) then mic (high)
+//
+// Prompt display order:
+// 1. Mic
+// 2. Geolocation will get delayed 2 seconds, then preempted to front of queue
+// 3. Notification
+TEST_P(PermissionRequestManagerTestQuietChip,
+       NewHighPriorityRequestDuringUIDecision) {
+  if (!GetParam())
+    return;
+
+  manager_->clear_permission_ui_selector_for_testing();
+  MockNotificationPermissionUiSelector::CreateForManager(
+      manager_, QuietUiReason::kTriggeredDueToAbusiveRequests,
+      absl::make_optional<base::TimeDelta>(base::Seconds(2)));
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
+
+  task_environment()->FastForwardBy(base::Seconds(1));
+
+  MockPermissionRequest request(RequestType::kNotifications,
+                                PermissionRequestGestureType::GESTURE);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
+  WaitForBubbleToBeShown();
+  manager_->clear_permission_ui_selector_for_testing();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request_mic_.granted());
+  EXPECT_FALSE(request.granted());
+  EXPECT_FALSE(request1_.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request1_.granted());
+  EXPECT_FALSE(request.granted());
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  EXPECT_EQ(prompt_factory_->request_count(), 1);
+  Accept();
+  EXPECT_TRUE(request.granted());
+}
+
 }  // namespace permissions
diff --git a/components/permissions/permission_request_queue.cc b/components/permissions/permission_request_queue.cc
index 15ff50b0..1c515fe 100644
--- a/components/permissions/permission_request_queue.cc
+++ b/components/permissions/permission_request_queue.cc
@@ -6,6 +6,7 @@
 
 #include "base/stl_util.h"
 #include "components/permissions/features.h"
+#include "components/permissions/permission_util.h"
 
 namespace permissions {
 
@@ -13,19 +14,19 @@
 
 PermissionRequestQueue::~PermissionRequestQueue() = default;
 
-bool PermissionRequestQueue::IsEmpty() {
+bool PermissionRequestQueue::IsEmpty() const {
   return queued_requests_.empty();
 }
 
-size_t PermissionRequestQueue::Count() {
+size_t PermissionRequestQueue::Count() const {
   return queued_requests_.size();
 }
 
-size_t PermissionRequestQueue::Count(PermissionRequest* request) {
+size_t PermissionRequestQueue::Count(PermissionRequest* request) const {
   return base::STLCount(queued_requests_, request);
 }
 
-void PermissionRequestQueue::Push(permissions::PermissionRequest* request) {
+void PermissionRequestQueue::PushInternal(PermissionRequest* request) {
   if (base::FeatureList::IsEnabled(features::kPermissionQuietChip) &&
       !base::FeatureList::IsEnabled(features::kPermissionChip)) {
     queued_requests_.push_front(request);
@@ -34,6 +35,41 @@
   }
 }
 
+void PermissionRequestQueue::Push(PermissionRequest* request,
+                                  bool reorder_based_on_priority) {
+  if (!reorder_based_on_priority) {
+    PushInternal(request);
+    return;
+  }
+
+  if (!base::FeatureList::IsEnabled(features::kPermissionQuietChip) ||
+      !base::FeatureList::IsEnabled(features::kPermissionChip)) {
+    PushInternal(request);
+    return;
+  }
+
+  // There're situations we need to take the priority into consideration (eg:
+  // kPermissionChip and kPermissionQuietChip both are enabled). In such cases,
+  // push the new request to front of queue if it has high priority. Otherwise,
+  // insert the request after the first low priority request.
+  // Note that, the queue processing order is FIFO, but we have to iterate the
+  // queue in reverse order (see |PushInternal|)
+  if (queued_requests_.empty() ||
+      !PermissionUtil::IsLowPriorityPermissionRequest(request)) {
+    PushInternal(request);
+    return;
+  }
+
+  PermissionRequestQueue::const_reverse_iterator iter =
+      queued_requests_.rbegin();
+  for (; iter != queued_requests_.rend() &&
+         !PermissionUtil::IsLowPriorityPermissionRequest(*iter);
+       ++iter) {
+  }
+
+  queued_requests_.insert(iter.base(), request);
+}
+
 PermissionRequest* PermissionRequestQueue::Pop() {
   PermissionRequest* next = Peek();
   if (base::FeatureList::IsEnabled(features::kPermissionChip))
@@ -43,14 +79,14 @@
   return next;
 }
 
-PermissionRequest* PermissionRequestQueue::Peek() {
+PermissionRequest* PermissionRequestQueue::Peek() const {
   return base::FeatureList::IsEnabled(features::kPermissionChip)
              ? queued_requests_.back()
              : queued_requests_.front();
 }
 
 PermissionRequest* PermissionRequestQueue::FindDuplicate(
-    PermissionRequest* request) {
+    PermissionRequest* request) const {
   for (PermissionRequest* queued_request : queued_requests_) {
     if (request->IsDuplicateOf(queued_request)) {
       return queued_request;
@@ -59,11 +95,11 @@
   return nullptr;
 }
 
-PermissionRequestQueue::iterator PermissionRequestQueue::begin() {
+PermissionRequestQueue::const_iterator PermissionRequestQueue::begin() const {
   return queued_requests_.begin();
 }
 
-PermissionRequestQueue::iterator PermissionRequestQueue::end() {
+PermissionRequestQueue::const_iterator PermissionRequestQueue::end() const {
   return queued_requests_.end();
 }
 
diff --git a/components/permissions/permission_request_queue.h b/components/permissions/permission_request_queue.h
index 326bf30..c46d778 100644
--- a/components/permissions/permission_request_queue.h
+++ b/components/permissions/permission_request_queue.h
@@ -17,7 +17,10 @@
 // configuration.
 class PermissionRequestQueue {
  public:
-  using iterator = base::circular_deque<PermissionRequest*>::iterator;
+  using const_iterator =
+      base::circular_deque<PermissionRequest*>::const_iterator;
+  using const_reverse_iterator =
+      base::circular_deque<PermissionRequest*>::const_reverse_iterator;
 
   // Not copyable or movable
   PermissionRequestQueue(const PermissionRequestQueue&) = delete;
@@ -25,20 +28,28 @@
   PermissionRequestQueue();
   ~PermissionRequestQueue();
 
-  bool IsEmpty();
-  size_t Count();
-  size_t Count(PermissionRequest* request);
-  void Push(permissions::PermissionRequest* request);
+  bool IsEmpty() const;
+  size_t Count() const;
+  size_t Count(PermissionRequest* request) const;
+
+  // Push a new request into queue. When |reorder_based_on_priority| is set, the
+  // request might be inserted to correct position based on its priority,
+  // instead of be pushed to the front of queue.
+  void Push(permissions::PermissionRequest* request,
+            bool reorder_based_on_priority = false);
   PermissionRequest* Pop();
-  PermissionRequest* Peek();
+  PermissionRequest* Peek() const;
 
   // Searches queued_requests_ and returns the first matching request, or
   // nullptr if there is no match.
-  PermissionRequest* FindDuplicate(PermissionRequest* request);
+  PermissionRequest* FindDuplicate(PermissionRequest* request) const;
+
+  // Used for iterating over the queued requests.
+  const_iterator begin() const;
+  const_iterator end() const;
 
  private:
-  iterator begin();
-  iterator end();
+  void PushInternal(permissions::PermissionRequest* request);
 
   base::circular_deque<PermissionRequest*> queued_requests_;
 };
diff --git a/components/permissions/permission_util.cc b/components/permissions/permission_util.cc
index da651158..a061fc3a 100644
--- a/components/permissions/permission_util.cc
+++ b/components/permissions/permission_util.cc
@@ -10,6 +10,7 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "components/permissions/features.h"
+#include "components/permissions/permission_request.h"
 #include "components/permissions/permission_result.h"
 #include "components/permissions/permissions_client.h"
 #include "content/public/browser/browser_context.h"
@@ -172,6 +173,12 @@
   return PermissionUtil::GetPermissionType(type, &permission);
 }
 
+bool PermissionUtil::IsLowPriorityPermissionRequest(
+    const PermissionRequest* request) {
+  return request->request_type() == RequestType::kNotifications ||
+         request->request_type() == RequestType::kGeolocation;
+}
+
 bool PermissionUtil::IsGuardContentSetting(ContentSettingsType type) {
   switch (type) {
     case ContentSettingsType::USB_GUARD:
diff --git a/components/permissions/permission_util.h b/components/permissions/permission_util.h
index 65317ca..fc021b48 100644
--- a/components/permissions/permission_util.h
+++ b/components/permissions/permission_util.h
@@ -11,7 +11,6 @@
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/permissions/permission_prompt.h"
-#include "components/permissions/permission_request.h"
 #include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
 
 namespace blink {
@@ -27,6 +26,7 @@
 class GURL;
 
 namespace permissions {
+class PermissionRequest;
 struct PermissionResult;
 
 // This enum backs a UMA histogram, so it must be treated as append-only.
@@ -69,6 +69,11 @@
   // PermissionManager.
   static bool IsPermission(ContentSettingsType type);
 
+  // Check whether the given permission request has low priority, based on the
+  // acceptance rates data (notifications and geolocations have the lowest
+  // acceptance data)
+  static bool IsLowPriorityPermissionRequest(const PermissionRequest* request);
+
   // Checks whether the given ContentSettingsType is a guard content setting,
   // meaning it does not support allow setting and toggles between "ask" and
   // "block" instead. This is primarily used for chooser-based permissions.
diff --git a/components/permissions/test/permission_request_observer.cc b/components/permissions/test/permission_request_observer.cc
index 093ad6b8..ba0bd291 100644
--- a/components/permissions/test/permission_request_observer.cc
+++ b/components/permissions/test/permission_request_observer.cc
@@ -17,7 +17,7 @@
   loop_.Run();
 }
 
-void PermissionRequestObserver::OnBubbleAdded() {
+void PermissionRequestObserver::OnPromptAdded() {
   request_shown_ = true;
   loop_.Quit();
 }
diff --git a/components/permissions/test/permission_request_observer.h b/components/permissions/test/permission_request_observer.h
index bc38b845..48b32f1 100644
--- a/components/permissions/test/permission_request_observer.h
+++ b/components/permissions/test/permission_request_observer.h
@@ -27,7 +27,7 @@
   void Wait();
 
   // PermissionRequestManager::Observer:
-  void OnBubbleAdded() override;
+  void OnPromptAdded() override;
   void OnRequestsFinalized() override;
   void OnPermissionRequestManagerDestructed() override;
 
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 1b48173..9b5e993 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -17221,7 +17221,6 @@
       ],
       'default': True,
       'example_value': True,
-      'default_for_enterprise_users': False,
       'id': 1015,
       'caption': '''Enable <ph name="GOOGLE_CALENDAR_NAME">Google Calendar</ph> Integration''',
       'tags': [],
@@ -17231,7 +17230,7 @@
 
           If this policy is disabled, <ph name="PRODUCT_OS_NAME">$2<ex>Google ChromeOS</ex></ph> device cannot retrieve <ph name="GOOGLE_CALENDAR_NAME">Google Calendar</ph> events to populate <ph name="PRODUCT_OS_NAME">$2<ex>Google ChromeOS</ex></ph> calendar widget in system status bar for the logged in user.
 
-          If this policy is left unset, the <ph name="GOOGLE_CALENDAR_NAME">Google Calendar</ph> feature is disabled by default for enterprise users.''',
+          If this policy is left unset, the <ph name="GOOGLE_CALENDAR_NAME">Google Calendar</ph> feature is enabled by default for enterprise users.''',
     },
     {
       'name': 'DeviceLoginScreenDefaultScreenMagnifierType',
diff --git a/components/saved_tab_groups/saved_tab_group_model.cc b/components/saved_tab_groups/saved_tab_group_model.cc
index e50376e..686db4d 100644
--- a/components/saved_tab_groups/saved_tab_group_model.cc
+++ b/components/saved_tab_groups/saved_tab_group_model.cc
@@ -5,11 +5,13 @@
 #include "components/saved_tab_groups/saved_tab_group_model.h"
 
 #include <cstddef>
+#include <memory>
 #include <vector>
 
 #include "base/observer_list.h"
 #include "components/saved_tab_groups/saved_tab_group.h"
 #include "components/saved_tab_groups/saved_tab_group_model_observer.h"
+#include "components/sync/protocol/saved_tab_group_specifics.pb.h"
 #include "components/tab_groups/tab_group_color.h"
 #include "components/tab_groups/tab_group_id.h"
 #include "components/tab_groups/tab_group_visual_data.h"
@@ -20,30 +22,58 @@
 
 SavedTabGroupModel::SavedTabGroupModel(Profile* profile) : profile_(profile) {}
 
-int SavedTabGroupModel::GetIndexOf(tab_groups::TabGroupId tab_group_id) const {
-  for (size_t i = 0; i < saved_tab_groups_.size(); i++)
+absl::optional<int> SavedTabGroupModel::GetIndexOf(
+    tab_groups::TabGroupId tab_group_id) const {
+  for (size_t i = 0; i < saved_tab_groups_.size(); i++) {
     if (saved_tab_groups_[i].local_group_id() == tab_group_id)
       return i;
+  }
 
-  return -1;
+  return absl::nullopt;
 }
 
-int SavedTabGroupModel::GetIndexOf(const base::GUID& id) const {
+absl::optional<int> SavedTabGroupModel::GetIndexOf(const base::GUID& id) const {
   for (size_t i = 0; i < saved_tab_groups_.size(); i++) {
     if (saved_tab_groups_[i].saved_guid() == id)
       return i;
   }
 
-  return -1;
+  return absl::nullopt;
 }
 
 const SavedTabGroup* SavedTabGroupModel::Get(const base::GUID& id) const {
-  int index = GetIndexOf(id);
-  if (index < 0) {
+  absl::optional<int> index = GetIndexOf(id);
+  if (!index.has_value()) {
     return nullptr;
   }
 
-  return &saved_tab_groups_[index];
+  return &saved_tab_groups_[index.value()];
+}
+
+SavedTabGroup* SavedTabGroupModel::Get(const base::GUID& id) {
+  absl::optional<int> index = GetIndexOf(id);
+  if (!index.has_value())
+    return nullptr;
+
+  return &saved_tab_groups_[index.value()];
+}
+
+const SavedTabGroup* SavedTabGroupModel::Get(
+    const tab_groups::TabGroupId local_group_id) const {
+  absl::optional<int> index = GetIndexOf(local_group_id);
+  if (!index.has_value())
+    return nullptr;
+
+  return &saved_tab_groups_[index.value()];
+}
+
+SavedTabGroup* SavedTabGroupModel::Get(
+    const tab_groups::TabGroupId local_group_id) {
+  absl::optional<int> index = GetIndexOf(local_group_id);
+  if (!index.has_value())
+    return nullptr;
+
+  return &saved_tab_groups_[index.value()];
 }
 
 void SavedTabGroupModel::Add(SavedTabGroup saved_group) {
@@ -52,24 +82,31 @@
 
   saved_tab_groups_.emplace_back(std::move(saved_group));
   const int index = Count() - 1;
-  for (auto& observer : observers_)
-    observer.SavedTabGroupAdded(saved_tab_groups_[index], index);
+  for (auto& observer : observers_) {
+    observer.SavedTabGroupAddedLocally(saved_tab_groups_[index].saved_guid());
+  }
 }
 
 void SavedTabGroupModel::Remove(const tab_groups::TabGroupId tab_group_id) {
   if (!Contains(tab_group_id))
     return;
 
-  const int index = GetIndexOf(tab_group_id);
-  RemoveImpl(index);
+  const absl::optional<int> index = GetIndexOf(tab_group_id);
+  base::GUID removed_guid = Get(tab_group_id)->saved_guid();
+  std::unique_ptr<SavedTabGroup> removed_group = RemoveImpl(index.value());
+  for (auto& observer : observers_)
+    observer.SavedTabGroupRemovedLocally(removed_group.get());
 }
 
 void SavedTabGroupModel::Remove(const base::GUID& id) {
   if (!Contains(id))
     return;
 
-  const int index = GetIndexOf(id);
-  return RemoveImpl(index);
+  const absl::optional<int> index = GetIndexOf(id);
+  base::GUID removed_guid = Get(id)->saved_guid();
+  std::unique_ptr<SavedTabGroup> removed_group = RemoveImpl(index.value());
+  for (auto& observer : observers_)
+    observer.SavedTabGroupRemovedLocally(removed_group.get());
 }
 
 void SavedTabGroupModel::UpdateVisualData(
@@ -78,8 +115,11 @@
   if (!Contains(tab_group_id))
     return;
 
-  const int index = GetIndexOf(tab_group_id);
-  UpdateVisualDataImpl(index, visual_data);
+  const absl::optional<int> index = GetIndexOf(tab_group_id);
+  UpdateVisualDataImpl(index.value(), visual_data);
+  base::GUID updated_guid = Get(tab_group_id)->saved_guid();
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedLocally(updated_guid);
 }
 
 void SavedTabGroupModel::UpdateVisualData(
@@ -88,59 +128,235 @@
   if (!Contains(id))
     return;
 
-  const int index = GetIndexOf(id);
-  UpdateVisualDataImpl(index, visual_data);
+  const absl::optional<int> index = GetIndexOf(id);
+  UpdateVisualDataImpl(index.value(), visual_data);
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedLocally(id);
+}
+
+void SavedTabGroupModel::AddedFromSync(SavedTabGroup saved_group) {
+  if (Contains(saved_group.saved_guid()))
+    return;
+
+  saved_tab_groups_.emplace_back(std::move(saved_group));
+  const int index = Count() - 1;
+  for (auto& observer : observers_)
+    observer.SavedTabGroupAddedFromSync(saved_tab_groups_[index].saved_guid());
+}
+
+void SavedTabGroupModel::RemovedFromSync(
+    const tab_groups::TabGroupId tab_group_id) {
+  if (!Contains(tab_group_id))
+    return;
+
+  const absl::optional<int> index = GetIndexOf(tab_group_id);
+  base::GUID removed_guid = Get(tab_group_id)->saved_guid();
+  std::unique_ptr<SavedTabGroup> removed_group = RemoveImpl(index.value());
+  for (auto& observer : observers_)
+    observer.SavedTabGroupRemovedFromSync(removed_group.get());
+}
+
+void SavedTabGroupModel::RemovedFromSync(const base::GUID& id) {
+  if (!Contains(id))
+    return;
+
+  const absl::optional<int> index = GetIndexOf(id);
+  base::GUID removed_guid = Get(id)->saved_guid();
+  std::unique_ptr<SavedTabGroup> removed_group = RemoveImpl(index.value());
+  for (auto& observer : observers_)
+    observer.SavedTabGroupRemovedFromSync(removed_group.get());
+}
+
+void SavedTabGroupModel::UpdatedVisualDataFromSync(
+    tab_groups::TabGroupId tab_group_id,
+    const tab_groups::TabGroupVisualData* visual_data) {
+  if (!Contains(tab_group_id))
+    return;
+
+  const absl::optional<int> index = GetIndexOf(tab_group_id);
+  UpdateVisualDataImpl(index.value(), visual_data);
+  base::GUID updated_guid = Get(tab_group_id)->saved_guid();
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedFromSync(updated_guid);
+}
+
+void SavedTabGroupModel::UpdatedVisualDataFromSync(
+    const base::GUID& id,
+    const tab_groups::TabGroupVisualData* visual_data) {
+  if (!Contains(id))
+    return;
+
+  const absl::optional<int> index = GetIndexOf(id);
+  UpdateVisualDataImpl(index.value(), visual_data);
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedFromSync(id);
+}
+
+void SavedTabGroupModel::AddTabToGroup(const base::GUID& group_id,
+                                       SavedTabGroupTab tab,
+                                       int index) {
+  if (!Contains(group_id))
+    return;
+
+  absl::optional<int> group_index = GetIndexOf(group_id);
+  saved_tab_groups_[group_index.value()].AddTab(index, tab);
+
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedLocally(group_id);
+}
+
+void SavedTabGroupModel::RemoveTabFromGroup(const base::GUID& group_id,
+                                            const base::GUID& tab_id) {
+  if (!Contains(group_id))
+    return;
+
+  absl::optional<int> index = GetIndexOf(group_id);
+  saved_tab_groups_[index.value()].RemoveTab(tab_id);
+
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedLocally(group_id);
+}
+
+void SavedTabGroupModel::ReplaceTabInGroupAt(const base::GUID& group_id,
+                                             const base::GUID& tab_id,
+                                             SavedTabGroupTab new_tab) {
+  if (!Contains(group_id))
+    return;
+
+  absl::optional<int> index = GetIndexOf(group_id);
+  saved_tab_groups_[index.value()].ReplaceTabAt(tab_id, new_tab);
+
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedLocally(group_id);
+}
+
+void SavedTabGroupModel::MoveTabInGroupTo(const base::GUID& group_id,
+                                          const base::GUID& tab_id,
+                                          int new_index) {
+  if (!Contains(group_id))
+    return;
+
+  absl::optional<int> index = GetIndexOf(group_id);
+  saved_tab_groups_[index.value()].MoveTab(tab_id, new_index);
+
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedLocally(group_id);
+}
+
+std::unique_ptr<sync_pb::SavedTabGroupSpecifics> SavedTabGroupModel::MergeGroup(
+    std::unique_ptr<sync_pb::SavedTabGroupSpecifics> sync_specific) {
+  const base::GUID& group_id =
+      base::GUID::ParseLowercase(sync_specific->guid());
+
+  DCHECK(Contains(group_id));
+
+  absl::optional<int> index = GetIndexOf(group_id);
+  saved_tab_groups_[index.value()].MergeGroup(std::move(sync_specific));
+
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedFromSync(group_id);
+
+  return saved_tab_groups_[index.value()].ToSpecifics();
+}
+
+std::unique_ptr<sync_pb::SavedTabGroupSpecifics> SavedTabGroupModel::MergeTab(
+    std::unique_ptr<sync_pb::SavedTabGroupSpecifics> sync_specific) {
+  const base::GUID& group_id =
+      base::GUID::ParseLowercase(sync_specific->tab().group_guid());
+  const base::GUID& tab_id = base::GUID::ParseLowercase(sync_specific->guid());
+  DCHECK(Contains(group_id));
+
+  absl::optional<int> index = GetIndexOf(group_id);
+  saved_tab_groups_[index.value()].GetTab(tab_id)->MergeTab(
+      std::move(sync_specific));
+
+  for (auto& observer : observers_)
+    observer.SavedTabGroupUpdatedFromSync(group_id);
+
+  return saved_tab_groups_[index.value()].GetTab(tab_id)->ToSpecifics();
 }
 
 void SavedTabGroupModel::Reorder(const base::GUID& id, int new_index) {
   DCHECK_GE(new_index, 0);
   DCHECK_LT(new_index, Count());
 
-  int index = GetIndexOf(id);
-  CHECK_GE(index, 0);
+  absl::optional<int> index = GetIndexOf(id);
+  CHECK(index.has_value());
+  CHECK_GE(index.value(), 0);
 
-  SavedTabGroup group = saved_tab_groups_[index];
+  SavedTabGroup group = saved_tab_groups_[index.value()];
 
-  saved_tab_groups_.erase(saved_tab_groups_.begin() + index);
+  saved_tab_groups_.erase(saved_tab_groups_.begin() + index.value());
   saved_tab_groups_.emplace(saved_tab_groups_.begin() + new_index,
                             std::move(group));
 
   for (auto& observer : observers_)
-    observer.SavedTabGroupMoved(saved_tab_groups_[new_index], index, new_index);
+    observer.SavedTabGroupReorderedLocally();
+}
+
+void SavedTabGroupModel::LoadStoredEntries(
+    std::vector<sync_pb::SavedTabGroupSpecifics> entries) {
+  // TODO(crbug/1372095): Figure out if we should clear `saved_tab_groups`, in
+  // the case there are entries saved before the bridge had a chance to load.
+  std::vector<SavedTabGroupTab> tabs;
+
+  // The `entries` is not ordered such that groups are guaranteed to be
+  // at the front of the vector. As such, we can run into the case where we
+  // try to add a tab to a group that does not exist for us yet.
+  for (sync_pb::SavedTabGroupSpecifics proto : entries) {
+    if (proto.has_group())
+      saved_tab_groups_.emplace_back(SavedTabGroup::FromSpecifics(proto));
+    else
+      tabs.emplace_back(SavedTabGroupTab::FromSpecifics(proto));
+  }
+
+  for (auto tab : tabs) {
+    absl::optional<int> index = GetIndexOf(tab.group_guid());
+    if (!index.has_value())
+      continue;
+
+    saved_tab_groups_[index.value()].AddTab(0, std::move(tab));
+  }
+
+  for (SavedTabGroup group : saved_tab_groups_) {
+    for (auto& observer : observers_)
+      observer.SavedTabGroupAddedLocally(group.saved_guid());
+  }
 }
 
 void SavedTabGroupModel::OnGroupClosedInTabStrip(
     const tab_groups::TabGroupId& tab_group_id) {
-  const int index = GetIndexOf(tab_group_id);
-  if (index == -1)
+  const absl::optional<int> index = GetIndexOf(tab_group_id);
+  if (!index.has_value())
     return;
 
-  SavedTabGroup& saved_group = saved_tab_groups_[index];
+  SavedTabGroup& saved_group = saved_tab_groups_[index.value()];
   saved_group.SetLocalGroupId(absl::nullopt);
 
   for (auto& observer : observers_)
-    observer.SavedTabGroupUpdated(saved_group, index);
+    observer.SavedTabGroupUpdatedLocally(saved_group.saved_guid());
 }
 
 void SavedTabGroupModel::OnGroupOpenedInTabStrip(
     const base::GUID& id,
     const tab_groups::TabGroupId& tab_group_id) {
-  const int index = GetIndexOf(id);
-  CHECK_GE(index, 0);
+  const absl::optional<int> index = GetIndexOf(id);
+  CHECK(index.has_value());
+  CHECK_GE(index.value(), 0);
 
-  SavedTabGroup& saved_group = saved_tab_groups_[index];
+  SavedTabGroup& saved_group = saved_tab_groups_[index.value()];
   saved_group.SetLocalGroupId(tab_group_id);
 
   for (auto& observer : observers_)
-    observer.SavedTabGroupUpdated(saved_group, index);
+    observer.SavedTabGroupUpdatedLocally(saved_group.saved_guid());
 }
 
-void SavedTabGroupModel::RemoveImpl(int index) {
+std::unique_ptr<SavedTabGroup> SavedTabGroupModel::RemoveImpl(int index) {
   CHECK_GE(index, 0);
+  std::unique_ptr<SavedTabGroup> removed_group =
+      std::make_unique<SavedTabGroup>(std::move(saved_tab_groups_[index]));
   saved_tab_groups_.erase(saved_tab_groups_.begin() + index);
-
-  for (auto& observer : observers_)
-    observer.SavedTabGroupRemoved(index);
+  return removed_group;
 }
 
 void SavedTabGroupModel::UpdateVisualDataImpl(
@@ -153,8 +369,6 @@
 
   saved_group.SetTitle(visual_data->title());
   saved_group.SetColor(visual_data->color());
-  for (auto& observer : observers_)
-    observer.SavedTabGroupUpdated(saved_group, index);
 }
 
 void SavedTabGroupModel::AddObserver(SavedTabGroupModelObserver* observer) {
diff --git a/components/saved_tab_groups/saved_tab_group_model.h b/components/saved_tab_groups/saved_tab_group_model.h
index 5eb2943b..226bb02 100644
--- a/components/saved_tab_groups/saved_tab_group_model.h
+++ b/components/saved_tab_groups/saved_tab_group_model.h
@@ -5,15 +5,18 @@
 #ifndef COMPONENTS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_MODEL_H_
 #define COMPONENTS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_MODEL_H_
 
+#include <memory>
 #include <vector>
 
 #include "base/memory/raw_ptr.h"
-
 #include "base/observer_list.h"
 #include "components/saved_tab_groups/saved_tab_group.h"
+#include "components/saved_tab_groups/saved_tab_group_tab.h"
+#include "components/sync/protocol/saved_tab_group_specifics.pb.h"
 #include "components/tab_groups/tab_group_color.h"
 #include "components/tab_groups/tab_group_id.h"
 #include "components/tab_groups/tab_group_visual_data.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
 class SavedTabGroupModelObserver;
@@ -34,22 +37,29 @@
     return saved_tab_groups_;
   }
   Profile* profile() const { return profile_; }
+  std::vector<SavedTabGroup> saved_tab_groups() { return saved_tab_groups_; }
 
   // Returns the index of the SavedTabGroup if it exists in the vector. Else
-  // returns -1.
-  int GetIndexOf(const tab_groups::TabGroupId local_group_id) const;
-  int GetIndexOf(const base::GUID& id) const;
+  // absl::nullopt.
+  absl::optional<int> GetIndexOf(
+      const tab_groups::TabGroupId local_group_id) const;
+  absl::optional<int> GetIndexOf(const base::GUID& id) const;
 
   // Get a pointer to the SavedTabGroup from an ID. Returns nullptr if not in
   // vector.
   const SavedTabGroup* Get(const tab_groups::TabGroupId local_group_id) const;
   const SavedTabGroup* Get(const base::GUID& id) const;
+  // TODO(crbug/1372503): Remove non-const accessor functions.
+  SavedTabGroup* Get(const tab_groups::TabGroupId local_group_id);
+  SavedTabGroup* Get(const base::GUID& id);
 
   // Methods for checking if a group is in the SavedTabGroupModel.
   bool Contains(const tab_groups::TabGroupId& local_group_id) const {
-    return GetIndexOf(local_group_id) >= 0;
+    return GetIndexOf(local_group_id).has_value();
   }
-  bool Contains(const base::GUID& id) const { return GetIndexOf(id) >= 0; }
+  bool Contains(const base::GUID& id) const {
+    return GetIndexOf(id).has_value();
+  }
 
   // Helper for getting number of SavedTabGroups in the vector.
   int Count() const { return saved_tab_groups_.size(); }
@@ -57,7 +67,7 @@
   // Helper for getting empty state of the SavedTabGroup vector.
   bool IsEmpty() const { return Count() <= 0; }
 
-  // Add / Remove a single tab group from the model.
+  // Add / Remove / Update a single tab group from the model.
   void Add(SavedTabGroup saved_group);
   void Remove(const tab_groups::TabGroupId local_group_id);
   void Remove(const base::GUID& id);
@@ -66,10 +76,60 @@
   void UpdateVisualData(const base::GUID& id,
                         const tab_groups::TabGroupVisualData* visual_data);
 
+  // Similar to the Add/Remove/Update but originate from sync. As such, these
+  // function do not notify sync observers of these changes to avoid looping
+  // calls.
+  void AddedFromSync(SavedTabGroup saved_group);
+  void RemovedFromSync(const tab_groups::TabGroupId local_group_id);
+  void RemovedFromSync(const base::GUID& id);
+  void UpdatedVisualDataFromSync(
+      const tab_groups::TabGroupId local_group_id,
+      const tab_groups::TabGroupVisualData* visual_data);
+  void UpdatedVisualDataFromSync(
+      const base::GUID& id,
+      const tab_groups::TabGroupVisualData* visual_data);
+
+  // Adds a saved tab to `index` in the specified group denoted by `group_id` if
+  // it exists.
+  void AddTabToGroup(const base::GUID& group_id,
+                     SavedTabGroupTab tab,
+                     int index);
+
+  // Removes a saved tab from `index` in the specified group denoted by
+  // `group_id` if it exists.
+  void RemoveTabFromGroup(const base::GUID& group_id, const base::GUID& tab_id);
+
+  // Replaces a saved tab at `index` in the specified group denoted by
+  // `group_id` if it exists.
+  void ReplaceTabInGroupAt(const base::GUID& group_id,
+                           const base::GUID& tab_id,
+                           SavedTabGroupTab new_tab);
+
+  // Moves a saved tab from its current position to `index` in the specified
+  // group denoted by `group_id` if it exists.
+  void MoveTabInGroupTo(const base::GUID& group_id,
+                        const base::GUID& tab_id,
+                        int index);
+
+  // Attempts to merge the sync_specific with the local object that holds the
+  // same guid.
+  std::unique_ptr<sync_pb::SavedTabGroupSpecifics> MergeGroup(
+      std::unique_ptr<sync_pb::SavedTabGroupSpecifics> sync_specific);
+  std::unique_ptr<sync_pb::SavedTabGroupSpecifics> MergeTab(
+      std::unique_ptr<sync_pb::SavedTabGroupSpecifics> sync_specific);
+
   // Changes the index of a given tab group by id. The new index provided is the
   // expected index after the group is removed.
   void Reorder(const base::GUID& id, int new_index);
 
+  // Loads the entries (a sync_pb::SavedTabGroupSpecifics can be a group or a
+  // tab) saved locally in the model type store (local storage) and attempts to
+  // reconstruct the model by matching groups with their tabs using their
+  // `group_id`'s. We do this by adding the groups to the model first, then
+  // populating them with their respective tabs. Note: Any tabs that do not have
+  // a matching group, will be lost.
+  void LoadStoredEntries(std::vector<sync_pb::SavedTabGroupSpecifics> entries);
+
   // Functions that should be called when a SavedTabGroup's corresponding
   // TabGroup is closed or opened.
   void OnGroupOpenedInTabStrip(const base::GUID& id,
@@ -82,7 +142,7 @@
 
  private:
   // Implementations of CRUD operations.
-  void RemoveImpl(int index);
+  std::unique_ptr<SavedTabGroup> RemoveImpl(int index);
   void UpdateVisualDataImpl(int index,
                             const tab_groups::TabGroupVisualData* visual_data);
 
diff --git a/components/saved_tab_groups/saved_tab_group_model_observer.h b/components/saved_tab_groups/saved_tab_group_model_observer.h
index 2b8797f83..8afa10a 100644
--- a/components/saved_tab_groups/saved_tab_group_model_observer.h
+++ b/components/saved_tab_groups/saved_tab_group_model_observer.h
@@ -5,7 +5,10 @@
 #ifndef COMPONENTS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_MODEL_OBSERVER_H_
 #define COMPONENTS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_MODEL_OBSERVER_H_
 
+#include "base/guid.h"
 #include "components/saved_tab_groups/saved_tab_group_model.h"
+#include "components/saved_tab_groups/saved_tab_group_tab.h"
+#include "components/tab_groups/tab_group_id.h"
 
 // Serves to notify any SavedTabGroupModel listeners that a change has occurred
 // supply the SavedTabGroup that was changed.
@@ -16,18 +19,29 @@
       delete;
 
   // Called when a saved tab group is added to the backend.
-  virtual void SavedTabGroupAdded(const SavedTabGroup& group, int index) {}
+  virtual void SavedTabGroupAddedLocally(const base::GUID& guid) {}
 
   // Called when a saved tab group will be removed from the backend.
-  virtual void SavedTabGroupRemoved(int index) {}
+  virtual void SavedTabGroupRemovedLocally(const SavedTabGroup* removed_group) {
+  }
 
-  // Called when the title, urls, or color change
-  virtual void SavedTabGroupUpdated(const SavedTabGroup& group, int index) {}
+  // Called when the title, tabs, or color change.
+  virtual void SavedTabGroupUpdatedLocally(const base::GUID& guid) {}
 
-  // Called when the order of saved tab groups in the bookmark bar are changed
-  virtual void SavedTabGroupMoved(const SavedTabGroup& group,
-                                  int old_index,
-                                  int new_index) {}
+  // Called when the order of saved tab groups in the bookmark bar are changed.
+  // TODO(crbug/1372052): Figure out if we can maintain ordering of groups and
+  // tabs in sync.
+  virtual void SavedTabGroupReorderedLocally() {}
+
+  // Called when sync / ModelTypeStore updates data.
+  virtual void SavedTabGroupAddedFromSync(const base::GUID& guid) {}
+
+  // TODO(crbug/1372072): Decide if we want to also remove the tabgroup from the
+  // tabstrip if it is open, or just remove it from sync.
+  virtual void SavedTabGroupRemovedFromSync(
+      const SavedTabGroup* removed_group) {}
+
+  virtual void SavedTabGroupUpdatedFromSync(const base::GUID& guid) {}
 
  protected:
   SavedTabGroupModelObserver() = default;
diff --git a/components/saved_tab_groups/saved_tab_group_model_unittest.cc b/components/saved_tab_groups/saved_tab_group_model_unittest.cc
index 4c619c8..9d52fdf 100644
--- a/components/saved_tab_groups/saved_tab_group_model_unittest.cc
+++ b/components/saved_tab_groups/saved_tab_group_model_unittest.cc
@@ -9,11 +9,15 @@
 #include <string>
 #include <vector>
 
+#include "base/guid.h"
 #include "components/saved_tab_groups/saved_tab_group.h"
 #include "components/saved_tab_groups/saved_tab_group_model_observer.h"
+#include "components/saved_tab_groups/saved_tab_group_tab.h"
+#include "components/sync/protocol/saved_tab_group_specifics.pb.h"
 #include "components/tab_groups/tab_group_color.h"
 #include "components/tab_groups/tab_group_id.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/image/image.h"
 #include "url/gurl.h"
 
@@ -49,31 +53,45 @@
 
   void TearDown() override { saved_tab_group_model_.reset(); }
 
-  void SavedTabGroupAdded(const SavedTabGroup& group, int index) override {
-    retrieved_group_.emplace_back(group);
-    retrieved_index_ = index;
+  void SavedTabGroupAddedLocally(const base::GUID& guid) override {
+    retrieved_group_.emplace_back(*saved_tab_group_model_->Get(guid));
+    retrieved_index_ = saved_tab_group_model_->GetIndexOf(guid).value_or(-1);
   }
 
-  void SavedTabGroupRemoved(int index) override { retrieved_index_ = index; }
-
-  void SavedTabGroupUpdated(const SavedTabGroup& group, int index) override {
-    retrieved_group_.emplace_back(group);
-    retrieved_index_ = index;
+  void SavedTabGroupRemovedLocally(
+      const SavedTabGroup* removed_group) override {
+    retrieved_guid_ = removed_group->saved_guid();
   }
 
-  void SavedTabGroupMoved(const SavedTabGroup& group,
-                          int old_index,
-                          int new_index) override {
-    retrieved_group_.emplace_back(group);
-    retrieved_old_index_ = old_index;
-    retrieved_new_index_ = new_index;
+  void SavedTabGroupUpdatedLocally(const base::GUID& guid) override {
+    retrieved_group_.emplace_back(*saved_tab_group_model_->Get(guid));
+    retrieved_index_ = saved_tab_group_model_->GetIndexOf(guid).value_or(-1);
   }
 
+  void SavedTabGroupAddedFromSync(const base::GUID& guid) override {
+    retrieved_group_.emplace_back(*saved_tab_group_model_->Get(guid));
+    retrieved_index_ = saved_tab_group_model_->GetIndexOf(guid).value_or(-1);
+  }
+
+  void SavedTabGroupRemovedFromSync(
+      const SavedTabGroup* removed_group) override {
+    retrieved_guid_ = removed_group->saved_guid();
+  }
+
+  void SavedTabGroupUpdatedFromSync(const base::GUID& guid) override {
+    retrieved_group_.emplace_back(*saved_tab_group_model_->Get(guid));
+    retrieved_index_ = saved_tab_group_model_->GetIndexOf(guid).value_or(-1);
+  }
+
+  void SavedTabGroupReorderedLocally() override { reordered_called_ = true; }
+
   void ClearSignals() {
     retrieved_group_.clear();
     retrieved_index_ = -1;
     retrieved_old_index_ = -1;
     retrieved_new_index_ = -1;
+    reordered_called_ = false;
+    retrieved_guid_ = base::GUID::GenerateRandomV4();
   }
 
   SavedTabGroupTab CreateSavedTabGroupTab(const std::string& url,
@@ -115,6 +133,8 @@
   int retrieved_index_ = -1;
   int retrieved_old_index_ = -1;
   int retrieved_new_index_ = -1;
+  bool reordered_called_ = false;
+  base::GUID retrieved_guid_ = base::GUID::GenerateRandomV4();
   std::string base_path_ = "file:///c:/tmp/";
 };
 
@@ -151,14 +171,14 @@
         tab_groups::TabGroupColorId::kGreen;
 
     std::vector<SavedTabGroupTab> group_1_tabs = {
-        CreateSavedTabGroupTab("A_Link", u"Only Tab")};
+        CreateSavedTabGroupTab("A_Link", u"Only Tab", id_1_)};
     std::vector<SavedTabGroupTab> group_2_tabs = {
-        CreateSavedTabGroupTab("One_Link", u"One Of Two"),
-        CreateSavedTabGroupTab("Two_Link", u"Second")};
+        CreateSavedTabGroupTab("One_Link", u"One Of Two", id_2_),
+        CreateSavedTabGroupTab("Two_Link", u"Second", id_2_)};
     std::vector<SavedTabGroupTab> group_3_tabs = {
-        CreateSavedTabGroupTab("Athos", u"All For One"),
-        CreateSavedTabGroupTab("Porthos", u"And"),
-        CreateSavedTabGroupTab("Aramis", u"One For All")};
+        CreateSavedTabGroupTab("Athos", u"All For One", id_3_),
+        CreateSavedTabGroupTab("Porthos", u"And", id_3_),
+        CreateSavedTabGroupTab("Aramis", u"One For All", id_3_)};
 
     saved_tab_group_model_->Add(
         CreateSavedTabGroup(title_1, color_1, group_1_tabs, id_1_));
@@ -184,9 +204,9 @@
   }
 
   SavedTabGroupTab CreateSavedTabGroupTab(const std::string& url,
-                                          const std::u16string& title) {
-    SavedTabGroupTab tab(GURL(base_path_ + url),
-                         base::GUID::GenerateRandomV4());
+                                          const std::u16string& title,
+                                          const base::GUID& group_guid) {
+    SavedTabGroupTab tab(GURL(base_path_ + url), group_guid);
     tab.SetTitle(title).SetFavicon(gfx::Image());
     return tab;
   }
@@ -275,9 +295,9 @@
       tab_groups::TabGroupColorId::kBlue;
 
   SavedTabGroupTab tab1 =
-      CreateSavedTabGroupTab("4th group", u"First Tab 4th Group");
+      CreateSavedTabGroupTab("4th group", u"First Tab 4th Group", id_4);
   SavedTabGroupTab tab2 =
-      CreateSavedTabGroupTab("2nd link", u"Second Tab 4th Group");
+      CreateSavedTabGroupTab("2nd link", u"Second Tab 4th Group", id_4);
 
   std::vector<SavedTabGroupTab> group_4_tabs = {tab1, tab2};
   SavedTabGroup group_4(title_4, color_4, group_4_tabs, id_4);
@@ -337,6 +357,115 @@
   saved_tab_group_model_->UpdateVisualData(id_1_, &change_color_visual_data);
   EXPECT_EQ(group->title(), original_title);
   EXPECT_EQ(group->color(), random_color);
+
+  // Update update time
+  base::Time time = base::Time::Now();
+  saved_tab_group_model_->Get(id_1_)->SetUpdateTimeWindowsEpochMicros(time);
+  EXPECT_EQ(
+      time,
+      saved_tab_group_model_->Get(id_1_)->update_time_windows_epoch_micros());
+}
+
+// Tests that the correct tabs are added to the correct position in group 1.
+TEST_F(SavedTabGroupModelTest, AddTabToGroup) {
+  SavedTabGroupTab tab1 =
+      CreateSavedTabGroupTab("4th group", u"First Tab 4th Group", id_1_);
+  SavedTabGroupTab tab2 =
+      CreateSavedTabGroupTab("2nd link", u"Second Tab 4th Group", id_1_);
+
+  SavedTabGroup* group = saved_tab_group_model_->Get(id_1_);
+  ASSERT_EQ(group->saved_tabs().size(), size_t(1));
+
+  saved_tab_group_model_->AddTabToGroup(group->saved_guid(), tab1, 0);
+  EXPECT_EQ(group->saved_tabs().size(), size_t(2));
+  EXPECT_EQ(0, group->GetIndexOfTab(tab1.guid()));
+  EXPECT_TRUE(group->ContainsTab(tab1.guid()));
+  ASSERT_TRUE(group->GetTab(tab1.guid()).has_value());
+  CompareSavedTabGroupTabs({group->GetTab(tab1.guid()).value()}, {tab1});
+
+  saved_tab_group_model_->AddTabToGroup(group->saved_guid(), tab2, 2);
+  EXPECT_EQ(group->saved_tabs().size(), size_t(3));
+  EXPECT_EQ(2, group->GetIndexOfTab(tab2.guid()));
+  EXPECT_TRUE(group->ContainsTab(tab2.guid()));
+  ASSERT_TRUE(group->GetTab(tab2.guid()).has_value());
+  CompareSavedTabGroupTabs({group->GetTab(tab2.guid()).value()}, {tab2});
+  CompareSavedTabGroupTabs(group->saved_tabs(),
+                           {tab1, group->saved_tabs()[1], tab2});
+}
+
+// Tests that the correct tabs are removed from the correct position in group 1.
+TEST_F(SavedTabGroupModelTest, RemoveTabFromGroup) {
+  SavedTabGroupTab tab1 =
+      CreateSavedTabGroupTab("4th group", u"First Tab 4th Group", id_1_);
+  SavedTabGroupTab tab2 =
+      CreateSavedTabGroupTab("2nd link", u"Second Tab 4th Group", id_1_);
+
+  SavedTabGroup* group = saved_tab_group_model_->Get(id_1_);
+  ASSERT_EQ(group->saved_tabs().size(), size_t(1));
+
+  saved_tab_group_model_->AddTabToGroup(group->saved_guid(), tab1, 0);
+  saved_tab_group_model_->AddTabToGroup(group->saved_guid(), tab2, 2);
+  EXPECT_EQ(group->saved_tabs().size(), size_t(3));
+
+  saved_tab_group_model_->RemoveTabFromGroup(group->saved_guid(), tab1.guid());
+  EXPECT_EQ(group->saved_tabs().size(), size_t(2));
+  CompareSavedTabGroupTabs(group->saved_tabs(), {group->saved_tabs()[0], tab2});
+
+  saved_tab_group_model_->RemoveTabFromGroup(group->saved_guid(), tab2.guid());
+  EXPECT_EQ(group->saved_tabs().size(), size_t(1));
+  CompareSavedTabGroupTabs(group->saved_tabs(), {group->saved_tabs()[0]});
+}
+
+// Tests that the correct tabs are replaced in group 1.
+TEST_F(SavedTabGroupModelTest, ReplaceTabInGroup) {
+  SavedTabGroupTab tab1 = CreateSavedTabGroupTab("first", u"First Tab", id_1_);
+  SavedTabGroupTab tab2 =
+      CreateSavedTabGroupTab("second", u"Second Tab", id_1_);
+  SavedTabGroupTab tab3 = CreateSavedTabGroupTab("third", u"Third Tab", id_1_);
+
+  SavedTabGroup* group = saved_tab_group_model_->Get(id_1_);
+  ASSERT_EQ(group->saved_tabs().size(), size_t(1));
+
+  saved_tab_group_model_->AddTabToGroup(group->saved_guid(), tab1, 0);
+  saved_tab_group_model_->AddTabToGroup(group->saved_guid(), tab2, 2);
+  EXPECT_EQ(group->saved_tabs().size(), size_t(3));
+
+  saved_tab_group_model_->ReplaceTabInGroupAt(group->saved_guid(), tab1.guid(),
+                                              tab3);
+  CompareSavedTabGroupTabs(group->saved_tabs(),
+                           {tab3, group->saved_tabs()[1], tab2});
+
+  saved_tab_group_model_->ReplaceTabInGroupAt(group->saved_guid(), tab2.guid(),
+                                              tab1);
+  CompareSavedTabGroupTabs(group->saved_tabs(),
+                           {tab3, group->saved_tabs()[1], tab1});
+
+  saved_tab_group_model_->ReplaceTabInGroupAt(
+      group->saved_guid(), group->saved_tabs()[1].guid(), tab2);
+  CompareSavedTabGroupTabs(group->saved_tabs(), {tab3, tab2, tab1});
+}
+
+// Tests that the correct tabs are moved in group 1.
+TEST_F(SavedTabGroupModelTest, MoveTabInGroup) {
+  SavedTabGroupTab tab1 =
+      CreateSavedTabGroupTab("4th group", u"First Tab 4th Group", id_1_);
+  SavedTabGroupTab tab2 =
+      CreateSavedTabGroupTab("2nd link", u"Second Tab 4th Group", id_1_);
+
+  SavedTabGroup* group = saved_tab_group_model_->Get(id_1_);
+  ASSERT_EQ(group->saved_tabs().size(), size_t(1));
+
+  saved_tab_group_model_->AddTabToGroup(group->saved_guid(), tab1, 0);
+  saved_tab_group_model_->AddTabToGroup(group->saved_guid(), tab2, 2);
+  EXPECT_EQ(group->saved_tabs().size(), size_t(3));
+
+  saved_tab_group_model_->MoveTabInGroupTo(group->saved_guid(), tab1.guid(), 2);
+  CompareSavedTabGroupTabs(group->saved_tabs(),
+                           {group->saved_tabs()[0], tab2, tab1});
+
+  saved_tab_group_model_->MoveTabInGroupTo(group->saved_guid(), tab1.guid(), 1);
+  CompareSavedTabGroupTabs(group->saved_tabs(),
+                           {group->saved_tabs()[0], tab1, tab2});
 }
 
 TEST_F(SavedTabGroupModelTest, MoveElement) {
@@ -347,6 +476,73 @@
   EXPECT_EQ(0, saved_tab_group_model_->GetIndexOf(id_2_));
 }
 
+TEST_F(SavedTabGroupModelTest, LoadStoredEntriesPopulatesModel) {
+  std::unique_ptr<SavedTabGroup> group =
+      std::make_unique<SavedTabGroup>(*saved_tab_group_model_->Get(id_3_));
+
+  std::vector<sync_pb::SavedTabGroupSpecifics> specifics;
+  specifics.emplace_back(*group->ToSpecifics());
+
+  for (SavedTabGroupTab tab : group->saved_tabs())
+    specifics.emplace_back(*tab.ToSpecifics());
+
+  EXPECT_EQ(specifics.size(), size_t(4));
+  saved_tab_group_model_->Remove(id_3_);
+
+  saved_tab_group_model_->LoadStoredEntries(specifics);
+
+  EXPECT_TRUE(saved_tab_group_model_->Contains(id_3_));
+  EXPECT_EQ(saved_tab_group_model_->GetIndexOf(id_3_), 2);
+  EXPECT_EQ(saved_tab_group_model_->Count(), 3);
+
+  const SavedTabGroup* saved_group = saved_tab_group_model_->Get(id_3_);
+  EXPECT_EQ(saved_group->saved_guid(), id_3_);
+  EXPECT_EQ(saved_group->title(), group->title());
+  EXPECT_EQ(saved_group->color(), group->color());
+  // TODO(dljames): Use CompareSavedTabGroupTabs when we can ensure the order of
+  // tabs and groups are maintained.
+  EXPECT_EQ(saved_group->saved_tabs().size(), group->saved_tabs().size());
+}
+
+// Tests that merging a group with the same group_id changes the state of the
+// object correctly.
+TEST_F(SavedTabGroupModelTest, MergeGroupsFromModel) {
+  SavedTabGroup* group1 = saved_tab_group_model_->Get(id_1_);
+  SavedTabGroup group2 = SavedTabGroup::FromSpecifics(*group1->ToSpecifics());
+  group2.SetColor(tab_groups::TabGroupColorId::kPink);
+  group2.SetTitle(u"Updated title");
+  SavedTabGroup merged_group = SavedTabGroup::FromSpecifics(
+      *saved_tab_group_model_->MergeGroup(group2.ToSpecifics()));
+
+  EXPECT_EQ(group1->title(), group2.title());
+  EXPECT_EQ(group1->color(), group2.color());
+  EXPECT_EQ(group1->saved_guid(), group2.saved_guid());
+  EXPECT_EQ(group1->creation_time_windows_epoch_micros(),
+            group2.creation_time_windows_epoch_micros());
+  EXPECT_EQ(group1->update_time_windows_epoch_micros(),
+            group2.update_time_windows_epoch_micros());
+}
+
+// Tests that merging a tab with the same tab_id changes the state of the object
+// correctly.
+TEST_F(SavedTabGroupModelTest, MergeTabsFromModel) {
+  SavedTabGroupTab tab1 = saved_tab_group_model_->Get(id_1_)->saved_tabs()[0];
+  SavedTabGroupTab tab2 = SavedTabGroupTab::FromSpecifics(*tab1.ToSpecifics());
+  tab2.SetTitle(u"Updated Title");
+  tab2.SetURL(GURL("chrome://updated_url"));
+
+  SavedTabGroupTab merged_tab = SavedTabGroupTab::FromSpecifics(
+      *saved_tab_group_model_->MergeTab(tab2.ToSpecifics()));
+
+  EXPECT_EQ(tab1.url(), merged_tab.url());
+  EXPECT_EQ(tab1.guid(), merged_tab.guid());
+  EXPECT_EQ(tab1.group_guid(), merged_tab.group_guid());
+  EXPECT_EQ(tab1.creation_time_windows_epoch_micros(),
+            merged_tab.creation_time_windows_epoch_micros());
+  EXPECT_EQ(tab1.update_time_windows_epoch_micros(),
+            merged_tab.update_time_windows_epoch_micros());
+}
+
 // Tests that SavedTabGroupModelObserver::Added passes the correct element from
 // the model.
 TEST_F(SavedTabGroupModelObserverTest, AddElement) {
@@ -372,21 +568,13 @@
   saved_tab_group_model_->Add(group_4);
   saved_tab_group_model_->Remove(group_4.saved_guid());
 
-  const int index = retrieved_group_.size() - 1;
-  ASSERT_GE(index, 0);
-
-  SavedTabGroup received_group = retrieved_group_[index];
-  EXPECT_EQ(group_4.local_group_id(), received_group.local_group_id());
-  EXPECT_EQ(group_4.title(), received_group.title());
-  EXPECT_EQ(group_4.color(), received_group.color());
-  CompareSavedTabGroupTabs(group_4.saved_tabs(), received_group.saved_tabs());
+  EXPECT_EQ(group_4.saved_guid(), retrieved_guid_);
+  EXPECT_FALSE(saved_tab_group_model_->Contains(retrieved_guid_));
 
   // The model will have already removed and sent the index our element was at
   // before it was removed from the model. As such, we should get -1 when
   // checking the model and 0 for the retrieved index.
-  EXPECT_EQ(saved_tab_group_model_->GetIndexOf(received_group.saved_guid()),
-            -1);
-  EXPECT_EQ(retrieved_index_, 0);
+  EXPECT_EQ(saved_tab_group_model_->GetIndexOf(retrieved_guid_), absl::nullopt);
 }
 
 // Tests that SavedTabGroupModelObserver::Updated passes the correct
@@ -416,6 +604,67 @@
             retrieved_index_);
 }
 
+// Tests that SavedTabGroupModelObserver::AddedFromSync passes the correct
+// element from the model.
+TEST_F(SavedTabGroupModelObserverTest, AddElementFromSync) {
+  SavedTabGroup group_4(CreateTestSavedTabGroup());
+  saved_tab_group_model_->AddedFromSync(group_4);
+
+  const int index = retrieved_group_.size() - 1;
+  ASSERT_GE(index, 0);
+
+  SavedTabGroup received_group = retrieved_group_[index];
+  EXPECT_EQ(group_4.local_group_id(), received_group.local_group_id());
+  EXPECT_EQ(group_4.title(), received_group.title());
+  EXPECT_EQ(group_4.color(), received_group.color());
+  CompareSavedTabGroupTabs(group_4.saved_tabs(), received_group.saved_tabs());
+  EXPECT_EQ(saved_tab_group_model_->GetIndexOf(received_group.saved_guid()),
+            retrieved_index_);
+}
+
+// Tests that SavedTabGroupModelObserver::RemovedFromSync passes the correct
+// element from the model.
+TEST_F(SavedTabGroupModelObserverTest, RemovedElementFromSync) {
+  SavedTabGroup group_4(CreateTestSavedTabGroup());
+  saved_tab_group_model_->Add(group_4);
+  saved_tab_group_model_->RemovedFromSync(group_4.saved_guid());
+
+  EXPECT_EQ(group_4.saved_guid(), retrieved_guid_);
+  EXPECT_FALSE(saved_tab_group_model_->Contains(retrieved_guid_));
+
+  // The model will have already removed and sent the index our element was at
+  // before it was removed from the model. As such, we should get -1 when
+  // checking the model and 0 for the retrieved index.
+  EXPECT_EQ(saved_tab_group_model_->GetIndexOf(retrieved_guid_), absl::nullopt);
+}
+
+// Tests that SavedTabGroupModelObserver::UpdatedFromSync passes the correct
+// element from the model.
+TEST_F(SavedTabGroupModelObserverTest, UpdatedElementFromSync) {
+  SavedTabGroup group_4(CreateTestSavedTabGroup());
+  saved_tab_group_model_->Add(group_4);
+
+  const std::u16string new_title = u"New Title";
+  const tab_groups::TabGroupColorId& new_color =
+      tab_groups::TabGroupColorId::kBlue;
+
+  const tab_groups::TabGroupVisualData new_visual_data(new_title, new_color,
+                                                       /*is_collapsed*/ false);
+  saved_tab_group_model_->UpdatedVisualDataFromSync(group_4.saved_guid(),
+                                                    &new_visual_data);
+
+  const int index = retrieved_group_.size() - 1;
+  ASSERT_GE(index, 0);
+
+  SavedTabGroup received_group = retrieved_group_[index];
+  EXPECT_EQ(group_4.local_group_id(), received_group.local_group_id());
+  EXPECT_EQ(new_title, received_group.title());
+  EXPECT_EQ(new_color, received_group.color());
+  CompareSavedTabGroupTabs(group_4.saved_tabs(), received_group.saved_tabs());
+  EXPECT_EQ(saved_tab_group_model_->GetIndexOf(received_group.saved_guid()),
+            retrieved_index_);
+}
+
 // Verify that SavedTabGroupModel::OnGroupClosedInTabStrip passes the correct
 // index.
 TEST_F(SavedTabGroupModelObserverTest, OnGroupClosedInTabStrip) {
@@ -423,7 +672,8 @@
   tab_groups::TabGroupId tab_group_id = tab_groups::TabGroupId::GenerateNew();
   group_4.SetLocalGroupId(tab_group_id);
   saved_tab_group_model_->Add(group_4);
-  const int index = saved_tab_group_model_->GetIndexOf(group_4.saved_guid());
+  const int index =
+      saved_tab_group_model_->GetIndexOf(group_4.saved_guid()).value();
   ASSERT_GE(index, 0);
 
   // Expect the saved group that calls update is the one that was removed from
@@ -436,7 +686,7 @@
   // a valid index when searched by tab group id, but does return the right
   // index when searched by saved guid.
   saved_tab_group_model_->OnGroupClosedInTabStrip(tab_group_id);
-  EXPECT_EQ(saved_tab_group_model_->GetIndexOf(tab_group_id), -1);
+  EXPECT_EQ(saved_tab_group_model_->GetIndexOf(tab_group_id), absl::nullopt);
   EXPECT_EQ(saved_tab_group_model_->GetIndexOf(group_4.saved_guid()), index);
 }
 
@@ -457,15 +707,8 @@
   saved_tab_group_model_->Add(stg_2);
   saved_tab_group_model_->Add(stg_3);
 
-  ClearSignals();
-
   saved_tab_group_model_->Reorder(stg_2.saved_guid(), 2);
 
-  const int index = retrieved_group_.size() - 1;
-  ASSERT_GE(index, 0);
-
-  SavedTabGroup received_group = retrieved_group_[index];
-  EXPECT_EQ(stg_2.saved_guid(), received_group.saved_guid());
-  EXPECT_EQ(1, retrieved_old_index_);
-  EXPECT_EQ(2, retrieved_new_index_);
+  EXPECT_TRUE(reordered_called_);
+  EXPECT_EQ(2, saved_tab_group_model_->GetIndexOf(stg_2.saved_guid()));
 }
diff --git a/components/services/app_service/public/cpp/icon_types.h b/components/services/app_service/public/cpp/icon_types.h
index 8272e68..0afe0a6 100644
--- a/components/services/app_service/public/cpp/icon_types.h
+++ b/components/services/app_service/public/cpp/icon_types.h
@@ -101,10 +101,6 @@
   // `allow_placeholder_icon` set to true, which states whether the caller will
   // accept a placeholder if the real icon can not be provided at this time.
   bool is_placeholder_icon = false;
-
-  // Whether the icon failed to load and a fallback (e.g. grey box icon) has
-  // been returned instead.
-  bool is_fallback_icon = false;
 };
 
 using IconValuePtr = std::unique_ptr<IconValue>;
diff --git a/components/user_manager/user_image/user_image.h b/components/user_manager/user_image/user_image.h
index e3331cdb..17c9402 100644
--- a/components/user_manager/user_image/user_image.h
+++ b/components/user_manager/user_image/user_image.h
@@ -26,8 +26,6 @@
     FORMAT_JPEG,
     FORMAT_PNG,
     FORMAT_UNKNOWN,
-    // Useful when the image is external and animated.
-    FORMAT_WEBP,
   };
 
   // Encodes the given bitmap to bytes representation in |image_format| for
diff --git a/content/browser/devtools/devtools_session.cc b/content/browser/devtools/devtools_session.cc
index e4b7578..f563c28 100644
--- a/content/browser/devtools/devtools_session.cc
+++ b/content/browser/devtools/devtools_session.cc
@@ -28,9 +28,11 @@
 bool ShouldSendOnIO(crdtp::span<uint8_t> method) {
   static auto* kEntries = new std::vector<crdtp::span<uint8_t>>{
       crdtp::SpanFrom("Debugger.getPossibleBreakpoints"),
+      crdtp::SpanFrom("Debugger.getScriptSource"),
       crdtp::SpanFrom("Debugger.getStackTrace"),
       crdtp::SpanFrom("Debugger.pause"),
       crdtp::SpanFrom("Debugger.removeBreakpoint"),
+      crdtp::SpanFrom("Debugger.resume"),
       crdtp::SpanFrom("Debugger.setBreakpoint"),
       crdtp::SpanFrom("Debugger.setBreakpointByUrl"),
       crdtp::SpanFrom("Debugger.setBreakpointsActive"),
diff --git a/content/browser/fenced_frame/fenced_frame_browsertest.cc b/content/browser/fenced_frame/fenced_frame_browsertest.cc
index cfa4dbb..70044c1 100644
--- a/content/browser/fenced_frame/fenced_frame_browsertest.cc
+++ b/content/browser/fenced_frame/fenced_frame_browsertest.cc
@@ -1993,7 +1993,7 @@
       net::Error expected_net_error_code = net::OK) {
     RenderFrameHostImpl* rfh =
         static_cast<RenderFrameHostImpl*>(adapter.render_frame_host());
-    EXPECT_TRUE(rfh->frame_tree_node()->IsInFencedFrameTree());
+    EXPECT_TRUE(rfh->IsNestedWithinFencedFrame());
     RenderFrameHostImpl* target_rfh = rfh->GetParentOrOuterDocument();
     ExecuteNavigationOrHistoryScriptInFencedFrameTree(
         target_rfh, rfh, navigate_script, expected_net_error_code);
@@ -2004,7 +2004,7 @@
       const std::string& history_script) {
     RenderFrameHostImpl* rfh =
         static_cast<RenderFrameHostImpl*>(adapter.render_frame_host());
-    EXPECT_TRUE(rfh->frame_tree_node()->IsInFencedFrameTree());
+    EXPECT_TRUE(rfh->IsNestedWithinFencedFrame());
 
     ExecuteNavigationOrHistoryScriptInFencedFrameTree(rfh, rfh, history_script);
   }
diff --git a/content/browser/file_system_access/fake_file_system_access_permission_context.cc b/content/browser/file_system_access/fake_file_system_access_permission_context.cc
index 2ebe937..590cf12 100644
--- a/content/browser/file_system_access/fake_file_system_access_permission_context.cc
+++ b/content/browser/file_system_access/fake_file_system_access_permission_context.cc
@@ -40,7 +40,7 @@
     PathType path_type,
     const base::FilePath& path,
     HandleType handle_type,
-    ui::SelectFileDialog::Type dialog_type,
+    UserAction user_action,
     GlobalRenderFrameHostId frame_id,
     base::OnceCallback<void(SensitiveEntryResult)> callback) {
   std::move(callback).Run(SensitiveEntryResult::kAllowed);
diff --git a/content/browser/file_system_access/fake_file_system_access_permission_context.h b/content/browser/file_system_access/fake_file_system_access_permission_context.h
index 235507d..ea5f12c5 100644
--- a/content/browser/file_system_access/fake_file_system_access_permission_context.h
+++ b/content/browser/file_system_access/fake_file_system_access_permission_context.h
@@ -7,7 +7,6 @@
 #include "base/files/file_path.h"
 #include "content/public/browser/file_system_access_permission_context.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_manager.mojom-shared.h"
-#include "ui/shell_dialogs/select_file_dialog.h"
 
 #ifndef CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FAKE_FILE_SYSTEM_ACCESS_PERMISSION_CONTEXT_H_
 #define CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FAKE_FILE_SYSTEM_ACCESS_PERMISSION_CONTEXT_H_
@@ -43,7 +42,7 @@
       PathType path_type,
       const base::FilePath& path,
       HandleType handle_type,
-      ui::SelectFileDialog::Type dialog_type,
+      UserAction user_action,
       GlobalRenderFrameHostId frame_id,
       base::OnceCallback<void(SensitiveEntryResult)> callback) override;
 
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.cc b/content/browser/file_system_access/file_system_access_manager_impl.cc
index e727578..7d22621 100644
--- a/content/browser/file_system_access/file_system_access_manager_impl.cc
+++ b/content/browser/file_system_access/file_system_access_manager_impl.cc
@@ -689,17 +689,12 @@
       url.type() == storage::FileSystemType::kFileSystemTypeLocal
           ? PathType::kLocal
           : PathType::kExternal;
-  // TODO(https://crbug.com/1370433): Update ConfirmSensitiveEntryAccess() to
-  // take a UserAction and show a prompt specific to D&D accordingly. For now,
-  // run the same security checks and show the same prompt for D&D as for the
-  // file picker.
-  ui::SelectFileDialog::Type dialog_type =
-      file_type == HandleType::kFile
-          ? ui::SelectFileDialog::Type::SELECT_OPEN_FILE
-          : ui::SelectFileDialog::Type::SELECT_UPLOAD_FOLDER;
+  // TODO(https://crbug.com/1370433): Add a prompt specific to D&D. For now, run
+  // the same security checks and show the same prompt for D&D as for the file
+  // picker.
   permission_context_->ConfirmSensitiveEntryAccess(
       binding_context.storage_key.origin(), path_type, file_path, file_type,
-      dialog_type, binding_context.frame_id,
+      UserAction::kDragAndDrop, binding_context.frame_id,
       base::BindOnce(&FileSystemAccessManagerImpl::
                          DidVerifySensitiveDirectoryAccessForDataTransfer,
                      weak_factory_.GetWeakPtr(), binding_context, file_path,
@@ -1297,7 +1292,10 @@
       options.type() == ui::SelectFileDialog::SELECT_FOLDER;
   permission_context_->ConfirmSensitiveEntryAccess(
       binding_context.storage_key.origin(), first_entry.type, first_entry.path,
-      is_directory ? HandleType::kDirectory : HandleType::kFile, options.type(),
+      is_directory ? HandleType::kDirectory : HandleType::kFile,
+      options.type() == ui::SelectFileDialog::SELECT_SAVEAS_FILE
+          ? UserAction::kSave
+          : UserAction::kOpen,
       binding_context.frame_id,
       base::BindOnce(
           &FileSystemAccessManagerImpl::DidVerifySensitiveDirectoryAccess,
diff --git a/content/browser/file_system_access/file_system_access_manager_impl_unittest.cc b/content/browser/file_system_access/file_system_access_manager_impl_unittest.cc
index bafc0c2..3a637514 100644
--- a/content/browser/file_system_access/file_system_access_manager_impl_unittest.cc
+++ b/content/browser/file_system_access/file_system_access_manager_impl_unittest.cc
@@ -253,7 +253,8 @@
             kTestStorageKey.origin(),
             FileSystemAccessPermissionContext::PathType::kLocal, file_path,
             FileSystemAccessPermissionContext::HandleType::kFile,
-            ui::SelectFileDialog::Type::SELECT_OPEN_FILE, kFrameId, testing::_))
+            FileSystemAccessPermissionContext::UserAction::kDragAndDrop,
+            kFrameId, testing::_))
         .WillOnce(RunOnceCallback<6>(
             FileSystemAccessPermissionContext::SensitiveEntryResult::kAllowed));
 
@@ -310,8 +311,8 @@
             kTestStorageKey.origin(),
             FileSystemAccessPermissionContext::PathType::kLocal, dir_path,
             FileSystemAccessPermissionContext::HandleType::kDirectory,
-            ui::SelectFileDialog::Type::SELECT_UPLOAD_FOLDER, kFrameId,
-            testing::_))
+            FileSystemAccessPermissionContext::UserAction::kDragAndDrop,
+            kFrameId, testing::_))
         .WillOnce(RunOnceCallback<6>(
             FileSystemAccessPermissionContext::SensitiveEntryResult::kAllowed));
 
@@ -1300,7 +1301,8 @@
           kTestStorageKey.origin(),
           FileSystemAccessPermissionContext::PathType::kLocal, file_path,
           FileSystemAccessPermissionContext::HandleType::kFile,
-          ui::SelectFileDialog::Type::SELECT_OPEN_FILE, kFrameId, testing::_))
+          FileSystemAccessPermissionContext::UserAction::kDragAndDrop, kFrameId,
+          testing::_))
       .WillOnce(RunOnceCallback<6>(
           FileSystemAccessPermissionContext::SensitiveEntryResult::kAbort));
 
@@ -1333,8 +1335,8 @@
                   kTestStorageKey.origin(),
                   FileSystemAccessPermissionContext::PathType::kLocal, kDirPath,
                   FileSystemAccessPermissionContext::HandleType::kDirectory,
-                  ui::SelectFileDialog::Type::SELECT_UPLOAD_FOLDER, kFrameId,
-                  testing::_))
+                  FileSystemAccessPermissionContext::UserAction::kDragAndDrop,
+                  kFrameId, testing::_))
       .WillOnce(RunOnceCallback<6>(
           FileSystemAccessPermissionContext::SensitiveEntryResult::kAbort));
 
@@ -1421,7 +1423,7 @@
           kTestStorageKey.origin(),
           FileSystemAccessPermissionContext::PathType::kLocal, test_file,
           FileSystemAccessPermissionContext::HandleType::kFile,
-          ui::SelectFileDialog::Type::SELECT_OPEN_FILE,
+          FileSystemAccessPermissionContext::UserAction::kOpen,
           web_contents_->GetPrimaryMainFrame()->GetGlobalId(), testing::_))
       .WillOnce(RunOnceCallback<6>(
           FileSystemAccessPermissionContext::SensitiveEntryResult::kAllowed));
@@ -1508,7 +1510,7 @@
           kTestStorageKey.origin(),
           FileSystemAccessPermissionContext::PathType::kLocal, test_file,
           FileSystemAccessPermissionContext::HandleType::kFile,
-          ui::SelectFileDialog::Type::SELECT_SAVEAS_FILE,
+          FileSystemAccessPermissionContext::UserAction::kSave,
           web_contents_->GetPrimaryMainFrame()->GetGlobalId(), testing::_))
       .WillOnce(RunOnceCallback<6>(
           FileSystemAccessPermissionContext::SensitiveEntryResult::kAllowed));
@@ -1591,7 +1593,7 @@
           kTestStorageKey.origin(),
           FileSystemAccessPermissionContext::PathType::kLocal, test_dir,
           FileSystemAccessPermissionContext::HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER,
+          FileSystemAccessPermissionContext::UserAction::kOpen,
           web_contents_->GetPrimaryMainFrame()->GetGlobalId(), testing::_))
       .WillOnce(RunOnceCallback<6>(
           FileSystemAccessPermissionContext::SensitiveEntryResult::kAllowed));
diff --git a/content/browser/file_system_access/file_system_chooser_browsertest.cc b/content/browser/file_system_access/file_system_chooser_browsertest.cc
index 9cc7d4d..bd9d7c0 100644
--- a/content/browser/file_system_access/file_system_chooser_browsertest.cc
+++ b/content/browser/file_system_access/file_system_chooser_browsertest.cc
@@ -509,12 +509,12 @@
               SetLastPickedDirectory(origin, std::string(), test_dir,
                                      PathType::kLocal));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_dir,
-          FileSystemAccessPermissionContext::HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_dir,
+                  FileSystemAccessPermissionContext::HandleType::kDirectory,
+                  FileSystemAccessPermissionContext::UserAction::kOpen,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAllowed));
 
   EXPECT_CALL(permission_context,
@@ -590,12 +590,12 @@
               SetLastPickedDirectory(origin, std::string(), test_dir,
                                      PathType::kLocal));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_dir,
-          FileSystemAccessPermissionContext::HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_dir,
+                  FileSystemAccessPermissionContext::HandleType::kDirectory,
+                  FileSystemAccessPermissionContext::UserAction::kOpen,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAllowed));
 
   EXPECT_CALL(permission_context,
@@ -678,12 +678,12 @@
               SetLastPickedDirectory(origin, std::string(), test_dir,
                                      PathType::kLocal));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_dir,
-          FileSystemAccessPermissionContext::HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_dir,
+                  FileSystemAccessPermissionContext::HandleType::kDirectory,
+                  FileSystemAccessPermissionContext::UserAction::kOpen,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAllowed));
 
   EXPECT_CALL(permission_context,
@@ -771,12 +771,12 @@
   EXPECT_CALL(permission_context, GetPickerTitle(testing::_))
       .WillOnce(testing::Return(std::u16string()));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_file,
-          FileSystemAccessPermissionContext::HandleType::kFile,
-          ui::SelectFileDialog::Type::SELECT_SAVEAS_FILE, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_file,
+                  FileSystemAccessPermissionContext::HandleType::kFile,
+                  FileSystemAccessPermissionContext::UserAction::kSave,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAbort));
 
   ASSERT_TRUE(
@@ -837,12 +837,12 @@
   EXPECT_CALL(permission_context, GetPickerTitle(testing::_))
       .WillOnce(testing::Return(std::u16string()));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_file,
-          FileSystemAccessPermissionContext::HandleType::kFile,
-          ui::SelectFileDialog::Type::SELECT_SAVEAS_FILE, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_file,
+                  FileSystemAccessPermissionContext::HandleType::kFile,
+                  FileSystemAccessPermissionContext::UserAction::kSave,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAbort));
 
   ASSERT_TRUE(
@@ -977,12 +977,12 @@
               SetLastPickedDirectory(origin, std::string(), test_dir,
                                      PathType::kLocal));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_dir,
-          FileSystemAccessPermissionContext::HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_dir,
+                  FileSystemAccessPermissionContext::HandleType::kDirectory,
+                  FileSystemAccessPermissionContext::UserAction::kOpen,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAllowed));
 
   EXPECT_CALL(permission_context,
@@ -1070,12 +1070,12 @@
               SetLastPickedDirectory(origin, std::string(), test_dir,
                                      PathType::kLocal));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_dir,
-          FileSystemAccessPermissionContext::HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_dir,
+                  FileSystemAccessPermissionContext::HandleType::kDirectory,
+                  FileSystemAccessPermissionContext::UserAction::kOpen,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAllowed));
 
   EXPECT_CALL(permission_context,
@@ -1157,12 +1157,12 @@
               SetLastPickedDirectory(origin, std::string(), test_dir,
                                      PathType::kLocal));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_dir,
-          FileSystemAccessPermissionContext::HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_dir,
+                  FileSystemAccessPermissionContext::HandleType::kDirectory,
+                  FileSystemAccessPermissionContext::UserAction::kOpen,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAllowed));
 
   EXPECT_CALL(permission_context,
@@ -1252,12 +1252,12 @@
               SetLastPickedDirectory(origin, std::string(), test_dir,
                                      PathType::kLocal));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_dir,
-          FileSystemAccessPermissionContext::HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_dir,
+                  FileSystemAccessPermissionContext::HandleType::kDirectory,
+                  FileSystemAccessPermissionContext::UserAction::kOpen,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAllowed));
 
   EXPECT_CALL(permission_context,
@@ -1346,12 +1346,12 @@
               SetLastPickedDirectory(origin, std::string(), test_dir,
                                      PathType::kLocal));
 
-  EXPECT_CALL(
-      permission_context,
-      ConfirmSensitiveEntryAccess_(
-          origin, PathType::kLocal, test_dir,
-          FileSystemAccessPermissionContext::HandleType::kDirectory,
-          ui::SelectFileDialog::Type::SELECT_FOLDER, frame_id, testing::_))
+  EXPECT_CALL(permission_context,
+              ConfirmSensitiveEntryAccess_(
+                  origin, PathType::kLocal, test_dir,
+                  FileSystemAccessPermissionContext::HandleType::kDirectory,
+                  FileSystemAccessPermissionContext::UserAction::kOpen,
+                  frame_id, testing::_))
       .WillOnce(RunOnceCallback<6>(SensitiveEntryResult::kAllowed));
 
   EXPECT_CALL(permission_context,
diff --git a/content/browser/file_system_access/mock_file_system_access_permission_context.cc b/content/browser/file_system_access/mock_file_system_access_permission_context.cc
index 60d383e2..bbf08ec 100644
--- a/content/browser/file_system_access/mock_file_system_access_permission_context.cc
+++ b/content/browser/file_system_access/mock_file_system_access_permission_context.cc
@@ -16,11 +16,11 @@
     PathType path_type,
     const base::FilePath& path,
     HandleType handle_type,
-    ui::SelectFileDialog::Type dialog_type,
+    UserAction user_action,
     GlobalRenderFrameHostId frame_id,
     base::OnceCallback<void(SensitiveEntryResult)> callback) {
   ConfirmSensitiveEntryAccess_(origin, path_type, path, handle_type,
-                               dialog_type, frame_id, callback);
+                               user_action, frame_id, callback);
 }
 
 void MockFileSystemAccessPermissionContext::PerformAfterWriteChecks(
diff --git a/content/browser/file_system_access/mock_file_system_access_permission_context.h b/content/browser/file_system_access/mock_file_system_access_permission_context.h
index c96407a3..ef203bc 100644
--- a/content/browser/file_system_access/mock_file_system_access_permission_context.h
+++ b/content/browser/file_system_access/mock_file_system_access_permission_context.h
@@ -41,7 +41,7 @@
       PathType path_type,
       const base::FilePath& path,
       HandleType handle_type,
-      ui::SelectFileDialog::Type dialog_type,
+      UserAction user_action,
       GlobalRenderFrameHostId frame_id,
       base::OnceCallback<void(SensitiveEntryResult)> callback) override;
   MOCK_METHOD(void,
@@ -50,7 +50,7 @@
                PathType path_type,
                const base::FilePath& path,
                HandleType handle_type,
-               ui::SelectFileDialog::Type dialog_type,
+               UserAction user_action,
                GlobalRenderFrameHostId frame_id,
                base::OnceCallback<void(SensitiveEntryResult)>& callback));
 
diff --git a/content/browser/notifications/blink_notification_service_impl.cc b/content/browser/notifications/blink_notification_service_impl.cc
index a84465f..f66c863 100644
--- a/content/browser/notifications/blink_notification_service_impl.cc
+++ b/content/browser/notifications/blink_notification_service_impl.cc
@@ -149,7 +149,7 @@
   NotificationEventDispatcherImpl* event_dispatcher =
       NotificationEventDispatcherImpl::GetInstance();
   event_dispatcher->RegisterNonPersistentNotificationListener(
-      notification_id, std::move(event_listener_remote));
+      notification_id, std::move(event_listener_remote), weak_document_ptr_);
 
   browser_context_->GetPlatformNotificationService()->DisplayNotification(
       notification_id, origin_.GetURL(), document_url_,
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.cc b/content/browser/notifications/notification_event_dispatcher_impl.cc
index 84c7bdbe1..485407b 100644
--- a/content/browser/notifications/notification_event_dispatcher_impl.cc
+++ b/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -18,6 +18,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/storage_partition.h"
+#include "content/public/browser/weak_document_ptr.h"
 #include "content/public/common/persistent_notification_status.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/notifications/platform_notification_data.h"
@@ -413,6 +414,52 @@
 NotificationEventDispatcherImpl::NotificationEventDispatcherImpl() = default;
 NotificationEventDispatcherImpl::~NotificationEventDispatcherImpl() = default;
 
+NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo::
+    NonPersistentNotificationListenerInfo(
+        mojo::Remote<blink::mojom::NonPersistentNotificationListener> remote,
+        WeakDocumentPtr document)
+    : remote(std::move(remote)), document(document) {}
+
+NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo::
+    NonPersistentNotificationListenerInfo(
+        NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo&&
+            info) = default;
+
+NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo::
+    ~NonPersistentNotificationListenerInfo() = default;
+
+bool NotificationEventDispatcherImpl::
+    ShouldDispatchNonPersistentNotificationEvent(
+        const std::string& notification_id) {
+  auto listener = non_persistent_notification_listeners_.find(notification_id);
+
+  // If there is no listener registered for this notification id, no event
+  // should be dispatched.
+  if (listener == non_persistent_notification_listeners_.end()) {
+    return false;
+  }
+
+  if (RenderFrameHost* rfh =
+          listener->second.document.AsRenderFrameHostIfValid()) {
+    // If the associated document is currently in back/forward cache, the
+    // function
+    // returns false to prevent the listener from being triggered.
+    // TODO: in the future, this could be improved to cover more lifecycle
+    // state. see: https://crrev.com/c/3861889/comment/e1759c1e_4dd15e4e/
+    return !rfh->IsInLifecycleState(
+        RenderFrameHost::LifecycleState::kInBackForwardCache);
+  }
+
+  // TODO(https://crbug.com/1350944): if the rfh is not set, there are two
+  // possible cases: it's possible that the notification service is registered
+  // from a shared/service worker, or the original page is gone and the
+  // disconnect handler does not complete yet. We can't set this to false
+  // since it will break the notification that's created from a shared/service
+  // worker. A better support will be added in another CL
+  // (https://crrev.com/c/3876770).
+  return true;
+}
+
 void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
     BrowserContext* browser_context,
     const std::string& notification_id,
@@ -454,7 +501,8 @@
 void NotificationEventDispatcherImpl::RegisterNonPersistentNotificationListener(
     const std::string& notification_id,
     mojo::PendingRemote<blink::mojom::NonPersistentNotificationListener>
-        event_listener_remote) {
+        event_listener_remote,
+    const WeakDocumentPtr& event_document_ptr) {
   mojo::Remote<blink::mojom::NonPersistentNotificationListener> bound_remote(
       std::move(event_listener_remote));
 
@@ -466,54 +514,61 @@
           HandleConnectionErrorForNonPersistentNotificationListener,
       base::Unretained(this), notification_id));
 
+  // Dispatch the close event for any previously displayed notification with
+  // the same notification id. This happens whenever a non-persistent
+  // notification is replaced (by creating another with the same tag), since
+  // from the JavaScript point of view there will be two notification objects,
+  // and the old one needs to receive a close event before the new one
+  // receives a show event.
+  DispatchNonPersistentCloseEvent(notification_id, base::DoNothing());
+
   if (non_persistent_notification_listeners_.count(notification_id)) {
-    // Dispatch the close event for any previously displayed notification with
-    // the same notification id. This happens whenever a non-persistent
-    // notification is replaced (by creating another with the same tag), since
-    // from the JavaScript point of view there will be two notification objects,
-    // and the old one needs to receive a close event before the new one
-    // receives a show event.
-    non_persistent_notification_listeners_[notification_id]->OnClose(
-        base::DoNothing());
     non_persistent_notification_listeners_.erase(notification_id);
   }
-
-  non_persistent_notification_listeners_.insert(
-      {notification_id, std::move(bound_remote)});
+  non_persistent_notification_listeners_.emplace(
+      std::piecewise_construct, std::forward_as_tuple(notification_id),
+      std::forward_as_tuple(std::move(bound_remote), event_document_ptr));
 }
 
+// Only fire the notification listeners (including show, click and
+// close) when it exists in the map and the document is currently
+// not in back/forward cache.
+// See https://crbug.com/1350944
 void NotificationEventDispatcherImpl::DispatchNonPersistentShowEvent(
     const std::string& notification_id) {
-  if (!non_persistent_notification_listeners_.count(notification_id))
-    return;
-  non_persistent_notification_listeners_[notification_id]->OnShow();
+  if (ShouldDispatchNonPersistentNotificationEvent(notification_id)) {
+    auto listener =
+        non_persistent_notification_listeners_.find(notification_id);
+    listener->second.remote->OnShow();
+  }
 }
 
 void NotificationEventDispatcherImpl::DispatchNonPersistentClickEvent(
     const std::string& notification_id,
     NotificationClickEventCallback callback) {
-  if (!non_persistent_notification_listeners_.count(notification_id)) {
+  if (ShouldDispatchNonPersistentNotificationEvent(notification_id)) {
+    auto listener =
+        non_persistent_notification_listeners_.find(notification_id);
+    listener->second.remote->OnClick(
+        base::BindOnce(std::move(callback), true /* success */));
+  } else {
     std::move(callback).Run(false /* success */);
-    return;
   }
-
-  non_persistent_notification_listeners_[notification_id]->OnClick(
-      base::BindOnce(std::move(callback), true /* success */));
 }
 
 void NotificationEventDispatcherImpl::DispatchNonPersistentCloseEvent(
     const std::string& notification_id,
     base::OnceClosure completed_closure) {
-  if (!non_persistent_notification_listeners_.count(notification_id)) {
+  if (ShouldDispatchNonPersistentNotificationEvent(notification_id)) {
+    // Listeners get freed together with `this`, thus the Unretained is safe.
+    auto listener =
+        non_persistent_notification_listeners_.find(notification_id);
+    listener->second.remote->OnClose(base::BindOnce(
+        &NotificationEventDispatcherImpl::OnNonPersistentCloseComplete,
+        base::Unretained(this), notification_id, std::move(completed_closure)));
+  } else {
     std::move(completed_closure).Run();
-    return;
   }
-  // Listeners get freed together with |this|, thus the Unretained is safe.
-  non_persistent_notification_listeners_[notification_id]->OnClose(
-      base::BindOnce(
-          &NotificationEventDispatcherImpl::OnNonPersistentCloseComplete,
-          base::Unretained(this), notification_id,
-          std::move(completed_closure)));
 }
 
 void NotificationEventDispatcherImpl::OnNonPersistentCloseComplete(
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.h b/content/browser/notifications/notification_event_dispatcher_impl.h
index ca331bc..920132c 100644
--- a/content/browser/notifications/notification_event_dispatcher_impl.h
+++ b/content/browser/notifications/notification_event_dispatcher_impl.h
@@ -14,6 +14,7 @@
 #include "content/common/content_export.h"
 #include "content/public/browser/notification_database_data.h"
 #include "content/public/browser/notification_event_dispatcher.h"
+#include "content/public/browser/weak_document_ptr.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/blink/public/mojom/notifications/notification_service.mojom.h"
@@ -55,20 +56,49 @@
       const std::string& notification_id,
       base::OnceClosure completed_closure) override;
 
-  // Registers |listener| to receive the show, click and close events of the
-  // non-persistent notification identified by |notification_id|.
+  // Registers the associated document weak pointer and the listener to receive
+  // the show, click and close events of the non-persistent notification
+  // identified by `notification_id`. For more information about the
+  // `event_document_ptr`, see the comments of `weak_document_ptr_` property in
+  // `BlinkNotificationServiceImpl`.
   void RegisterNonPersistentNotificationListener(
       const std::string& notification_id,
       mojo::PendingRemote<blink::mojom::NonPersistentNotificationListener>
-          event_listener_remote);
+          event_listener_remote,
+      const WeakDocumentPtr& event_document_ptr);
 
  private:
+  struct NonPersistentNotificationListenerInfo {
+    NonPersistentNotificationListenerInfo(
+        mojo::Remote<blink::mojom::NonPersistentNotificationListener> remote,
+        WeakDocumentPtr document);
+    NonPersistentNotificationListenerInfo(
+        NonPersistentNotificationListenerInfo&&);
+    NonPersistentNotificationListenerInfo(
+        const NonPersistentNotificationListenerInfo&) = delete;
+    NonPersistentNotificationListenerInfo& operator=(
+        const NonPersistentNotificationListenerInfo&) = delete;
+    ~NonPersistentNotificationListenerInfo();
+
+    mojo::Remote<blink::mojom::NonPersistentNotificationListener> remote;
+    // This is used to determine if the associated document that registers the
+    // listeners is in back/forward cache when the event is dispatched.
+    WeakDocumentPtr document;
+  };
+
   friend class NotificationEventDispatcherImplTest;
   friend struct base::DefaultSingletonTraits<NotificationEventDispatcherImpl>;
 
   NotificationEventDispatcherImpl();
   ~NotificationEventDispatcherImpl() override;
 
+  // Checks if the event listener for the `notification_id` should be fired.
+  // It returns false if:
+  // 1. The event listener is not found from the map, or
+  // 2. The document is currently in back/forward cache.
+  bool ShouldDispatchNonPersistentNotificationEvent(
+      const std::string& notification_id);
+
   // Removes all references to the listener registered to receive events
   // from the non-persistent notification identified by |notification_id|,
   // and executes |completed_closure|. This method is called after OnClose has
@@ -82,9 +112,8 @@
   void HandleConnectionErrorForNonPersistentNotificationListener(
       const std::string& notification_id);
 
-  // Notification Id -> listener.
-  std::map<std::string,
-           mojo::Remote<blink::mojom::NonPersistentNotificationListener>>
+  // Mapping between the notification id and the event listener.
+  std::map<std::string, NonPersistentNotificationListenerInfo>
       non_persistent_notification_listeners_;
 };
 
diff --git a/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc b/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc
index 3b36eec..4b345dc0 100644
--- a/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc
+++ b/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc
@@ -14,6 +14,8 @@
 #include "base/test/task_environment.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "content/browser/renderer_host/render_frame_host_impl.h"
+#include "content/public/test/test_renderer_host.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -77,7 +79,7 @@
 
 }  // anonymous namespace
 
-class NotificationEventDispatcherImplTest : public ::testing::Test {
+class NotificationEventDispatcherImplTest : public RenderViewHostTestHarness {
  public:
   NotificationEventDispatcherImplTest()
       : dispatcher_(new NotificationEventDispatcherImpl()) {}
@@ -90,11 +92,9 @@
   ~NotificationEventDispatcherImplTest() override { delete dispatcher_; }
 
   // Waits until the task runner managing the Mojo connection has finished.
-  void WaitForMojoTasksToComplete() { task_environment_.RunUntilIdle(); }
+  void WaitForMojoTasksToComplete() { task_environment()->RunUntilIdle(); }
 
  protected:
-  base::test::TaskEnvironment task_environment_;
-
   // Using a raw pointer because NotificationEventDispatcherImpl is a singleton
   // with private constructor and destructor, so unique_ptr is not an option.
   raw_ptr<NotificationEventDispatcherImpl> dispatcher_;
@@ -103,11 +103,13 @@
 TEST_F(NotificationEventDispatcherImplTest,
        DispatchNonPersistentShowEvent_NotifiesCorrectRegisteredListener) {
   auto listener = std::make_unique<TestNotificationListener>();
-  dispatcher_->RegisterNonPersistentNotificationListener(kPrimaryUniqueId,
-                                                         listener->GetRemote());
+  dispatcher_->RegisterNonPersistentNotificationListener(
+      kPrimaryUniqueId, listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
   auto other_listener = std::make_unique<TestNotificationListener>();
   dispatcher_->RegisterNonPersistentNotificationListener(
-      kSomeOtherUniqueId, other_listener->GetRemote());
+      kSomeOtherUniqueId, other_listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
 
@@ -125,10 +127,91 @@
 }
 
 TEST_F(NotificationEventDispatcherImplTest,
+       DispatchNonPersistentEvent_DocumentInBFCache) {
+  auto listener = std::make_unique<TestNotificationListener>();
+  const WeakDocumentPtr document = main_rfh()->GetWeakDocumentPtr();
+  RenderFrameHostImpl* rfh =
+      static_cast<RenderFrameHostImpl*>(document.AsRenderFrameHostIfValid());
+  EXPECT_TRUE(rfh);
+  // The rfh should be initially in active lifecycle state.
+  EXPECT_TRUE(
+      rfh->IsInLifecycleState(RenderFrameHost::LifecycleState::kActive));
+  dispatcher_->RegisterNonPersistentNotificationListener(
+      kPrimaryUniqueId, listener->GetRemote(), document);
+
+  dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
+
+  WaitForMojoTasksToComplete();
+
+  // After dispatching the show and click events when the rfh is active,
+  // the counter should increment as expected.
+  EXPECT_EQ(listener->on_show_count(), 1);
+  EXPECT_EQ(listener->on_click_count(), 0);
+  EXPECT_EQ(listener->on_close_count(), 0);
+
+  dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
+                                               base::DoNothing());
+
+  WaitForMojoTasksToComplete();
+
+  EXPECT_EQ(listener->on_show_count(), 1);
+  EXPECT_EQ(listener->on_click_count(), 1);
+  EXPECT_EQ(listener->on_close_count(), 0);
+
+  dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
+
+  WaitForMojoTasksToComplete();
+
+  EXPECT_EQ(listener->on_show_count(), 2);
+  EXPECT_EQ(listener->on_click_count(), 1);
+  EXPECT_EQ(listener->on_close_count(), 0);
+
+  // Simulate the scenario where the rfh is put into the back/forward cache
+  // by setting the lifecycle state explicitly.
+  rfh->SetLifecycleState(
+      RenderFrameHostImpl::LifecycleStateImpl::kInBackForwardCache);
+  EXPECT_TRUE(rfh->IsInLifecycleState(
+      RenderFrameHost::LifecycleState::kInBackForwardCache));
+
+  dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
+                                               base::DoNothing());
+
+  WaitForMojoTasksToComplete();
+
+  dispatcher_->DispatchNonPersistentCloseEvent(kPrimaryUniqueId,
+                                               base::DoNothing());
+
+  WaitForMojoTasksToComplete();
+
+  // Now the dispatched click and close events should not invoke the listener.
+  EXPECT_EQ(listener->on_show_count(), 2);
+  EXPECT_EQ(listener->on_click_count(), 1);
+  EXPECT_EQ(listener->on_close_count(), 0);
+
+  // Simulate the scenario where the rfh is back to active state and
+  // dispatch a close event.
+  rfh->SetLifecycleState(RenderFrameHostImpl::LifecycleStateImpl::kActive);
+  EXPECT_FALSE(rfh->IsInLifecycleState(
+      RenderFrameHost::LifecycleState::kInBackForwardCache));
+
+  dispatcher_->DispatchNonPersistentCloseEvent(kPrimaryUniqueId,
+                                               base::DoNothing());
+
+  WaitForMojoTasksToComplete();
+
+  // Since the rfh is active, the dispatched close event should result in
+  // the increment of the close counter.
+  EXPECT_EQ(listener->on_show_count(), 2);
+  EXPECT_EQ(listener->on_click_count(), 1);
+  EXPECT_EQ(listener->on_close_count(), 1);
+}
+
+TEST_F(NotificationEventDispatcherImplTest,
        RegisterNonPersistentListener_FirstListenerGetsOnClose) {
   auto original_listener = std::make_unique<TestNotificationListener>();
   dispatcher_->RegisterNonPersistentNotificationListener(
-      kPrimaryUniqueId, original_listener->GetRemote());
+      kPrimaryUniqueId, original_listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
 
@@ -136,7 +219,8 @@
 
   auto replacement_listener = std::make_unique<TestNotificationListener>();
   dispatcher_->RegisterNonPersistentNotificationListener(
-      kPrimaryUniqueId, replacement_listener->GetRemote());
+      kPrimaryUniqueId, replacement_listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   WaitForMojoTasksToComplete();
 
@@ -148,7 +232,8 @@
        RegisterNonPersistentListener_SecondListenerGetsOnShow) {
   auto original_listener = std::make_unique<TestNotificationListener>();
   dispatcher_->RegisterNonPersistentNotificationListener(
-      kPrimaryUniqueId, original_listener->GetRemote());
+      kPrimaryUniqueId, original_listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
 
@@ -158,7 +243,8 @@
 
   auto replacement_listener = std::make_unique<TestNotificationListener>();
   dispatcher_->RegisterNonPersistentNotificationListener(
-      kPrimaryUniqueId, replacement_listener->GetRemote());
+      kPrimaryUniqueId, replacement_listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
 
@@ -172,13 +258,15 @@
        RegisterNonPersistentListener_ReplacedListenerGetsOnClick) {
   auto original_listener = std::make_unique<TestNotificationListener>();
   dispatcher_->RegisterNonPersistentNotificationListener(
-      kPrimaryUniqueId, original_listener->GetRemote());
+      kPrimaryUniqueId, original_listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
 
   auto replacement_listener = std::make_unique<TestNotificationListener>();
   dispatcher_->RegisterNonPersistentNotificationListener(
-      kPrimaryUniqueId, replacement_listener->GetRemote());
+      kPrimaryUniqueId, replacement_listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   WaitForMojoTasksToComplete();
 
@@ -196,11 +284,13 @@
 TEST_F(NotificationEventDispatcherImplTest,
        DispatchNonPersistentClickEvent_NotifiesCorrectRegisteredListener) {
   auto listener = std::make_unique<TestNotificationListener>();
-  dispatcher_->RegisterNonPersistentNotificationListener(kPrimaryUniqueId,
-                                                         listener->GetRemote());
+  dispatcher_->RegisterNonPersistentNotificationListener(
+      kPrimaryUniqueId, listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
   auto other_listener = std::make_unique<TestNotificationListener>();
   dispatcher_->RegisterNonPersistentNotificationListener(
-      kSomeOtherUniqueId, other_listener->GetRemote());
+      kSomeOtherUniqueId, other_listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
                                                base::DoNothing());
@@ -222,11 +312,13 @@
 TEST_F(NotificationEventDispatcherImplTest,
        DispatchNonPersistentCloseEvent_NotifiesCorrectRegisteredListener) {
   auto listener = std::make_unique<TestNotificationListener>();
-  dispatcher_->RegisterNonPersistentNotificationListener(kPrimaryUniqueId,
-                                                         listener->GetRemote());
+  dispatcher_->RegisterNonPersistentNotificationListener(
+      kPrimaryUniqueId, listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
   auto other_listener = std::make_unique<TestNotificationListener>();
   dispatcher_->RegisterNonPersistentNotificationListener(
-      kSomeOtherUniqueId, other_listener->GetRemote());
+      kSomeOtherUniqueId, other_listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   dispatcher_->DispatchNonPersistentCloseEvent(kPrimaryUniqueId,
                                                base::DoNothing());
@@ -248,8 +340,9 @@
 TEST_F(NotificationEventDispatcherImplTest,
        DispatchMultipleNonPersistentEvents_StopsNotifyingAfterClose) {
   auto listener = std::make_unique<TestNotificationListener>();
-  dispatcher_->RegisterNonPersistentNotificationListener(kPrimaryUniqueId,
-                                                         listener->GetRemote());
+  dispatcher_->RegisterNonPersistentNotificationListener(
+      kPrimaryUniqueId, listener->GetRemote(),
+      main_rfh()->GetWeakDocumentPtr());
 
   dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
   dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc
index 9d5597d..3830d72 100644
--- a/content/browser/renderer_host/navigation_controller_impl.cc
+++ b/content/browser/renderer_host/navigation_controller_impl.cc
@@ -1954,7 +1954,7 @@
   params->should_update_history = true;
   params->item_sequence_number = 0;
   params->document_sequence_number = 0;
-  bool is_in_fenced_frame_tree = rfh->frame_tree_node()->IsInFencedFrameTree();
+  bool is_in_fenced_frame_tree = rfh->IsNestedWithinFencedFrame();
   params->transition = is_in_fenced_frame_tree
                            ? ui::PAGE_TRANSITION_AUTO_SUBFRAME
                            : ui::PAGE_TRANSITION_LINK;
@@ -2130,8 +2130,7 @@
 
   InsertOrReplaceEntry(std::move(new_entry), replace_entry,
                        !request->post_commit_error_page_html().empty(),
-                       rfh->frame_tree_node()->IsInFencedFrameTree(),
-                       commit_details);
+                       rfh->IsNestedWithinFencedFrame(), commit_details);
 }
 
 void NavigationControllerImpl::RendererDidNavigateToExistingEntry(
@@ -2345,8 +2344,7 @@
   // delete the |frame_entry| when the function exits if it doesn't get used.
 
   InsertOrReplaceEntry(std::move(new_entry), replace_entry, false,
-                       rfh->frame_tree_node()->IsInFencedFrameTree(),
-                       commit_details);
+                       rfh->IsNestedWithinFencedFrame(), commit_details);
 }
 
 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe(
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index f00a5c6..e4e16cc 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -11518,7 +11518,7 @@
               .required_document_policy,
           params->document_policy_header)) {
     bad_message::ReceivedBadMessage(
-        GetProcess(), bad_message::RFH_BAD_DOCUMENT_POLICY_HEADER);
+        process, bad_message::RFH_BAD_DOCUMENT_POLICY_HEADER);
     return false;
   }
 
@@ -11527,7 +11527,7 @@
   base::WeakPtr<RenderFrameHostImpl> old_frame_host =
       frame_tree_node_->render_manager()->current_frame_host()->GetWeakPtr();
   if (is_same_document_navigation && this != old_frame_host.get()) {
-    bad_message::ReceivedBadMessage(this->GetProcess(),
+    bad_message::ReceivedBadMessage(process,
                                     bad_message::NI_IN_PAGE_NAVIGATION);
     return false;
   }
@@ -11540,8 +11540,7 @@
                                          .controller()
                                          .has_post_commit_error_entry()) {
     bad_message::ReceivedBadMessage(
-        frame_tree_node_->render_manager()->current_frame_host()->GetProcess(),
-        bad_message::NC_SAME_DOCUMENT_POST_COMMIT_ERROR);
+        process, bad_message::NC_SAME_DOCUMENT_POST_COMMIT_ERROR);
     return false;
   }
 
@@ -11551,7 +11550,7 @@
       // Terminate the renderer if allowing this subframe navigation to commit
       // would change the origin of the main frame.
       bad_message::ReceivedBadMessage(
-          GetProcess(),
+          process,
           bad_message::RFHI_SUBFRAME_NAV_WOULD_CHANGE_MAINFRAME_ORIGIN);
       return false;
     }
@@ -12025,7 +12024,7 @@
     // main frames can be recorded.
     // TODO(crbug.com/1245014): For prerendering pages, record the source url
     // after activation.
-    if (frame_tree_node()->GetFrameType() == FrameType::kPrimaryMainFrame &&
+    if (navigation_request->IsInPrimaryMainFrame() &&
         document_ukm_source_id != ukm::kInvalidSourceId) {
       ukm_recorder->UpdateSourceURL(document_ukm_source_id, params->url);
     }
@@ -12054,9 +12053,10 @@
   }
 
   // TODO(https://crbug.com/1131832): Do not pass |params| to DidNavigate().
-  frame_tree_node()->navigator().DidNavigate(this, *params,
-                                             std::move(navigation_request),
-                                             is_same_document_navigation);
+  NavigationRequest* raw_navigation_request = navigation_request.get();
+  raw_navigation_request->frame_tree_node()->navigator().DidNavigate(
+      this, *params, std::move(navigation_request),
+      is_same_document_navigation);
 
   // Reset back the state to false after navigation commits.
   // TODO(https://crbug.com/1072817): Undo this plumbing after removing the
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index cf51488..49473c7 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -545,24 +545,6 @@
       WebRuntimeFeatures::EnablePendingBeaconAPI(true);
     }
   }
-
-  if (base::FeatureList::IsEnabled(
-          blink::features::kBackForwardCacheSendNotRestoredReasons)) {
-    // The Chromium flag `kBackForwardCacheSendNotRestoredReasons` is true,
-    // which enables the parts of the API's implementation in Chromium.
-    if (blink::features::
-            kBackForwardCacheSendNotRestoredReasonsRequiresOriginTrial.Get()) {
-      // `kBackForwardCacheSendNotRestoredReasonsRequiresOriginTrial`=true
-      // specifies that execution context needs to have an origin trial token in
-      // order to use the BackForwardCacheNotRestoredReasons web API. So disable
-      // the RuntimeEnabledFeature flag BackForwardCacheNotRestoredReasons here
-      // and let the existence of OT token to decide whether the web API is
-      // enabled.
-      WebRuntimeFeatures::EnableBackForwardCacheNotRestoredReasons(false);
-    } else {
-      WebRuntimeFeatures::EnableBackForwardCacheNotRestoredReasons(true);
-    }
-  }
 }
 
 // Ensures that the various ways of enabling/disabling features do not produce
diff --git a/content/public/browser/file_system_access_permission_context.h b/content/public/browser/file_system_access_permission_context.h
index 6a4db1a..1fceadd 100644
--- a/content/public/browser/file_system_access_permission_context.h
+++ b/content/public/browser/file_system_access_permission_context.h
@@ -13,7 +13,6 @@
 #include "content/public/browser/global_routing_id.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_manager.mojom-forward.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_manager.mojom-shared.h"
-#include "ui/shell_dialogs/select_file_dialog.h"
 #include "url/origin.h"
 
 namespace content {
@@ -108,7 +107,7 @@
       PathType path_type,
       const base::FilePath& path,
       HandleType handle_type,
-      ui::SelectFileDialog::Type dialog_type,
+      UserAction user_action,
       GlobalRenderFrameHostId frame_id,
       base::OnceCallback<void(SensitiveEntryResult)> callback) = 0;
 
diff --git a/extensions/common/api/_manifest_features.json b/extensions/common/api/_manifest_features.json
index 1bdbee9..9586c2f8 100644
--- a/extensions/common/api/_manifest_features.json
+++ b/extensions/common/api/_manifest_features.json
@@ -354,8 +354,7 @@
       "allowlist": [
         "3BC1ED0B3E6EFDC7BD4D3D1D75D44B52DEE0A226",  // Secure Shell Ext (stable)
         "38C361D4A0726CE45D3572D65071B6BDB3092371"   // Secure Shell Ext (dev)
-      ],
-      "disallow_for_service_workers": true
+      ]
     },
     {
       "channel": "dev",
diff --git a/fuchsia_web/webengine/BUILD.gn b/fuchsia_web/webengine/BUILD.gn
index aef9f61..dbd3672 100644
--- a/fuchsia_web/webengine/BUILD.gn
+++ b/fuchsia_web/webengine/BUILD.gn
@@ -720,7 +720,9 @@
   sources = [
     "test_debug_listener.cc",
     "test_debug_listener.h",
-    "web_engine_debug_integration_test.cc",
+
+    # Disabled due to challenges connecting to fuchsia.web.Debug.
+    # "web_engine_debug_integration_test.cc",
     "web_engine_integration_logging_test.cc",
     "web_engine_integration_test.cc",
     "web_engine_integration_test_base.cc",
@@ -754,15 +756,10 @@
         ":web_engine",
         "web_engine",
       ] ]
-  use_cfv1 = true
-  use_cfv2 = false
   additional_manifest_fragments = [
-    "//build/config/fuchsia/test/audio_capabilities.test-cmx",
-    "//build/config/fuchsia/test/network_capabilities.test-cmx",
-    "//build/config/fuchsia/test/read_debug_data.test-cmx",
-    "//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
-    "//build/config/fuchsia/test/web_engine_required_capabilities.test-cmx",
-    "//build/config/fuchsia/test/web_instance_host_capabilities.test-cmx",
+    "//build/config/fuchsia/test/cfv1_launcher.shard.test-cml",
+    "//build/config/fuchsia/test/web_instance.shard.test-cml",
+    "//build/config/fuchsia/test/web_instance_host.shard.test-cml",
   ]
 }
 
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.mm b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.mm
index 7745ed96..c1289de 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.mm
@@ -10,9 +10,6 @@
 #import "base/callback_helpers.h"
 #import "base/command_line.h"
 #import "base/no_destructor.h"
-#import "base/task/sequenced_task_runner.h"
-#import "base/task/thread_pool.h"
-#import "base/threading/sequenced_task_runner_handle.h"
 #import "components/keyed_service/core/service_access_type.h"
 #import "components/keyed_service/ios/browser_state_dependency_manager.h"
 #import "components/password_manager/core/browser/login_database.h"
@@ -77,17 +74,6 @@
       password_manager::CreateLoginDatabaseForProfileStorage(
           context->GetStatePath()));
 
-  scoped_refptr<base::SequencedTaskRunner> main_task_runner(
-      base::SequencedTaskRunnerHandle::Get());
-  // USER_VISIBLE priority is chosen for the background task runner, because
-  // the passwords obtained through tasks on the background runner influence
-  // what the user sees.
-  // TODO(crbug.com/741660): Create the task runner inside password_manager
-  // component instead.
-  scoped_refptr<base::SequencedTaskRunner> db_task_runner(
-      base::ThreadPool::CreateSequencedTaskRunner(
-          {base::MayBlock(), base::TaskPriority::USER_VISIBLE}));
-
   scoped_refptr<password_manager::PasswordStore> store =
       base::MakeRefCounted<password_manager::PasswordStore>(
           std::make_unique<password_manager::PasswordStoreBuiltInBackend>(
diff --git a/ios/chrome/browser/ui/icons/BUILD.gn b/ios/chrome/browser/ui/icons/BUILD.gn
index efda568..926c22b 100644
--- a/ios/chrome/browser/ui/icons/BUILD.gn
+++ b/ios/chrome/browser/ui/icons/BUILD.gn
@@ -2,6 +2,21 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/buildflag_header.gni")
+
+declare_args() {
+  # This defines targets to include branded icons.
+  ios_branded_icons = ":branded"
+}
+
+_use_branded_symbols = get_label_info(":branded", "label_no_toolchain") !=
+                       get_label_info(ios_branded_icons, "label_no_toolchain")
+
+buildflag_header("buildflags") {
+  header = "buildflags.h"
+  flags = [ "IOS_USE_BRANDED_SYMBOLS=$_use_branded_symbols" ]
+}
+
 source_set("icons") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
@@ -67,6 +82,7 @@
     "settings_icon.mm",
   ]
   deps = [
+    ":buildflags",
     ":symbols",
     "//ios/chrome/browser/ui/icons/resources:arrow_triangle_slash_circlepath",
     "//ios/chrome/browser/ui/icons/resources:checkerboard_shield",
@@ -102,6 +118,7 @@
     "//ios/chrome/browser/ui/icons/resources:square_number",
     "//ios/chrome/browser/ui/icons/resources:translate",
     "//ui/base",
+    ios_branded_icons,
   ]
   frameworks = [
     "CoreGraphics.framework",
@@ -132,3 +149,7 @@
     "//third_party/material_design_icons:ic_search",
   ]
 }
+
+group("branded") {
+  # Empty in the non-branded repo.
+}
diff --git a/ios/chrome/browser/ui/icons/chrome_symbol.h b/ios/chrome/browser/ui/icons/chrome_symbol.h
index e4033e4b..02c50b4 100644
--- a/ios/chrome/browser/ui/icons/chrome_symbol.h
+++ b/ios/chrome/browser/ui/icons/chrome_symbol.h
@@ -91,6 +91,10 @@
 UIImage* CustomSymbolTemplateWithPointSize(NSString* symbol_name,
                                            CGFloat point_size);
 
+// Returns a custom symbol named `symbol_name`, configured with the default
+// configuration and the given `point_size`.
+UIImage* CustomMulticolorSymbol(NSString* symbol_name, CGFloat point_size);
+
 // Returns YES if the kUseSFSymbols flag is enabled.
 bool UseSymbols();
 
diff --git a/ios/chrome/browser/ui/icons/chrome_symbol.mm b/ios/chrome/browser/ui/icons/chrome_symbol.mm
index fd9c435..d76713bc 100644
--- a/ios/chrome/browser/ui/icons/chrome_symbol.mm
+++ b/ios/chrome/browser/ui/icons/chrome_symbol.mm
@@ -133,6 +133,21 @@
       imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
 }
 
+UIImage* CustomMulticolorSymbol(NSString* symbol_name, CGFloat point_size) {
+  UIImageConfiguration* configuration =
+      DefaultSymbolConfigurationWithPointSize(point_size);
+  if (@available(iOS 15, *)) {
+    configuration = [configuration
+        configurationByApplyingConfiguration:
+            [UIImageSymbolConfiguration configurationPreferringMulticolor]];
+  }
+  UIImage* symbol = CustomSymbolWithConfiguration(symbol_name, configuration);
+  if (@available(iOS 15, *)) {
+    return symbol;
+  }
+  return [symbol imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
+}
+
 bool UseSymbols() {
   return base::FeatureList::IsEnabled(kUseSFSymbols);
 }
diff --git a/ios/chrome/browser/ui/icons/settings_icon.h b/ios/chrome/browser/ui/icons/settings_icon.h
index 9992425f..e051243 100644
--- a/ios/chrome/browser/ui/icons/settings_icon.h
+++ b/ios/chrome/browser/ui/icons/settings_icon.h
@@ -7,10 +7,15 @@
 
 #import <UIKit/UIKit.h>
 
+#import "ios/chrome/browser/ui/icons/buildflags.h"
+
 // Custom symbol names.
 extern NSString* const kPrivacySymbol;
 extern NSString* const kSyncDisabledSymbol;
 extern NSString* const kSafetyCheckSymbol;
+#if BUILDFLAG(IOS_USE_BRANDED_SYMBOLS)
+extern NSString* const kGoogleIconSymbol;
+#endif  // BUILDFLAG(IOS_USE_BRANDED_SYMBOLS)
 
 // Default symbol names.
 extern NSString* const kSyncEnabledSymbol;
@@ -24,5 +29,8 @@
 // Returns a custom symbol named `symbol_name` configured for the Settings
 // root screen.
 UIImage* CustomSettingsRootSymbol(NSString* symbol_name);
+// Returns a custom symbol named `symbol_name` configured for the Settings
+// root screen, with multicolor enabled.
+UIImage* CustomSettingsRootMulticolorSymbol(NSString* symbol_name);
 
 #endif  // IOS_CHROME_BROWSER_UI_ICONS_SETTINGS_ICON_H_
diff --git a/ios/chrome/browser/ui/icons/settings_icon.mm b/ios/chrome/browser/ui/icons/settings_icon.mm
index e48f1f45..afce744 100644
--- a/ios/chrome/browser/ui/icons/settings_icon.mm
+++ b/ios/chrome/browser/ui/icons/settings_icon.mm
@@ -16,6 +16,9 @@
 NSString* const kPrivacySymbol = @"checkerboard_shield";
 NSString* const kSyncDisabledSymbol = @"arrow_triangle_slash_circlepath";
 NSString* const kSafetyCheckSymbol = @"checkermark_shield";
+#if BUILDFLAG(IOS_USE_BRANDED_SYMBOLS)
+NSString* const kGoogleIconSymbol = @"google_icon";
+#endif  // BUILDFLAG(IOS_USE_BRANDED_SYMBOLS)
 
 // Default symbol names.
 NSString* const kSyncEnabledSymbol = @"arrow.triangle.2.circlepath";
@@ -32,3 +35,7 @@
   return CustomSymbolWithPointSize(symbol_name,
                                    kSettingsRootSymbolImagePointSize);
 }
+
+UIImage* CustomSettingsRootMulticolorSymbol(NSString* symbol_name) {
+  return CustomMulticolorSymbol(symbol_name, kSettingsRootSymbolImagePointSize);
+}
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index b7dae17..0518b11b 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -156,6 +156,7 @@
     "//ios/chrome/browser/ui/elements:elements_internal",
     "//ios/chrome/browser/ui/first_run:field_trial",
     "//ios/chrome/browser/ui/icons",
+    "//ios/chrome/browser/ui/icons:buildflags",
     "//ios/chrome/browser/ui/icons:settings_icons",
     "//ios/chrome/browser/ui/icons:symbols",
     "//ios/chrome/browser/ui/keyboard",
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
index f09c7960..9156edd 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -62,6 +62,7 @@
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/chrome/browser/ui/commands/snackbar_commands.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
+#import "ios/chrome/browser/ui/icons/buildflags.h"
 #import "ios/chrome/browser/ui/icons/chrome_symbol.h"
 #import "ios/chrome/browser/ui/icons/settings_icon.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h"
@@ -192,6 +193,15 @@
   return kSyncEnabled;
 }
 
+// Returns the branded version of the Google Services symbol.
+UIImage* GetBrandedGoogleServicesSymbol() {
+#if BUILDFLAG(IOS_USE_BRANDED_SYMBOLS)
+  return CustomSettingsRootMulticolorSymbol(kGoogleIconSymbol);
+#else
+  return DefaultSettingsRootSymbol(@"gearshape.2");
+#endif
+}
+
 }  // namespace
 
 #pragma mark - SettingsTableViewController
@@ -741,13 +751,12 @@
 
 - (TableViewItem*)googleServicesCellItem {
   if (UseSymbols()) {
-    // TODO(crbug.com/1315544): The icon should be updated.
     return [self detailItemWithType:SettingsItemTypeGoogleServices
                                text:l10n_util::GetNSString(
                                         IDS_IOS_GOOGLE_SERVICES_SETTINGS_TITLE)
                          detailText:nil
-                             symbol:nil
-              symbolBackgroundColor:UIColor.clearColor
+                             symbol:GetBrandedGoogleServicesSymbol()
+              symbolBackgroundColor:nil
             accessibilityIdentifier:kSettingsGoogleServicesCellId];
   }
   return [self detailItemWithType:SettingsItemTypeGoogleServices
@@ -1323,8 +1332,10 @@
   detailItem.accessibilityTraits |= UIAccessibilityTraitButton;
   detailItem.accessibilityIdentifier = accessibilityIdentifier;
   detailItem.iconImage = symbol;
-  detailItem.iconBackgroundColor = backgroundColor;
-  detailItem.iconTintColor = UIColor.whiteColor;
+  if (backgroundColor) {
+    detailItem.iconBackgroundColor = backgroundColor;
+    detailItem.iconTintColor = UIColor.whiteColor;
+  }
   detailItem.iconCornerRadius = kColorfulBackgroundSymbolCornerRadius;
   return detailItem;
 }
diff --git a/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc b/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
index 9401d60..7c64ff6 100644
--- a/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
+++ b/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
@@ -12,7 +12,6 @@
 #include <utility>
 #include <vector>
 
-#include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/files/file.h"
@@ -34,7 +33,6 @@
 #include "media/capture/video/chromeos/mojom/camera_common.mojom.h"
 #include "media/capture/video/chromeos/mojom/cros_camera_client.mojom.h"
 #include "media/capture/video/chromeos/mojom/cros_camera_service.mojom.h"
-#include "media/capture/video/chromeos/mojom/effects_pipeline.mojom.h"
 #include "media/capture/video/chromeos/video_capture_features_chromeos.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/platform/named_platform_channel.h"
@@ -129,36 +127,6 @@
   mojo::Remote<cros::mojom::CameraHalClient> client_;
 };
 
-cros::mojom::EffectsConfigPtr GetCameraEffectState() {
-  cros::mojom::EffectsConfigPtr effects_state =
-      cros::mojom::EffectsConfig::New();
-
-  std::string blur_level = GetFieldTrialParamValueByFeature(
-      ash::features::kVCBackgroundBlur, "blur_level");
-  if (blur_level == "lowest") {
-    effects_state->blur_level = cros::mojom::BlurLevel::kLowest;
-  } else if (blur_level == "light") {
-    effects_state->blur_level = cros::mojom::BlurLevel::kLight;
-  } else if (blur_level == "medium") {
-    effects_state->blur_level = cros::mojom::BlurLevel::kMedium;
-  } else if (blur_level == "heavy") {
-    effects_state->blur_level = cros::mojom::BlurLevel::kHeavy;
-  } else if (blur_level == "maximum") {
-    effects_state->blur_level = cros::mojom::BlurLevel::kMaximum;
-  }
-
-  effects_state->effect = ash::features::IsVCBackgroundBlurEnabled()
-                              ? cros::mojom::CameraEffect::kBackgroundBlur
-                              : cros::mojom::CameraEffect::kNone;
-  effects_state->effect = ash::features::IsVCBackgroundReplaceEnabled()
-                              ? cros::mojom::CameraEffect::kBackgroundReplace
-                              : effects_state->effect;
-  effects_state->effect = ash::features::IsVCPortraitRelightingEnabled()
-                              ? cros::mojom::CameraEffect::kPortraitRelight
-                              : effects_state->effect;
-  return effects_state;
-}
-
 }  // namespace
 
 CameraClientObserver::~CameraClientObserver() = default;
@@ -311,11 +279,21 @@
     if (!base::DeleteFile(disable_file_path)) {
       LOG(WARNING) << "Could not delete " << kForceDisableEffectsPath;
     }
-    base::File file(ash::features::IsVCBackgroundBlurEnabled()
-                        ? enable_file_path
-                        : disable_file_path,
-                    base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
-    file.Close();
+    const base::CommandLine* command_line =
+        base::CommandLine::ForCurrentProcess();
+    if (command_line->HasSwitch(media::switches::kEffectsOverride)) {
+      std::string value =
+          command_line->GetSwitchValueASCII(switches::kEffectsOverride);
+      if (value == switches::kEffectsForceEnabled) {
+        base::File file(enable_file_path, base::File::FLAG_CREATE_ALWAYS |
+                                              base::File::FLAG_WRITE);
+        file.Close();
+      } else if (value == switches::kEffectsForceDisabled) {
+        base::File file(disable_file_path, base::File::FLAG_CREATE_ALWAYS |
+                                               base::File::FLAG_WRITE);
+        file.Close();
+      }
+    }
   }
 
   jda_factory_ = std::move(jda_factory);
@@ -498,12 +476,6 @@
         std::move(auto_framing_supported_callback_));
   }
   camera_hal_server_->SetAutoFramingState(current_auto_framing_state_);
-  camera_hal_server_->SetCameraEffect(
-      GetCameraEffectState(),
-      base::BindOnce([](cros::mojom::SetEffectResult result) {
-        if (result == cros::mojom::SetEffectResult::kError)
-          LOG(ERROR) << "SetCameraEffect failed.";
-      }));
   CAMERA_LOG(EVENT) << "Camera HAL server registered";
   std::move(callback).Run(
       0, camera_hal_server_callbacks_.BindNewPipeAndPassRemote());
diff --git a/media/capture/video/chromeos/camera_hal_dispatcher_impl_unittest.cc b/media/capture/video/chromeos/camera_hal_dispatcher_impl_unittest.cc
index e4d61ea..71c350d 100644
--- a/media/capture/video/chromeos/camera_hal_dispatcher_impl_unittest.cc
+++ b/media/capture/video/chromeos/camera_hal_dispatcher_impl_unittest.cc
@@ -16,7 +16,6 @@
 #include "media/capture/video/chromeos/mojom/camera_common.mojom.h"
 #include "media/capture/video/chromeos/mojom/cros_camera_client.mojom.h"
 #include "media/capture/video/chromeos/mojom/cros_camera_service.mojom.h"
-#include "media/capture/video/chromeos/mojom/effects_pipeline.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -43,12 +42,6 @@
       cros::mojom::CameraClientType camera_client_type) override {
     DoCreateChannel(std::move(camera_module_receiver), camera_client_type);
   }
-
-  // **NOTE**: If you add additional mocks here, you will need to
-  //           carefully add an EXPECT_CALL with a WillOnce to invoke
-  //           CameraHalDispatcherImplTest::QuitRunLoop and increment
-  //           RunLoop(val) appropriately. Failing to do this will
-  //           introduce flakiness into these tests.
   MOCK_METHOD2(DoCreateChannel,
                void(mojo::PendingReceiver<cros::mojom::CameraModule>
                         camera_module_receiver,
@@ -65,11 +58,6 @@
                void(cros::mojom::CameraPrivacySwitchState state));
   MOCK_METHOD1(GetAutoFramingSupported,
                void(GetAutoFramingSupportedCallback callback));
-  MOCK_METHOD2(SetCameraEffect,
-               void(::cros::mojom::EffectsConfigPtr config,
-                    SetCameraEffectCallback callback));
-  // **NOTE**: Please read the note at the top of these mocks if you're
-  //           adding more mocks.
 
   mojo::PendingRemote<cros::mojom::CameraHalServer> GetPendingRemote() {
     return receiver_.BindNewPipeAndPassRemote();
@@ -224,17 +212,6 @@
       .Times(1)
       .WillOnce(
           InvokeWithoutArgs(this, &CameraHalDispatcherImplTest::QuitRunLoop));
-  EXPECT_CALL(*mock_server, SetAutoFramingState(_))
-      .Times(1)
-      .WillOnce(
-          InvokeWithoutArgs(this, &CameraHalDispatcherImplTest::QuitRunLoop));
-  EXPECT_CALL(*mock_server, SetCameraEffect(_, _))
-      .Times(1)
-      .WillOnce([this](::cros::mojom::EffectsConfigPtr,
-                       MockCameraHalServer::SetCameraEffectCallback callback) {
-        std::move(callback).Run(::cros::mojom::SetEffectResult::kOk);
-        this->QuitRunLoop();
-      });
 
   auto server = mock_server->GetPendingRemote();
   GetProxyTaskRunner()->PostTask(
@@ -255,9 +232,8 @@
           base::BindOnce(&CameraHalDispatcherImplTest::OnRegisteredClient,
                          base::Unretained(this))));
 
-  // Wait until the client gets the established Mojo channel, and that
-  // all expected mojo calls have been invoked.
-  DoLoop(4);
+  // Wait until the client gets the established Mojo channel.
+  DoLoop(2);
 
   // The client registration callback may be called after
   // CameraHalClient::SetUpChannel(). Use a waitable event to make sure we have
@@ -278,17 +254,6 @@
       .Times(1)
       .WillOnce(
           InvokeWithoutArgs(this, &CameraHalDispatcherImplTest::QuitRunLoop));
-  EXPECT_CALL(*mock_server, SetAutoFramingState(_))
-      .Times(1)
-      .WillOnce(
-          InvokeWithoutArgs(this, &CameraHalDispatcherImplTest::QuitRunLoop));
-  EXPECT_CALL(*mock_server, SetCameraEffect(_, _))
-      .Times(1)
-      .WillOnce([this](::cros::mojom::EffectsConfigPtr,
-                       MockCameraHalServer::SetCameraEffectCallback callback) {
-        std::move(callback).Run(::cros::mojom::SetEffectResult::kOk);
-        this->QuitRunLoop();
-      });
 
   server = mock_server->GetPendingRemote();
   GetProxyTaskRunner()->PostTask(
@@ -299,9 +264,8 @@
           base::BindOnce(&CameraHalDispatcherImplTest::OnRegisteredServer,
                          base::Unretained(this))));
 
-  // Wait until the client gets the established Mojo channel, and that
-  // all expected mojo calls have been invoked.
-  DoLoop(4);
+  // Wait until the clients get the newly established Mojo channel.
+  DoLoop(2);
 }
 
 // Test that the CameraHalDisptcherImpl correctly re-establishes a Mojo channel
@@ -320,17 +284,6 @@
       .Times(1)
       .WillOnce(
           InvokeWithoutArgs(this, &CameraHalDispatcherImplTest::QuitRunLoop));
-  EXPECT_CALL(*mock_server, SetAutoFramingState(_))
-      .Times(1)
-      .WillOnce(
-          InvokeWithoutArgs(this, &CameraHalDispatcherImplTest::QuitRunLoop));
-  EXPECT_CALL(*mock_server, SetCameraEffect(_, _))
-      .Times(1)
-      .WillOnce([this](::cros::mojom::EffectsConfigPtr,
-                       MockCameraHalServer::SetCameraEffectCallback callback) {
-        std::move(callback).Run(::cros::mojom::SetEffectResult::kOk);
-        this->QuitRunLoop();
-      });
 
   auto server = mock_server->GetPendingRemote();
   GetProxyTaskRunner()->PostTask(
@@ -351,9 +304,8 @@
           base::BindOnce(&CameraHalDispatcherImplTest::OnRegisteredClient,
                          base::Unretained(this))));
 
-  // Wait until the client gets the established Mojo channel, and that
-  // all expected mojo calls have been invoked.
-  DoLoop(4);
+  // Wait until the client gets the established Mojo channel.
+  DoLoop(2);
 
   // The client registration callback may be called after
   // CameraHalClient::SetUpChannel(). Use a waitable event to make sure we have
@@ -386,8 +338,7 @@
           base::BindOnce(&CameraHalDispatcherImplTest::OnRegisteredClient,
                          base::Unretained(this))));
 
-  // Wait until the clients gets the newly established Mojo channel, and that
-  // all expected mojo calls have been invoked.
+  // Wait until the clients gets the newly established Mojo channel.
   DoLoop(2);
 
   // Make sure the client is still successfully registered.
@@ -411,7 +362,6 @@
           base::BindOnce(&CameraHalDispatcherImplTest::OnRegisteredServer,
                          base::Unretained(this))));
 
-  bool firstRun = true;
   for (auto type : TokenManager::kTrustedClientTypes) {
     auto mock_client = std::make_unique<MockCameraHalClient>();
     EXPECT_CALL(*mock_server, DoCreateChannel(_, _))
@@ -422,22 +372,6 @@
         .Times(1)
         .WillOnce(
             InvokeWithoutArgs(this, &CameraHalDispatcherImplTest::QuitRunLoop));
-    if (firstRun) {
-      EXPECT_CALL(*mock_server, SetAutoFramingState(_))
-          .Times(1)
-          .WillOnce(InvokeWithoutArgs(
-              this, &CameraHalDispatcherImplTest::QuitRunLoop));
-      EXPECT_CALL(*mock_server, SetCameraEffect(_, _))
-          .Times(1)
-          .WillOnce(
-              [this](::cros::mojom::EffectsConfigPtr,
-                     MockCameraHalServer::SetCameraEffectCallback callback) {
-                std::move(callback).Run(::cros::mojom::SetEffectResult::kOk);
-                this->QuitRunLoop();
-              });
-      // These above calls only happen on the first client connection
-      DoLoop(2);
-    }
 
     auto client = mock_client->GetPendingRemote();
     GetProxyTaskRunner()->PostTask(
@@ -457,7 +391,6 @@
     // have the result.
     register_client_event_.Wait();
     ASSERT_EQ(last_register_client_result_, 0);
-    firstRun = false;
   }
 }
 
diff --git a/media/capture/video/chromeos/mojom/BUILD.gn b/media/capture/video/chromeos/mojom/BUILD.gn
index f4889ad..8fbc22f 100644
--- a/media/capture/video/chromeos/mojom/BUILD.gn
+++ b/media/capture/video/chromeos/mojom/BUILD.gn
@@ -25,7 +25,6 @@
   sources = [
     "cros_camera_client.mojom",
     "cros_camera_service.mojom",
-    "effects_pipeline.mojom",
   ]
 
   deps = [
diff --git a/media/capture/video/chromeos/mojom/cros_camera_service.mojom b/media/capture/video/chromeos/mojom/cros_camera_service.mojom
index 1b8e3759c..d497d30 100644
--- a/media/capture/video/chromeos/mojom/cros_camera_service.mojom
+++ b/media/capture/video/chromeos/mojom/cros_camera_service.mojom
@@ -11,7 +11,6 @@
 import "components/chromeos_camera/common/mjpeg_decode_accelerator.mojom";
 import "media/capture/video/chromeos/mojom/camera_common.mojom";
 import "media/capture/video/chromeos/mojom/cros_camera_client.mojom";
-import "media/capture/video/chromeos/mojom/effects_pipeline.mojom";
 import "mojo/public/mojom/base/unguessable_token.mojom";
 
 // CameraClientType indicates the type of a CameraHalClient.
@@ -121,7 +120,7 @@
 
 // The CrOS camera HAL v3 Mojo server.
 //
-// Next method ID: 7
+// Next method ID: 6
 interface CameraHalServer {
   // A caller calls CreateChannel to create a new Mojo channel to the camera
   // HAL v3 adapter.  Upon successfully binding of |camera_module_receiver|, the
@@ -149,10 +148,6 @@
   // Get if the HAL supports auto framing.
   [MinVersion=9]
   GetAutoFramingSupported@5() => (bool supported);
-
-  // Turn ON/OFF and configure specified effect.
-  [MinVersion=10]
-  SetCameraEffect@6(EffectsConfig config) => (SetEffectResult result);
 };
 
 // CameraHalServerCallbacks is an interface for CameraHalServer to notify
diff --git a/media/capture/video/chromeos/mojom/effects_pipeline.mojom b/media/capture/video/chromeos/mojom/effects_pipeline.mojom
deleted file mode 100644
index ebd04709..0000000
--- a/media/capture/video/chromeos/mojom/effects_pipeline.mojom
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2022 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.
-
-// Next min version: 1
-
-module cros.mojom;
-
-// Set of effects that can be enabled.
-// Used by EffectsConfig to indicate which effect the g3 shared library
-// should be applying. Needs to be kept in sync with g3 version found in
-// chromeos/ml/effects_pipeline/effects_config.h
-[Extensible]
-enum CameraEffect {
-  [Default] kNone = 0,
-  kBackgroundBlur = 1,
-  kBackgroundReplace = 2,
-  kPortraitRelight = 3,
-};
-
-// Set of GPU APIs available.
-[Extensible]
-enum GpuApi {
-  kOpenCL = 0,
-  [Default] kOpenGL = 1,
-};
-
-// Indicates the state of setting an effect.
-[Extensible]
-enum SetEffectResult {
-  [Default] kOk = 0,
-  kError = 1,
-};
-
-// Defines which level of blur to apply with the background blur effect.
-[Extensible]
-enum BlurLevel {
-  kLowest,
-  kLight,
-  [Default] kMedium,
-  kHeavy,
-  kMaximum,
-};
-
-// Structure used for configuring and enabling video conferencing effects.
-// This should be kept in sync with the google3 version found in:
-// chromeos/ml/effects_pipeline/effects_config.h
-struct EffectsConfig {
-  // Name of the effect to enable.
-  CameraEffect effect = kNone;
-
-  // How much blur to apply for the background blur effect.
-  BlurLevel blur_level = kMedium;
-
-  // Select which GPU API to use to perform the segmentation inference.
-  GpuApi segmentation_gpu_api = kOpenGL;
-
-  // Maximum number of frames allowed in flight.
-  uint16 graph_max_frames_in_flight = 2;
-};
diff --git a/media/capture/video/chromeos/video_capture_features_chromeos.cc b/media/capture/video/chromeos/video_capture_features_chromeos.cc
index d579566..1375ac5 100644
--- a/media/capture/video/chromeos/video_capture_features_chromeos.cc
+++ b/media/capture/video/chromeos/video_capture_features_chromeos.cc
@@ -13,6 +13,7 @@
 const char kForceControlFaceAe[] = "force-control-face-ae";
 const char kHdrNetOverride[] = "hdrnet-override";
 const char kAutoFramingOverride[] = "auto-framing-override";
+const char kEffectsOverride[] = "effects-override";
 
 }  // namespace switches
 
diff --git a/media/capture/video/chromeos/video_capture_features_chromeos.h b/media/capture/video/chromeos/video_capture_features_chromeos.h
index d7c2a96..8f36098 100644
--- a/media/capture/video/chromeos/video_capture_features_chromeos.h
+++ b/media/capture/video/chromeos/video_capture_features_chromeos.h
@@ -22,6 +22,10 @@
 constexpr char kAutoFramingForceEnabled[] = "force-enabled";
 constexpr char kAutoFramingForceDisabled[] = "force-disabled";
 
+CAPTURE_EXPORT extern const char kEffectsOverride[];
+constexpr char kEffectsForceEnabled[] = "force-enabled";
+constexpr char kEffectsForceDisabled[] = "force-disabled";
+
 }  // namespace switches
 
 namespace features {
diff --git a/net/base/features.cc b/net/base/features.cc
index c0eeffd..aa4214e 100644
--- a/net/base/features.cc
+++ b/net/base/features.cc
@@ -361,4 +361,8 @@
              "EnableWebsocketsOverHttp3",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+BASE_FEATURE(kUseNAT64ForIPv4Literal,
+             "UseNAT64ForIPv4Literal",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 }  // namespace net::features
diff --git a/net/base/features.h b/net/base/features.h
index 7f13e30..e62875e 100644
--- a/net/base/features.h
+++ b/net/base/features.h
@@ -418,6 +418,9 @@
 
 NET_EXPORT BASE_DECLARE_FEATURE(kEnableWebsocketsOverHttp3);
 
+// Whether to do IPv4 to IPv6 address translation for IPv4 literals.
+NET_EXPORT BASE_DECLARE_FEATURE(kUseNAT64ForIPv4Literal);
+
 }  // namespace net::features
 
 #endif  // NET_BASE_FEATURES_H_
diff --git a/net/base/ip_address.cc b/net/base/ip_address.cc
index 4c0a2a06..7ac6331 100644
--- a/net/base/ip_address.cc
+++ b/net/base/ip_address.cc
@@ -490,4 +490,148 @@
                             IPAddress(all_ones->data(), all_ones->size()));
 }
 
+Dns64PrefixLength ExtractPref64FromIpv4onlyArpaAAAA(const IPAddress& address) {
+  DCHECK(address.IsIPv6());
+  IPAddress ipv4onlyarpa0(192, 0, 0, 170);
+  IPAddress ipv4onlyarpa1(192, 0, 0, 171);
+  if (std::equal(ipv4onlyarpa0.bytes().begin(), ipv4onlyarpa0.bytes().end(),
+                 address.bytes().begin() + 12u) ||
+      std::equal(ipv4onlyarpa1.bytes().begin(), ipv4onlyarpa1.bytes().end(),
+                 address.bytes().begin() + 12u)) {
+    return Dns64PrefixLength::k96bit;
+  } else if (std::equal(ipv4onlyarpa0.bytes().begin(),
+                        ipv4onlyarpa0.bytes().end(),
+                        address.bytes().begin() + 9u) ||
+             std::equal(ipv4onlyarpa1.bytes().begin(),
+                        ipv4onlyarpa1.bytes().end(),
+                        address.bytes().begin() + 9u)) {
+    return Dns64PrefixLength::k64bit;
+  } else if ((std::equal(ipv4onlyarpa0.bytes().begin(),
+                         ipv4onlyarpa0.bytes().begin() + 1u,
+                         address.bytes().begin() + 7u) &&
+              std::equal(ipv4onlyarpa0.bytes().begin() + 1u,
+                         ipv4onlyarpa0.bytes().end(),
+                         address.bytes().begin() + 9u)) ||
+             (std::equal(ipv4onlyarpa1.bytes().begin(),
+                         ipv4onlyarpa1.bytes().begin() + 1u,
+                         address.bytes().begin() + 7u) &&
+              std::equal(ipv4onlyarpa1.bytes().begin() + 1u,
+                         ipv4onlyarpa1.bytes().end(),
+                         address.bytes().begin() + 9u))) {
+    return Dns64PrefixLength::k56bit;
+  } else if ((std::equal(ipv4onlyarpa0.bytes().begin(),
+                         ipv4onlyarpa0.bytes().begin() + 2u,
+                         address.bytes().begin() + 6u) &&
+              std::equal(ipv4onlyarpa0.bytes().begin() + 2u,
+                         ipv4onlyarpa0.bytes().end(),
+                         address.bytes().begin() + 9u)) ||
+             ((std::equal(ipv4onlyarpa1.bytes().begin(),
+                          ipv4onlyarpa1.bytes().begin() + 2u,
+                          address.bytes().begin() + 6u) &&
+               std::equal(ipv4onlyarpa1.bytes().begin() + 2u,
+                          ipv4onlyarpa1.bytes().end(),
+                          address.bytes().begin() + 9u)))) {
+    return Dns64PrefixLength::k48bit;
+  } else if ((std::equal(ipv4onlyarpa0.bytes().begin(),
+                         ipv4onlyarpa0.bytes().begin() + 3u,
+                         address.bytes().begin() + 5u) &&
+              std::equal(ipv4onlyarpa0.bytes().begin() + 3u,
+                         ipv4onlyarpa0.bytes().end(),
+                         address.bytes().begin() + 9u)) ||
+             (std::equal(ipv4onlyarpa1.bytes().begin(),
+                         ipv4onlyarpa1.bytes().begin() + 3u,
+                         address.bytes().begin() + 5u) &&
+              std::equal(ipv4onlyarpa1.bytes().begin() + 3u,
+                         ipv4onlyarpa1.bytes().end(),
+                         address.bytes().begin() + 9u))) {
+    return Dns64PrefixLength::k40bit;
+  } else if (std::equal(ipv4onlyarpa0.bytes().begin(),
+                        ipv4onlyarpa0.bytes().end(),
+                        address.bytes().begin() + 4u) ||
+             std::equal(ipv4onlyarpa1.bytes().begin(),
+                        ipv4onlyarpa1.bytes().end(),
+                        address.bytes().begin() + 4u)) {
+    return Dns64PrefixLength::k32bit;
+  } else {
+    // if ipv4onlyarpa address is not found return 0
+    return Dns64PrefixLength::kInvalid;
+  }
+}
+
+IPAddress ConvertIPv4ToIPv4EmbeddedIPv6(const IPAddress& ipv4_address,
+                                        const IPAddress& ipv6_address,
+                                        Dns64PrefixLength prefix_length) {
+  DCHECK(ipv4_address.IsIPv4());
+  DCHECK(ipv6_address.IsIPv6());
+
+  base::StackVector<uint8_t, 16> bytes;
+
+  uint8_t zero_bits[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+  switch (prefix_length) {
+    case Dns64PrefixLength::k96bit:
+      bytes->insert(bytes->end(), ipv6_address.bytes().begin(),
+                    ipv6_address.bytes().begin() + 12u);
+      bytes->insert(bytes->end(), ipv4_address.bytes().begin(),
+                    ipv4_address.bytes().end());
+      return IPAddress(bytes->data(), bytes->size());
+    case Dns64PrefixLength::k64bit:
+      bytes->insert(bytes->end(), ipv6_address.bytes().begin(),
+                    ipv6_address.bytes().begin() + 8u);
+      bytes->insert(bytes->end(), std::begin(zero_bits),
+                    std::begin(zero_bits) + 1u);
+      bytes->insert(bytes->end(), ipv4_address.bytes().begin(),
+                    ipv4_address.bytes().end());
+      bytes->insert(bytes->end(), std::begin(zero_bits),
+                    std::begin(zero_bits) + 3u);
+      return IPAddress(bytes->data(), bytes->size());
+    case Dns64PrefixLength::k56bit:
+      bytes->insert(bytes->end(), ipv6_address.bytes().begin(),
+                    ipv6_address.bytes().begin() + 7u);
+      bytes->insert(bytes->end(), ipv4_address.bytes().begin(),
+                    ipv4_address.bytes().begin() + 1u);
+      bytes->insert(bytes->end(), std::begin(zero_bits),
+                    std::begin(zero_bits) + 1u);
+      bytes->insert(bytes->end(), ipv4_address.bytes().begin() + 1u,
+                    ipv4_address.bytes().end());
+      bytes->insert(bytes->end(), std::begin(zero_bits),
+                    std::begin(zero_bits) + 4u);
+      return IPAddress(bytes->data(), bytes->size());
+    case Dns64PrefixLength::k48bit:
+      bytes->insert(bytes->end(), ipv6_address.bytes().begin(),
+                    ipv6_address.bytes().begin() + 6u);
+      bytes->insert(bytes->end(), ipv4_address.bytes().begin(),
+                    ipv4_address.bytes().begin() + 2u);
+      bytes->insert(bytes->end(), std::begin(zero_bits),
+                    std::begin(zero_bits) + 1u);
+      bytes->insert(bytes->end(), ipv4_address.bytes().begin() + 2u,
+                    ipv4_address.bytes().end());
+      bytes->insert(bytes->end(), std::begin(zero_bits),
+                    std::begin(zero_bits) + 5u);
+      return IPAddress(bytes->data(), bytes->size());
+    case Dns64PrefixLength::k40bit:
+      bytes->insert(bytes->end(), ipv6_address.bytes().begin(),
+                    ipv6_address.bytes().begin() + 5u);
+      bytes->insert(bytes->end(), ipv4_address.bytes().begin(),
+                    ipv4_address.bytes().begin() + 3u);
+      bytes->insert(bytes->end(), std::begin(zero_bits),
+                    std::begin(zero_bits) + 1u);
+      bytes->insert(bytes->end(), ipv4_address.bytes().begin() + 3u,
+                    ipv4_address.bytes().end());
+      bytes->insert(bytes->end(), std::begin(zero_bits),
+                    std::begin(zero_bits) + 6u);
+      return IPAddress(bytes->data(), bytes->size());
+    case Dns64PrefixLength::k32bit:
+      bytes->insert(bytes->end(), ipv6_address.bytes().begin(),
+                    ipv6_address.bytes().begin() + 4u);
+      bytes->insert(bytes->end(), ipv4_address.bytes().begin(),
+                    ipv4_address.bytes().end());
+      bytes->insert(bytes->end(), std::begin(zero_bits),
+                    std::begin(zero_bits) + 8u);
+      return IPAddress(bytes->data(), bytes->size());
+    case Dns64PrefixLength::kInvalid:
+      return ipv4_address;
+  }
+}
+
 }  // namespace net
diff --git a/net/base/ip_address.h b/net/base/ip_address.h
index 57c1dd6..ea00438 100644
--- a/net/base/ip_address.h
+++ b/net/base/ip_address.h
@@ -293,6 +293,53 @@
   return std::equal(prefix, prefix + N, address.bytes().begin());
 }
 
+// According to RFC6052 Section 2.2 IPv4-Embedded IPv6 Address Format.
+// https://www.rfc-editor.org/rfc/rfc6052#section-2.2
+// +--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+// |PL| 0-------------32--40--48--56--64--72--80--88--96--104---------|
+// +--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+// |32|     prefix    |v4(32)         | u | suffix                    |
+// +--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+// |40|     prefix        |v4(24)     | u |(8)| suffix                |
+// +--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+// |48|     prefix            |v4(16) | u | (16)  | suffix            |
+// +--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+// |56|     prefix                |(8)| u |  v4(24)   | suffix        |
+// +--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+// |64|     prefix                    | u |   v4(32)      | suffix    |
+// +--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+// |96|     prefix                                    |    v4(32)     |
+// +--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+//
+// The NAT64/DNS64 translation prefixes has one of the following lengths.
+enum class Dns64PrefixLength {
+  k32bit,
+  k40bit,
+  k48bit,
+  k56bit,
+  k64bit,
+  k96bit,
+  kInvalid
+};
+
+// Extracts the NAT64 translation prefix from the IPv6 address using the well
+// known address ipv4only.arpa 192.0.0.170 and 192.0.0.171.
+// Returns prefix length on success, or Dns64PrefixLength::kInvalid on failure
+// (when the ipv4only.arpa IPv4 address is not found)
+NET_EXPORT Dns64PrefixLength
+ExtractPref64FromIpv4onlyArpaAAAA(const IPAddress& address);
+
+// Converts an IPv4 address to an IPv4-embedded IPv6 address using the given
+// prefix. For example 192.168.0.1 and 64:ff9b::/96 would be converted to
+// 64:ff9b::192.168.0.1
+// Returns converted IPv6 address when prefix_length is not
+// Dns64PrefixLength::kInvalid, and returns the original IPv4 address when
+// prefix_length is Dns64PrefixLength::kInvalid.
+NET_EXPORT IPAddress
+ConvertIPv4ToIPv4EmbeddedIPv6(const IPAddress& ipv4_address,
+                              const IPAddress& ipv6_address,
+                              Dns64PrefixLength prefix_length);
+
 }  // namespace net
 
 #endif  // NET_BASE_IP_ADDRESS_H_
diff --git a/net/base/ip_address_unittest.cc b/net/base/ip_address_unittest.cc
index 8385cba..1345bcd 100644
--- a/net/base/ip_address_unittest.cc
+++ b/net/base/ip_address_unittest.cc
@@ -677,6 +677,160 @@
   }
 }
 
+// Tests extraction of the NAT64 translation prefix.
+TEST(IPAddressTest, ExtractPref64FromIpv4onlyArpaAAAA) {
+  // Well Known Prefix 64:ff9b::/96.
+  IPAddress ipv6_address_WKP_0(0, 100, 255, 155, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0,
+                               0, 170);
+  IPAddress ipv6_address_WKP_1(0, 100, 255, 155, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0,
+                               0, 171);
+  Dns64PrefixLength pref64_length_WKP_0 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_WKP_0);
+  Dns64PrefixLength pref64_length_WKP_1 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_WKP_1);
+  EXPECT_EQ(Dns64PrefixLength::k96bit, pref64_length_WKP_0);
+  EXPECT_EQ(Dns64PrefixLength::k96bit, pref64_length_WKP_1);
+
+  // Prefix length 96
+  IPAddress ipv6_address_96_0(32, 1, 13, 184, 1, 34, 3, 68, 0, 0, 0, 0, 192, 0,
+                              0, 170);
+  IPAddress ipv6_address_96_1(32, 1, 13, 184, 1, 34, 3, 68, 0, 0, 0, 0, 192, 0,
+                              0, 171);
+  Dns64PrefixLength pref64_length_96_0 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_96_0);
+  Dns64PrefixLength pref64_length_96_1 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_96_1);
+  EXPECT_EQ(Dns64PrefixLength::k96bit, pref64_length_96_0);
+  EXPECT_EQ(Dns64PrefixLength::k96bit, pref64_length_96_1);
+
+  // Prefix length 64
+  IPAddress ipv6_address_64_0(32, 1, 13, 184, 1, 34, 3, 68, 0, 192, 0, 0, 170,
+                              0, 0, 0);
+  IPAddress ipv6_address_64_1(32, 1, 13, 184, 1, 34, 3, 68, 0, 192, 0, 0, 171,
+                              0, 0, 0);
+  Dns64PrefixLength pref64_length_64_0 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_64_0);
+  Dns64PrefixLength pref64_length_64_1 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_64_1);
+  EXPECT_EQ(Dns64PrefixLength::k64bit, pref64_length_64_0);
+  EXPECT_EQ(Dns64PrefixLength::k64bit, pref64_length_64_1);
+
+  // Prefix length 56
+  IPAddress ipv6_address_56_0(32, 1, 13, 184, 1, 34, 3, 192, 0, 0, 0, 170, 0, 0,
+                              0, 0);
+  IPAddress ipv6_address_56_1(32, 1, 13, 184, 1, 34, 3, 192, 0, 0, 0, 171, 0, 0,
+                              0, 0);
+  Dns64PrefixLength pref64_length_56_0 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_56_0);
+  Dns64PrefixLength pref64_length_56_1 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_56_1);
+  EXPECT_EQ(Dns64PrefixLength::k56bit, pref64_length_56_0);
+  EXPECT_EQ(Dns64PrefixLength::k56bit, pref64_length_56_1);
+
+  // Prefix length 48
+  IPAddress ipv6_address_48_0(32, 1, 13, 184, 1, 34, 192, 0, 0, 0, 170, 0, 0, 0,
+                              0, 0);
+  IPAddress ipv6_address_48_1(32, 1, 13, 184, 1, 34, 192, 0, 0, 0, 171, 0, 0, 0,
+                              0, 0);
+  Dns64PrefixLength pref64_length_48_0 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_48_0);
+  Dns64PrefixLength pref64_length_48_1 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_48_1);
+  EXPECT_EQ(Dns64PrefixLength::k48bit, pref64_length_48_0);
+  EXPECT_EQ(Dns64PrefixLength::k48bit, pref64_length_48_1);
+
+  // Prefix length 40
+  IPAddress ipv6_address_40_0(32, 1, 13, 184, 1, 192, 0, 0, 0, 170, 0, 0, 0, 0,
+                              0, 0);
+  IPAddress ipv6_address_40_1(32, 1, 13, 184, 1, 192, 0, 0, 0, 171, 0, 0, 0, 0,
+                              0, 0);
+  Dns64PrefixLength pref64_length_40_0 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_40_0);
+  Dns64PrefixLength pref64_length_40_1 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_40_1);
+  EXPECT_EQ(Dns64PrefixLength::k40bit, pref64_length_40_0);
+  EXPECT_EQ(Dns64PrefixLength::k40bit, pref64_length_40_1);
+
+  // Prefix length 32
+  IPAddress ipv6_address_32_0(32, 1, 13, 184, 192, 0, 0, 170, 0, 0, 0, 0, 0, 0,
+                              0, 0);
+  IPAddress ipv6_address_32_1(32, 1, 13, 184, 192, 0, 0, 171, 0, 0, 0, 0, 0, 0,
+                              0, 0);
+  Dns64PrefixLength pref64_length_32_0 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_32_0);
+  Dns64PrefixLength pref64_length_32_1 =
+      ExtractPref64FromIpv4onlyArpaAAAA(ipv6_address_32_1);
+  EXPECT_EQ(Dns64PrefixLength::k32bit, pref64_length_32_0);
+  EXPECT_EQ(Dns64PrefixLength::k32bit, pref64_length_32_1);
+}
+
+// Tests mapping an IPv4 address to an IPv6 address.
+TEST(IPAddressTest, ConvertIPv4ToIPv4EmbeddedIPv6) {
+  IPAddress ipv4_address(192, 0, 2, 33);
+
+  // Well Known Prefix 64:ff9b::/96.
+  IPAddress ipv6_address_WKP(0, 100, 255, 155, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0,
+                             0, 170);
+  IPAddress converted_ipv6_address_WKP = ConvertIPv4ToIPv4EmbeddedIPv6(
+      ipv4_address, ipv6_address_WKP, Dns64PrefixLength::k96bit);
+  EXPECT_EQ("0,100,255,155,0,0,0,0,0,0,0,0,192,0,2,33",
+            DumpIPAddress(converted_ipv6_address_WKP));
+  EXPECT_EQ("64:ff9b::c000:221", converted_ipv6_address_WKP.ToString());
+
+  // Prefix length 96
+  IPAddress ipv6_address_96(32, 1, 13, 184, 1, 34, 3, 68, 0, 0, 0, 0, 0, 0, 0,
+                            0);
+  IPAddress converted_ipv6_address_96 = ConvertIPv4ToIPv4EmbeddedIPv6(
+      ipv4_address, ipv6_address_96, Dns64PrefixLength::k96bit);
+  EXPECT_EQ("32,1,13,184,1,34,3,68,0,0,0,0,192,0,2,33",
+            DumpIPAddress(converted_ipv6_address_96));
+  EXPECT_EQ("2001:db8:122:344::c000:221", converted_ipv6_address_96.ToString());
+
+  // Prefix length 64
+  IPAddress ipv6_address_64(32, 1, 13, 184, 1, 34, 3, 68, 0, 0, 0, 0, 0, 0, 0,
+                            0);
+  IPAddress converted_ipv6_address_64 = ConvertIPv4ToIPv4EmbeddedIPv6(
+      ipv4_address, ipv6_address_64, Dns64PrefixLength::k64bit);
+  EXPECT_EQ("32,1,13,184,1,34,3,68,0,192,0,2,33,0,0,0",
+            DumpIPAddress(converted_ipv6_address_64));
+  EXPECT_EQ("2001:db8:122:344:c0:2:2100:0",
+            converted_ipv6_address_64.ToString());
+
+  // Prefix length 56
+  IPAddress ipv6_address_56(32, 1, 13, 184, 1, 34, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+                            0);
+  IPAddress converted_ipv6_address_56 = ConvertIPv4ToIPv4EmbeddedIPv6(
+      ipv4_address, ipv6_address_56, Dns64PrefixLength::k56bit);
+  EXPECT_EQ("32,1,13,184,1,34,3,192,0,0,2,33,0,0,0,0",
+            DumpIPAddress(converted_ipv6_address_56));
+  EXPECT_EQ("2001:db8:122:3c0:0:221::", converted_ipv6_address_56.ToString());
+
+  // Prefix length 48
+  IPAddress ipv6_address_48(32, 1, 13, 184, 1, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                            0);
+  IPAddress converted_ipv6_address_48 = ConvertIPv4ToIPv4EmbeddedIPv6(
+      ipv4_address, ipv6_address_48, Dns64PrefixLength::k48bit);
+  EXPECT_EQ("32,1,13,184,1,34,192,0,0,2,33,0,0,0,0,0",
+            DumpIPAddress(converted_ipv6_address_48));
+  EXPECT_EQ("2001:db8:122:c000:2:2100::", converted_ipv6_address_48.ToString());
+
+  // Prefix length 40
+  IPAddress ipv6_address_40(32, 1, 13, 184, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+  IPAddress converted_ipv6_address_40 = ConvertIPv4ToIPv4EmbeddedIPv6(
+      ipv4_address, ipv6_address_40, Dns64PrefixLength::k40bit);
+  EXPECT_EQ("32,1,13,184,1,192,0,2,0,33,0,0,0,0,0,0",
+            DumpIPAddress(converted_ipv6_address_40));
+  EXPECT_EQ("2001:db8:1c0:2:21::", converted_ipv6_address_40.ToString());
+
+  // Prefix length 32
+  IPAddress ipv6_address_32(32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+  IPAddress converted_ipv6_address_32 = ConvertIPv4ToIPv4EmbeddedIPv6(
+      ipv4_address, ipv6_address_32, Dns64PrefixLength::k32bit);
+  EXPECT_EQ("32,1,13,184,192,0,2,33,0,0,0,0,0,0,0,0",
+            DumpIPAddress(converted_ipv6_address_32));
+  EXPECT_EQ("2001:db8:c000:221::", converted_ipv6_address_32.ToString());
+}
+
 }  // anonymous namespace
 
 }  // namespace net
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
index 74389b6..9f4efcb2 100644
--- a/net/dns/BUILD.gn
+++ b/net/dns/BUILD.gn
@@ -62,6 +62,8 @@
     "host_resolver_mdns_listener_impl.h",
     "host_resolver_mdns_task.cc",
     "host_resolver_mdns_task.h",
+    "host_resolver_nat64_task.cc",
+    "host_resolver_nat64_task.h",
     "host_resolver_proc.cc",
     "host_resolver_proc.h",
     "host_resolver_system_task.cc",
diff --git a/net/dns/address_sorter_posix.cc b/net/dns/address_sorter_posix.cc
index 70d4838..d4b83965 100644
--- a/net/dns/address_sorter_posix.cc
+++ b/net/dns/address_sorter_posix.cc
@@ -27,7 +27,6 @@
 
 #include "base/containers/cxx20_erase_vector.h"
 #include "base/containers/unique_ptr_adapters.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
@@ -206,49 +205,49 @@
 
 // Returns true iff |dst_a| should precede |dst_b| in the address list.
 // RFC 3484, section 6.
-bool CompareDestinations(const std::unique_ptr<DestinationInfo>& dst_a,
-                         const std::unique_ptr<DestinationInfo>& dst_b) {
+bool CompareDestinations(const DestinationInfo& dst_a,
+                         const DestinationInfo& dst_b) {
   // Rule 1: Avoid unusable destinations.
   // Unusable destinations are already filtered out.
-  DCHECK(dst_a->src);
-  DCHECK(dst_b->src);
+  DCHECK(dst_a.src);
+  DCHECK(dst_b.src);
 
   // Rule 2: Prefer matching scope.
-  bool scope_match1 = (dst_a->src->scope == dst_a->scope);
-  bool scope_match2 = (dst_b->src->scope == dst_b->scope);
+  bool scope_match1 = (dst_a.src->scope == dst_a.scope);
+  bool scope_match2 = (dst_b.src->scope == dst_b.scope);
   if (scope_match1 != scope_match2)
     return scope_match1;
 
   // Rule 3: Avoid deprecated addresses.
-  if (dst_a->src->deprecated != dst_b->src->deprecated)
-    return !dst_a->src->deprecated;
+  if (dst_a.src->deprecated != dst_b.src->deprecated)
+    return !dst_a.src->deprecated;
 
   // Rule 4: Prefer home addresses.
-  if (dst_a->src->home != dst_b->src->home)
-    return dst_a->src->home;
+  if (dst_a.src->home != dst_b.src->home)
+    return dst_a.src->home;
 
   // Rule 5: Prefer matching label.
-  bool label_match1 = (dst_a->src->label == dst_a->label);
-  bool label_match2 = (dst_b->src->label == dst_b->label);
+  bool label_match1 = (dst_a.src->label == dst_a.label);
+  bool label_match2 = (dst_b.src->label == dst_b.label);
   if (label_match1 != label_match2)
     return label_match1;
 
   // Rule 6: Prefer higher precedence.
-  if (dst_a->precedence != dst_b->precedence)
-    return dst_a->precedence > dst_b->precedence;
+  if (dst_a.precedence != dst_b.precedence)
+    return dst_a.precedence > dst_b.precedence;
 
   // Rule 7: Prefer native transport.
-  if (dst_a->src->native != dst_b->src->native)
-    return dst_a->src->native;
+  if (dst_a.src->native != dst_b.src->native)
+    return dst_a.src->native;
 
   // Rule 8: Prefer smaller scope.
-  if (dst_a->scope != dst_b->scope)
-    return dst_a->scope < dst_b->scope;
+  if (dst_a.scope != dst_b.scope)
+    return dst_a.scope < dst_b.scope;
 
   // Rule 9: Use longest matching prefix. Only for matching address families.
-  if (dst_a->endpoint.address().size() == dst_b->endpoint.address().size()) {
-    if (dst_a->common_prefix_length != dst_b->common_prefix_length)
-      return dst_a->common_prefix_length > dst_b->common_prefix_length;
+  if (dst_a.endpoint.address().size() == dst_b.endpoint.address().size()) {
+    if (dst_a.common_prefix_length != dst_b.common_prefix_length)
+      return dst_a.common_prefix_length > dst_b.common_prefix_length;
   }
 
   // Rule 10: Leave the order unchanged.
@@ -272,17 +271,17 @@
     if (rv != OK) {
       VLOG(1) << "Could not connect to " << dest.ToStringWithoutPort()
               << " reason " << rv;
-      sort_list_[info_index]->failed = true;
+      sort_list_[info_index].failed = true;
       MaybeFinishSort();
       return;
     }
     // Filter out unusable destinations.
     IPEndPoint src;
-    rv = sort_list_[info_index]->socket->GetLocalAddress(&src);
+    rv = sort_list_[info_index].socket->GetLocalAddress(&src);
     if (rv != OK) {
       LOG(WARNING) << "Could not get local address for "
                    << dest.ToStringWithoutPort() << " reason " << rv;
-      sort_list_[info_index]->failed = true;
+      sort_list_[info_index].failed = true;
       MaybeFinishSort();
       return;
     }
@@ -294,21 +293,19 @@
       // want to sort, even though the HostCache will be cleared soon.
       sorter_->FillPolicy(src.address(), &src_info);
     }
-    sort_list_[info_index]->src = &src_info;
+    sort_list_[info_index].src = &src_info;
 
-    if (sort_list_[info_index]->endpoint.address().size() ==
+    if (sort_list_[info_index].endpoint.address().size() ==
         src.address().size()) {
-      sort_list_[info_index]->common_prefix_length = std::min(
-          CommonPrefixLength(sort_list_[info_index]->endpoint.address(),
-                             src.address()),
-          sort_list_[info_index]->src->prefix_length);
+      sort_list_[info_index].common_prefix_length =
+          std::min(CommonPrefixLength(sort_list_[info_index].endpoint.address(),
+                                      src.address()),
+                   sort_list_[info_index].src->prefix_length);
     }
     MaybeFinishSort();
   }
 
-  std::vector<std::unique_ptr<DestinationInfo>>& sort_list() {
-    return sort_list_;
-  }
+  std::vector<DestinationInfo>& sort_list() { return sort_list_; }
 
  private:
   void MaybeFinishSort() {
@@ -316,12 +313,12 @@
     if (num_completed_ != num_endpoints_) {
       return;
     }
-    base::EraseIf(sort_list_, [](auto& element) { return element->failed; });
+    base::EraseIf(sort_list_, [](auto& element) { return element.failed; });
     std::stable_sort(sort_list_.begin(), sort_list_.end(), CompareDestinations);
 
     std::vector<IPEndPoint> sorted_result;
     for (const auto& info : sort_list_)
-      sorted_result.push_back(info->endpoint);
+      sorted_result.push_back(info.endpoint);
 
     CallbackType callback = std::move(callback_);
     sorter_->FinishedSort(this);  // deletes this
@@ -330,7 +327,7 @@
 
   const size_t num_endpoints_;
   size_t num_completed_ = 0;
-  std::vector<std::unique_ptr<DestinationInfo>> sort_list_;
+  std::vector<DestinationInfo> sort_list_;
   AddressSorter::CallbackType callback_;
 
   const AddressSorterPosix* sorter_;
@@ -360,26 +357,25 @@
       endpoints.size(), std::move(callback), this));
   auto* sort_context = sort_contexts_.rbegin()->get();
   for (const IPEndPoint& endpoint : endpoints) {
-    auto info = std::make_unique<DestinationInfo>();
-    info->endpoint = endpoint;
-    info->scope = GetScope(ipv4_scope_table_, info->endpoint.address());
-    info->precedence =
-        GetPolicyValue(precedence_table_, info->endpoint.address());
-    info->label = GetPolicyValue(label_table_, info->endpoint.address());
+    DestinationInfo info;
+    info.endpoint = endpoint;
+    info.scope = GetScope(ipv4_scope_table_, info.endpoint.address());
+    info.precedence =
+        GetPolicyValue(precedence_table_, info.endpoint.address());
+    info.label = GetPolicyValue(label_table_, info.endpoint.address());
 
     // Each socket can only be bound once.
-    info->socket = socket_factory_->CreateDatagramClientSocket(
+    info.socket = socket_factory_->CreateDatagramClientSocket(
         DatagramSocket::DEFAULT_BIND, nullptr /* NetLog */, NetLogSource());
-    IPEndPoint dest = info->endpoint;
+    IPEndPoint dest = info.endpoint;
     // Even though no packets are sent, cannot use port 0 in Connect.
     if (dest.port() == 0) {
       dest = IPEndPoint(dest.address(), /*port=*/80);
     }
-    auto* info_ptr = info.get();
     sort_context->sort_list().push_back(std::move(info));
     size_t info_index = sort_context->sort_list().size() - 1;
     // Destroying a SortContext destroys the underlying socket.
-    int rv = info_ptr->socket->ConnectAsync(
+    int rv = sort_context->sort_list().back().socket->ConnectAsync(
         dest,
         base::BindOnce(&AddressSorterPosix::SortContext::DidCompleteConnect,
                        base::Unretained(sort_context), dest, info_index));
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
index b2087cc..9db789cd 100644
--- a/net/dns/host_resolver_manager.cc
+++ b/net/dns/host_resolver_manager.cc
@@ -84,6 +84,7 @@
 #include "net/dns/host_cache.h"
 #include "net/dns/host_resolver_mdns_listener_impl.h"
 #include "net/dns/host_resolver_mdns_task.h"
+#include "net/dns/host_resolver_nat64_task.h"
 #include "net/dns/host_resolver_proc.h"
 #include "net/dns/host_resolver_system_task.h"
 #include "net/dns/httpssvc_metrics.h"
@@ -2056,6 +2057,9 @@
       case TaskType::INSECURE_CACHE_LOOKUP:
         InsecureCacheLookup();
         break;
+      case TaskType::NAT64:
+        StartNat64Task();
+        break;
       case TaskType::SECURE_CACHE_LOOKUP:
       case TaskType::CACHE_LOOKUP:
       case TaskType::CONFIG_PRESET:
@@ -2464,6 +2468,23 @@
     CompleteRequestsWithError(rv);
   }
 
+  void StartNat64Task() {
+    DCHECK(!nat64_task_);
+    RequestImpl* req = requests_.head()->value();
+    nat64_task_ = std::make_unique<HostResolverNat64Task>(
+        std::string{GetHostname(key_.host)}, req->network_anonymization_key(),
+        req->source_net_log(), req->resolve_context(), req->host_cache(),
+        resolver_);
+    nat64_task_->Start(base::BindOnce(&Job::OnNat64TaskComplete,
+                                      weak_ptr_factory_.GetWeakPtr()));
+  }
+
+  void OnNat64TaskComplete() {
+    DCHECK(nat64_task_);
+    HostCache::Entry results = nat64_task_->GetResults();
+    CompleteRequestsWithoutCache(results, absl::nullopt /* stale_info */);
+  }
+
   void RecordJobHistograms(int error) {
     // Used in UMA_HISTOGRAM_ENUMERATION. Do not renumber entries or reuse
     // deprecated values.
@@ -2679,6 +2700,9 @@
   // Resolves the host using MDnsClient.
   std::unique_ptr<HostResolverMdnsTask> mdns_task_;
 
+  // Perform NAT64 address synthesis to a given IPv4 literal.
+  std::unique_ptr<HostResolverNat64Task> nat64_task_;
+
   // All Requests waiting for the result of this Job. Some can be canceled.
   base::LinkedList<RequestImpl> requests_;
 
@@ -3031,7 +3055,8 @@
   absl::optional<HostCache::EntryStaleness> stale_info;
   HostCache::Entry results = ResolveLocally(
       job_key, ip_address, parameters.cache_usage, parameters.secure_dns_policy,
-      request->source_net_log(), request->host_cache(), &tasks, &stale_info);
+      parameters.source, request->source_net_log(), request->host_cache(),
+      &tasks, &stale_info);
   if (results.error() != ERR_DNS_CACHE_MISS ||
       request->parameters().source == HostResolverSource::LOCAL_ONLY ||
       tasks.empty()) {
@@ -3055,6 +3080,7 @@
     const IPAddress& ip_address,
     ResolveHostParameters::CacheUsage cache_usage,
     SecureDnsPolicy secure_dns_policy,
+    HostResolverSource source,
     const NetLogWithSource& source_net_log,
     HostCache* cache,
     std::deque<TaskType>* out_tasks,
@@ -3092,8 +3118,19 @@
                             HostCache::Entry::SOURCE_UNKNOWN);
   }
 
-  if (ip_address.IsValid())
+  if (ip_address.IsValid()) {
+    // Use NAT64Task for IPv4 literal when the network is IPv6 only.
+    if (!default_family_due_to_no_ipv6 && ip_address.IsIPv4() &&
+        base::FeatureList::IsEnabled(features::kUseNAT64ForIPv4Literal) &&
+        !IsGloballyReachable(IPAddress(ip_address), source_net_log) &&
+        source != HostResolverSource::LOCAL_ONLY) {
+      out_tasks->push_front(TaskType::NAT64);
+      return HostCache::Entry(ERR_DNS_CACHE_MISS,
+                              HostCache::Entry::SOURCE_UNKNOWN);
+    }
+
     return ResolveAsIP(job_key.query_types, resolve_canonname, ip_address);
+  }
 
   // Special-case localhost names, as per the recommendations in
   // https://tools.ietf.org/html/draft-west-let-localhost-be-localhost.
@@ -3718,18 +3755,16 @@
   rv = socket->GetLocalAddress(&endpoint);
   if (rv != OK)
     return false;
-  DCHECK_EQ(ADDRESS_FAMILY_IPV6, endpoint.GetFamily());
   const IPAddress& address = endpoint.address();
 
-  bool is_link_local =
-      (address.bytes()[0] == 0xFE) && ((address.bytes()[1] & 0xC0) == 0x80);
-  if (is_link_local)
+  if (address.IsLinkLocal())
     return false;
 
-  const uint8_t kTeredoPrefix[] = {0x20, 0x01, 0, 0};
-  if (IPAddressStartsWith(address, kTeredoPrefix))
-    return false;
-
+  if (address.IsIPv6()) {
+    const uint8_t kTeredoPrefix[] = {0x20, 0x01, 0, 0};
+    if (IPAddressStartsWith(address, kTeredoPrefix))
+      return false;
+  }
   return true;
 }
 
diff --git a/net/dns/host_resolver_manager.h b/net/dns/host_resolver_manager.h
index ae65565..962e6e5 100644
--- a/net/dns/host_resolver_manager.h
+++ b/net/dns/host_resolver_manager.h
@@ -285,6 +285,7 @@
     INSECURE_CACHE_LOOKUP,
     SECURE_CACHE_LOOKUP,
     CONFIG_PRESET,
+    NAT64,
   };
 
   // Returns true if the task is local, synchronous, and instantaneous.
@@ -314,7 +315,8 @@
       const IPAddress& ip_address,
       ResolveHostParameters::CacheUsage cache_usage,
       SecureDnsPolicy secure_dns_policy,
-      const NetLogWithSource& request_net_log,
+      HostResolverSource source,
+      const NetLogWithSource& source_net_log,
       HostCache* cache,
       std::deque<TaskType>* out_tasks,
       absl::optional<HostCache::EntryStaleness>* out_stale_info);
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc
index aa4885b..57e84708 100644
--- a/net/dns/host_resolver_manager_unittest.cc
+++ b/net/dns/host_resolver_manager_unittest.cc
@@ -478,18 +478,25 @@
   TestHostResolverManager(const HostResolver::ManagerOptions& options,
                           SystemDnsConfigChangeNotifier* notifier,
                           NetLog* net_log,
-                          bool ipv6_reachable = true)
+                          bool ipv6_reachable = true,
+                          bool ipv4_reachable = true)
       : HostResolverManager(options, notifier, net_log),
-        ipv6_reachable_(ipv6_reachable) {}
+        ipv6_reachable_(ipv6_reachable),
+        ipv4_reachable_(ipv4_reachable) {}
 
   ~TestHostResolverManager() override = default;
 
  private:
   const bool ipv6_reachable_;
+  const bool ipv4_reachable_;
 
   bool IsGloballyReachable(const IPAddress& dest,
                            const NetLogWithSource& net_log) override {
-    return ipv6_reachable_;
+    if (dest.IsIPv6()) {
+      return ipv6_reachable_;
+    } else {
+      return ipv4_reachable_;
+    }
   }
 };
 
@@ -596,14 +603,16 @@
   virtual void CreateResolverWithOptionsAndParams(
       HostResolver::ManagerOptions options,
       const HostResolverSystemTask::Params& params,
-      bool ipv6_reachable) {
+      bool ipv6_reachable,
+      bool ipv4_reachable = true) {
     // Use HostResolverManagerDnsTest if enabling DNS client.
     DCHECK(!options.insecure_dns_client_enabled);
 
     DestroyResolver();
 
     resolver_ = std::make_unique<TestHostResolverManager>(
-        options, nullptr /* notifier */, nullptr /* net_log */, ipv6_reachable);
+        options, nullptr /* notifier */, nullptr /* net_log */, ipv6_reachable,
+        ipv4_reachable);
     resolver_->set_host_resolver_system_params_for_test(params);
 
     resolver_->RegisterResolveContext(resolve_context_.get());
@@ -4262,7 +4271,8 @@
   void CreateResolverWithOptionsAndParams(
       HostResolver::ManagerOptions options,
       const HostResolverSystemTask::Params& params,
-      bool ipv6_reachable) override {
+      bool ipv6_reachable,
+      bool ipv4_reachable = true) override {
     DestroyResolver();
 
     resolver_ = std::make_unique<TestHostResolverManager>(
@@ -13373,4 +13383,148 @@
                   ExpectEndpointResult(AddressesMatch(kRemoteAddrs)))));
 }
 
+TEST_F(HostResolverManagerTest, IPv4AddressLiteralInIPv6OnlyNetwork) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kUseNAT64ForIPv4Literal},
+      /*disabled_features=*/{});
+
+  HostResolver::ManagerOptions options = DefaultOptions();
+  CreateResolverWithOptionsAndParams(std::move(options), DefaultParams(proc_),
+                                     true /* ipv6_reachable */,
+                                     false /* ipv4_reachable */);
+  proc_->AddRule("ipv4only.arpa", ADDRESS_FAMILY_IPV6,
+                 "64:ff9b::c000:aa,64:ff9b::c000:ab,2001:db8:43::c000:aa,"
+                 "2001:db8:43::c000:ab");
+  proc_->SignalMultiple(1u);
+
+  ResolveHostResponseHelper response(resolver_->CreateRequest(
+      HostPortPair("192.168.1.42", 80), NetworkAnonymizationKey(),
+      NetLogWithSource(), absl::nullopt, resolve_context_.get(),
+      resolve_context_->host_cache()));
+
+  EXPECT_THAT(response.result_error(), IsOk());
+  EXPECT_THAT(response.top_level_result_error(), IsOk());
+  EXPECT_THAT(
+      response.request()->GetAddressResults()->endpoints(),
+      testing::ElementsAre(CreateExpected("64:ff9b::c0a8:12a", 80),
+                           CreateExpected("2001:db8:43::c0a8:12a", 80)));
+  EXPECT_THAT(
+      response.request()->GetEndpointResults(),
+      testing::Pointee(testing::ElementsAre(ExpectEndpointResult(
+          testing::ElementsAre(CreateExpected("64:ff9b::c0a8:12a", 80),
+                               CreateExpected("2001:db8:43::c0a8:12a", 80))))));
+  EXPECT_FALSE(response.request()->GetStaleInfo());
+
+  ASSERT_TRUE(!proc_->GetCaptureList().empty());
+  EXPECT_EQ("ipv4only.arpa", proc_->GetCaptureList()[0].hostname);
+
+  const std::pair<const HostCache::Key, HostCache::Entry>* cache_result =
+      GetCacheHit(HostCache::Key(
+          "ipv4only.arpa", DnsQueryType::AAAA, 0 /* host_resolver_flags */,
+          HostResolverSource::ANY, NetworkAnonymizationKey()));
+  EXPECT_TRUE(cache_result);
+}
+
+TEST_F(HostResolverManagerTest, IPv4AddressLiteralInIPv6OnlyNetworkPort443) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kUseNAT64ForIPv4Literal},
+      /*disabled_features=*/{});
+
+  HostResolver::ManagerOptions options = DefaultOptions();
+  CreateResolverWithOptionsAndParams(std::move(options), DefaultParams(proc_),
+                                     true /* ipv6_reachable */,
+                                     false /* ipv4_reachable */);
+  proc_->AddRule("ipv4only.arpa", ADDRESS_FAMILY_IPV6,
+                 "64:ff9b::c000:aa,64:ff9b::c000:ab,2001:db8:43::c000:aa,"
+                 "2001:db8:43::c000:ab");
+  proc_->SignalMultiple(1u);
+
+  ResolveHostResponseHelper response(resolver_->CreateRequest(
+      HostPortPair("192.168.1.42", 443), NetworkAnonymizationKey(),
+      NetLogWithSource(), absl::nullopt, resolve_context_.get(),
+      resolve_context_->host_cache()));
+
+  EXPECT_THAT(response.result_error(), IsOk());
+  EXPECT_THAT(response.top_level_result_error(), IsOk());
+  EXPECT_THAT(
+      response.request()->GetAddressResults()->endpoints(),
+      testing::ElementsAre(CreateExpected("64:ff9b::c0a8:12a", 443),
+                           CreateExpected("2001:db8:43::c0a8:12a", 443)));
+  EXPECT_THAT(response.request()->GetEndpointResults(),
+              testing::Pointee(testing::ElementsAre(
+                  ExpectEndpointResult(testing::ElementsAre(
+                      CreateExpected("64:ff9b::c0a8:12a", 443),
+                      CreateExpected("2001:db8:43::c0a8:12a", 443))))));
+  EXPECT_FALSE(response.request()->GetStaleInfo());
+
+  ASSERT_TRUE(!proc_->GetCaptureList().empty());
+  EXPECT_EQ("ipv4only.arpa", proc_->GetCaptureList()[0].hostname);
+
+  const std::pair<const HostCache::Key, HostCache::Entry>* cache_result =
+      GetCacheHit(HostCache::Key(
+          "ipv4only.arpa", DnsQueryType::AAAA, 0 /* host_resolver_flags */,
+          HostResolverSource::ANY, NetworkAnonymizationKey()));
+  EXPECT_TRUE(cache_result);
+}
+
+TEST_F(HostResolverManagerTest, IPv4AddressLiteralInIPv6OnlyNetworkNoDns64) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kUseNAT64ForIPv4Literal},
+      /*disabled_features=*/{});
+
+  HostResolver::ManagerOptions options = DefaultOptions();
+  CreateResolverWithOptionsAndParams(std::move(options), DefaultParams(proc_),
+                                     true /* ipv6_reachable */,
+                                     false /* ipv4_reachable */);
+  proc_->AddRule("ipv4only.arpa", ADDRESS_FAMILY_IPV6, std::string());
+  proc_->SignalMultiple(1u);
+
+  ResolveHostResponseHelper response(resolver_->CreateRequest(
+      HostPortPair("192.168.1.42", 80), NetworkAnonymizationKey(),
+      NetLogWithSource(), absl::nullopt, resolve_context_.get(),
+      resolve_context_->host_cache()));
+
+  EXPECT_THAT(response.result_error(), IsOk());
+  EXPECT_THAT(response.top_level_result_error(), IsOk());
+  EXPECT_THAT(response.request()->GetAddressResults()->endpoints(),
+              testing::ElementsAre(CreateExpected("192.168.1.42", 80)));
+  EXPECT_THAT(response.request()->GetEndpointResults(),
+              testing::Pointee(testing::ElementsAre(ExpectEndpointResult(
+                  testing::ElementsAre(CreateExpected("192.168.1.42", 80))))));
+  EXPECT_FALSE(response.request()->GetStaleInfo());
+}
+
+// Test when DNS returns bad IPv6 address of ipv4only.arpa., and the
+// IPv4 address of ipv4only.arpa is not contained in the IPv6 address.
+TEST_F(HostResolverManagerTest, IPv4AddressLiteralInIPv6OnlyNetworkBadAddress) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kUseNAT64ForIPv4Literal},
+      /*disabled_features=*/{});
+
+  HostResolver::ManagerOptions options = DefaultOptions();
+  CreateResolverWithOptionsAndParams(std::move(options), DefaultParams(proc_),
+                                     true /* ipv6_reachable */,
+                                     false /* ipv4_reachable */);
+  proc_->AddRule("ipv4only.arpa", ADDRESS_FAMILY_IPV6, "2001:db8::1");
+  proc_->SignalMultiple(1u);
+
+  ResolveHostResponseHelper response(resolver_->CreateRequest(
+      HostPortPair("192.168.1.42", 80), NetworkAnonymizationKey(),
+      NetLogWithSource(), absl::nullopt, resolve_context_.get(),
+      resolve_context_->host_cache()));
+
+  EXPECT_THAT(response.result_error(), IsOk());
+  EXPECT_THAT(response.top_level_result_error(), IsOk());
+  EXPECT_THAT(response.request()->GetAddressResults()->endpoints(),
+              testing::ElementsAre(CreateExpected("192.168.1.42", 80)));
+  EXPECT_THAT(response.request()->GetEndpointResults(),
+              testing::Pointee(testing::ElementsAre(ExpectEndpointResult(
+                  testing::ElementsAre(CreateExpected("192.168.1.42", 80))))));
+  EXPECT_FALSE(response.request()->GetStaleInfo());
+}
+
 }  // namespace net
diff --git a/net/dns/host_resolver_nat64_task.cc b/net/dns/host_resolver_nat64_task.cc
new file mode 100644
index 0000000..415c24b0
--- /dev/null
+++ b/net/dns/host_resolver_nat64_task.cc
@@ -0,0 +1,171 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/dns/host_resolver_nat64_task.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/check_op.h"
+#include "base/functional/callback.h"
+#include "base/location.h"
+#include "base/memory/raw_ptr.h"
+#include "base/notreached.h"
+#include "base/strings/string_util.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "net/base/address_list.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/dns/host_resolver.h"
+#include "net/dns/host_resolver_manager.h"
+#include "net/dns/public/dns_query_type.h"
+
+namespace net {
+
+HostResolverNat64Task::HostResolverNat64Task(
+    base::StringPiece hostname,
+    NetworkAnonymizationKey network_anonymization_key,
+    NetLogWithSource net_log,
+    ResolveContext* resolve_context,
+    HostCache* host_cache,
+    base::WeakPtr<HostResolverManager> resolver)
+    : hostname_(hostname),
+      network_anonymization_key_(std::move(network_anonymization_key)),
+      net_log_(std::move(net_log)),
+      resolve_context_(resolve_context),
+      host_cache_(host_cache),
+      resolver_(std::move(resolver)) {}
+
+HostResolverNat64Task::~HostResolverNat64Task() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+void HostResolverNat64Task::Start(base::OnceClosure completion_closure) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!completion_closure_);
+
+  completion_closure_ = std::move(completion_closure);
+
+  next_state_ = State::kResolve;
+  int rv = DoLoop(OK);
+  if (rv != ERR_IO_PENDING) {
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, std::move(completion_closure_));
+  }
+}
+
+HostCache::Entry HostResolverNat64Task::GetResults() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!completion_closure_);
+  return results_;
+}
+
+int HostResolverNat64Task::DoLoop(int result) {
+  DCHECK_NE(next_state_, State::kStateNone);
+  int rv = result;
+  do {
+    State state = next_state_;
+    next_state_ = State::kStateNone;
+    switch (state) {
+      case State::kResolve:
+        DCHECK_EQ(OK, rv);
+        rv = DoResolve();
+        break;
+      case State::kResolveComplete:
+        rv = DoResolveComplete(rv);
+        break;
+      case State::kSynthesizeToIpv6:
+        DCHECK_EQ(OK, rv);
+        rv = DoSynthesizeToIpv6();
+        break;
+      default:
+        NOTREACHED();
+        rv = ERR_FAILED;
+        break;
+    }
+  } while (rv != ERR_IO_PENDING && next_state_ != State::kStateNone);
+  return rv;
+}
+
+int HostResolverNat64Task::DoResolve() {
+  next_state_ = State::kResolveComplete;
+  HostResolver::ResolveHostParameters parameters;
+  parameters.dns_query_type = DnsQueryType::AAAA;
+
+  if (!resolver_) {
+    return ERR_FAILED;
+  }
+
+  request_ipv4onlyarpa_ = resolver_->CreateRequest(
+      HostPortPair("ipv4only.arpa", 80), network_anonymization_key_, net_log_,
+      parameters, resolve_context_, host_cache_);
+
+  return request_ipv4onlyarpa_->Start(base::BindOnce(
+      &HostResolverNat64Task::OnIOComplete, weak_ptr_factory_.GetWeakPtr()));
+}
+
+int HostResolverNat64Task::DoResolveComplete(int result) {
+  // If not under DNS64 and resolving ipv4only.arpa fails, return the original
+  // IPv4 address.
+  if (result != OK || request_ipv4onlyarpa_->GetEndpointResults()->empty()) {
+    IPAddress ipv4_address;
+    bool is_ip = ipv4_address.AssignFromIPLiteral(hostname_);
+    DCHECK(is_ip);
+    std::set<std::string> aliases;
+    results_ =
+        HostCache::Entry(OK, {IPEndPoint(ipv4_address, 0)}, std::move(aliases),
+                         HostCache::Entry::SOURCE_UNKNOWN);
+    return OK;
+  }
+
+  next_state_ = State::kSynthesizeToIpv6;
+  return OK;
+}
+
+int HostResolverNat64Task::DoSynthesizeToIpv6() {
+  IPAddress ipv4_address;
+  bool is_ip = ipv4_address.AssignFromIPLiteral(hostname_);
+  DCHECK(is_ip);
+
+  IPAddress ipv4onlyarpa_AAAA_address;
+
+  std::vector<IPEndPoint> converted_addresses;
+
+  for (const auto& endpoints : *request_ipv4onlyarpa_->GetEndpointResults()) {
+    for (const auto& ip_endpoint : endpoints.ip_endpoints) {
+      ipv4onlyarpa_AAAA_address = ip_endpoint.address();
+
+      Dns64PrefixLength pref64_length =
+          ExtractPref64FromIpv4onlyArpaAAAA(ipv4onlyarpa_AAAA_address);
+
+      IPAddress converted_address = ConvertIPv4ToIPv4EmbeddedIPv6(
+          ipv4_address, ipv4onlyarpa_AAAA_address, pref64_length);
+
+      IPEndPoint converted_ip_endpoint(converted_address, 0);
+      if (std::find(converted_addresses.begin(), converted_addresses.end(),
+                    converted_ip_endpoint) == converted_addresses.end()) {
+        converted_addresses.push_back(std::move(converted_ip_endpoint));
+      }
+    }
+  }
+
+  std::set<std::string> aliases;
+
+  if (converted_addresses.empty()) {
+    converted_addresses = {IPEndPoint(ipv4_address, 0)};
+  }
+
+  results_ = HostCache::Entry(OK, converted_addresses, std::move(aliases),
+                              HostCache::Entry::SOURCE_UNKNOWN);
+  return OK;
+}
+
+void HostResolverNat64Task::OnIOComplete(int result) {
+  result = DoLoop(result);
+  if (result != ERR_IO_PENDING)
+    std::move(completion_closure_).Run();
+}
+
+}  // namespace net
diff --git a/net/dns/host_resolver_nat64_task.h b/net/dns/host_resolver_nat64_task.h
new file mode 100644
index 0000000..01fb4ffb
--- /dev/null
+++ b/net/dns/host_resolver_nat64_task.h
@@ -0,0 +1,85 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_DNS_HOST_RESOLVER_NAT64_TASK_H_
+#define NET_DNS_HOST_RESOLVER_NAT64_TASK_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/functional/callback_forward.h"
+#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "net/dns/host_resolver.h"
+#include "net/dns/host_resolver_manager.h"
+#include "net/dns/public/dns_query_type.h"
+
+namespace net {
+
+class HostCache;
+
+// Representation of a single HostResolverImpl::Job task to convert an IPv4
+// address literal to an IPv4-Embedded IPv6 according to rfc6052.
+// https://www.rfc-editor.org/rfc/rfc6052
+// When a DNS64 is not found returns the original IPv4 address.
+// Destruction cancels the task and prevents any callbacks from being invoked.
+class HostResolverNat64Task {
+ public:
+  HostResolverNat64Task(base::StringPiece hostname,
+                        NetworkAnonymizationKey network_anonymization_key,
+                        NetLogWithSource net_log,
+                        ResolveContext* resolve_context,
+                        HostCache* host_cache,
+                        base::WeakPtr<HostResolverManager> resolver);
+
+  HostResolverNat64Task(const HostResolverNat64Task&) = delete;
+  HostResolverNat64Task& operator=(const HostResolverNat64Task&) = delete;
+
+  ~HostResolverNat64Task();
+
+  // Should only be called once.
+  void Start(base::OnceClosure completion_closure);
+
+  // Results only available after invocation of the completion closure.
+  HostCache::Entry GetResults() const;
+
+ private:
+  const std::string hostname_;
+  const NetworkAnonymizationKey network_anonymization_key_;
+  NetLogWithSource net_log_;
+  const raw_ptr<ResolveContext> resolve_context_;
+  const raw_ptr<HostCache> host_cache_;
+  base::OnceClosure completion_closure_;
+  base::WeakPtr<HostResolverManager> resolver_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  int DoResolve();
+  int DoResolveComplete(int result);
+  int DoSynthesizeToIpv6();
+
+  void OnIOComplete(int result);
+  int DoLoop(int result);
+
+  enum class State {
+    kResolve,
+    kResolveComplete,
+    kSynthesizeToIpv6,
+    kStateNone,
+  };
+
+  State next_state_ = State::kStateNone;
+
+  std::unique_ptr<HostResolver::ResolveHostRequest> request_ipv4onlyarpa_;
+
+  HostCache::Entry results_ =
+      HostCache::Entry(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
+  base::WeakPtrFactory<HostResolverNat64Task> weak_ptr_factory_{this};
+};
+
+}  // namespace net
+
+#endif  // NET_DNS_HOST_RESOLVER_NAT64_TASK_H_
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index d67bcac..c7a61a0 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -2401,8 +2401,8 @@
           ],
           "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "ash_crosapi_tests",
-        "test_id_prefix": "ninja://chrome/test:ash_crosapi_tests/"
+        "test": "ash_crosapi_browsertests",
+        "test_id_prefix": "ninja://chrome/test:ash_crosapi_browsertests/"
       },
       {
         "merge": {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index a7d1c0f4..e24e81cd 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -1644,8 +1644,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "ash_crosapi_tests",
-        "test_id_prefix": "ninja://chrome/test:ash_crosapi_tests/"
+        "test": "ash_crosapi_browsertests",
+        "test_id_prefix": "ninja://chrome/test:ash_crosapi_browsertests/"
       },
       {
         "merge": {
@@ -3237,8 +3237,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "ash_crosapi_tests",
-        "test_id_prefix": "ninja://chrome/test:ash_crosapi_tests/"
+        "test": "ash_crosapi_browsertests",
+        "test_id_prefix": "ninja://chrome/test:ash_crosapi_browsertests/"
       },
       {
         "args": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 92a94d66..4bbb59b 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -1674,8 +1674,8 @@
           "hard_timeout": 7200,
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "ash_crosapi_tests",
-        "test_id_prefix": "ninja://chrome/test:ash_crosapi_tests/"
+        "test": "ash_crosapi_browsertests",
+        "test_id_prefix": "ninja://chrome/test:ash_crosapi_browsertests/"
       },
       {
         "args": [
@@ -93085,8 +93085,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "ash_crosapi_tests",
-        "test_id_prefix": "ninja://chrome/test:ash_crosapi_tests/"
+        "test": "ash_crosapi_browsertests",
+        "test_id_prefix": "ninja://chrome/test:ash_crosapi_browsertests/"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index dade93e..3c3a15e 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -5190,8 +5190,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "ash_crosapi_tests",
-        "test_id_prefix": "ninja://chrome/test:ash_crosapi_tests/"
+        "test": "ash_crosapi_browsertests",
+        "test_id_prefix": "ninja://chrome/test:ash_crosapi_browsertests/"
       },
       {
         "args": [
@@ -7054,8 +7054,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "ash_crosapi_tests",
-        "test_id_prefix": "ninja://chrome/test:ash_crosapi_tests/"
+        "test": "ash_crosapi_browsertests",
+        "test_id_prefix": "ninja://chrome/test:ash_crosapi_browsertests/"
       },
       {
         "args": [
diff --git a/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter b/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter
index 7b04ab09..5785d8a 100644
--- a/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter
+++ b/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter
@@ -21,6 +21,7 @@
 -BackForwardCachePageLoadMetricsObserverBrowserTest.ResponsivenessMetricsNormalizationWithSendingAllLatencies
 -BackForwardCachePageLoadMetricsObserverBrowserTest.ResumesLoggingAfterRestoringFromCacheAfterBackgrounding
 -BackgroundFetchBrowserTest.OfflineItemCollection_VerifyIconReceived
+-BatterySaverBubbleViewTest.DisableModeForSession
 -BrowserShutdownBrowserTest.TwoBrowsersClosingShutdownHistograms
 -CrExtensionsA11yTestWithMultipleExensions.WithExtensions_marquee
 -CrExtensionsA11yTestWithMultipleExensions.WithExtensions_meta_viewport_large
@@ -107,9 +108,14 @@
 -ProfileHelperTest.DeleteSoleProfile
 -ProfilePickerLocalProfileCreationDialogBrowserTest.CancelLocalProfileCreation
 -ReaderModeIconViewBrowserTest.NonSecurePagesNotDistillable
+-RealboxSearchPreloadBrowserTest.SearchPreloadSuccess
 -RegionCaptureBrowserTest.CropToAllowedIfEmbeddedFrameCropsToElementInEmbedded
 -RegionCaptureClonesBrowserTest.CannotUncropClone
 -RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/0
+-RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/5
+-RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/6
+-RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/7
+-RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/8
 -RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/9
 -RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/10
 -RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/11
@@ -137,7 +143,11 @@
 -WebAppBrowserTest.AppInfoOpensPageInfo
 -WebAppBrowserTest.WebAppCreateAndDeleteShortcut
 -WebAppFileHandlingBrowserTest_FeatureSwitchesOff.OsIntegrationIsRemoved
--WebViewTests/WebViewTest.SpatialNavigationJavascriptAPI/SiteIsolationForGuestsEnabled 
+-WebViewTests/WebViewTest.SpatialNavigationJavascriptAPI/SiteIsolationForGuestsEnabled
+-TabStatsTrackerBrowserTest.TabSwitch
+-WebAppBrowserTest.WebAppCreateAndDeleteShortcut
+-WebAppFileHandlingBrowserTest_FeatureSwitchesOff.OsIntegrationIsRemoved
+-WebViewTests/WebViewTest.SpatialNavigationJavascriptAPI/SiteIsolationForGuestsDisabled
 -WorkerDevToolsTest.PauseInSharedWorkerInitialization
 -VariationsSafeModeEndToEndBrowserTest.ExtendedSafeModeEndToEnd
 -_/RegionCaptureSelfCaptureOnlyBrowserTest.CropTo/EmbeddedFrameSelfCapturingAndCroppingToElementInOwnTabsEmbeddedFrame
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 062ea5c0..8ace46e 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -180,8 +180,8 @@
     "label": "//ash/components:ash_components_unittests",
     "type": "windowed_test_launcher",
   },
-  "ash_crosapi_tests": {
-    "label": "//chrome/test:ash_crosapi_tests",
+  "ash_crosapi_browsertests": {
+    "label": "//chrome/test:ash_crosapi_browsertests",
     "type": "windowed_test_launcher",
   },
   "ash_webui_unittests": {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index d7c0a304..8997b6c 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -3819,7 +3819,7 @@
       # Chrome OS only.
       'ash_components_unittests': {},
       # TODO(crbug.com/1351793) Enable on CQ when stable.
-      'ash_crosapi_tests': {
+      'ash_crosapi_browsertests': {
         'ci_only': True,
       },
       'ash_unittests': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index bf51235..06f50c5 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1839,49 +1839,6 @@
             ]
         }
     ],
-    "BackForwardCacheEnabledForNonPluginEmbed": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "fuchsia",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "BackForwardCacheEnabledForNonPluginEmbed"
-                    ]
-                }
-            ]
-        }
-    ],
-    "BackForwardCacheExtendTimeToLive": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "fuchsia",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "params": {
-                        "time_to_live_seconds": "600"
-                    },
-                    "enable_features": [
-                        "BackForwardCacheTimeToLiveControl"
-                    ]
-                }
-            ]
-        }
-    ],
     "BackForwardCacheMemoryControls": [
         {
             "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 4bccf05..179b852 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -97,14 +97,6 @@
              "BackForwardCacheDedicatedWorker",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-BASE_FEATURE(kBackForwardCacheSendNotRestoredReasons,
-             "BackForwardCacheSendNotRestoredReasons",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-const base::FeatureParam<bool>
-    kBackForwardCacheSendNotRestoredReasonsRequiresOriginTrial = {
-        &kBackForwardCacheSendNotRestoredReasons, "requires_origin_trial",
-        false};
-
 // Enable intervention for download that was initiated from or occurred in an ad
 // frame without user activation.
 BASE_FEATURE(kBlockingDownloadsInAdFrameWithoutUserActivation,
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index 478cf8b..df9eabab 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -39,20 +39,6 @@
     kAutomaticLazyFrameLoadingToEmbedLoadingStrategyParam;
 BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kBackForwardCacheDedicatedWorker);
 
-// - kBackForwardCacheSendNotRestoredReasons = {true: {"requires_origin_trial":
-// false}} to enable the features globally.
-// - kBackForwardCacheSendNotRestoredReasons = {true: {"requires_origin_trial":
-// true}} to enable the features only for execution context with OT token.
-BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(
-    kBackForwardCacheSendNotRestoredReasons);
-// If true, the execution context from client request needs to have OT token in
-// it, in addition to `kBackForwardCacheSendNotRestoredReasons` being set to
-// true, such that the API can be enabled. If false, setting
-// `kBackForwardCacheSendNotRestoredReasons` to true enable the API both in
-// Chromium & in Blink.
-BLINK_COMMON_EXPORT extern const base::FeatureParam<bool>
-    kBackForwardCacheSendNotRestoredReasonsRequiresOriginTrial;
-
 BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(
     kBlockingDownloadsInAdFrameWithoutUserActivation);
 BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kConversionMeasurement);
diff --git a/third_party/blink/public/common/performance/largest_contentful_paint_type.h b/third_party/blink/public/common/performance/largest_contentful_paint_type.h
index b42b584a..70f31a09b 100644
--- a/third_party/blink/public/common/performance/largest_contentful_paint_type.h
+++ b/third_party/blink/public/common/performance/largest_contentful_paint_type.h
@@ -20,9 +20,9 @@
   kText = 1 << 1,
 
   kAnimatedImage = 1 << 2,
+  kVideo = 1 << 3,
 
   // The enum values below are not yet used and will be added later.
-  kVideo = 1 << 3,
   kDataURI = 1 << 4,
   kPNG = 1 << 5,
   kJPG = 1 << 6,
diff --git a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
index ba150a2..f80ec017 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
@@ -783,6 +783,7 @@
     kViewTimelineInset = 730,
     kViewTimelineName = 731,
     kToggleVisibility = 732,
+    kInitialLetter = 733,
     // 1. Add new features above this line (don't change the assigned numbers of
     //    the existing items).
     // 2. Run the src/tools/metrics/histograms/update_use_counter_css.py script
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
index 5ab2d10..3a8459f5 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3689,6 +3689,7 @@
   kInteractiveWidgetResizesVisual = 4368,
   kSerivceWorkerFallbackMainResource = 4369,
   kGetDisplayMediaWithoutUserActivation = 4370,
+  kBackForwardCacheNotRestoredReasons = 4371,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/media/url_index.h b/third_party/blink/public/platform/media/url_index.h
index 6c591ca..a5b3f1028 100644
--- a/third_party/blink/public/platform/media/url_index.h
+++ b/third_party/blink/public/platform/media/url_index.h
@@ -82,6 +82,10 @@
 
   bool has_access_control() const { return has_access_control_; }
 
+  bool passed_timing_allow_origin_check() const {
+    return passed_timing_allow_origin_check_;
+  }
+
   const std::string& mime_type() const { return mime_type_; }
 
   // Are HTTP range requests supported?
@@ -140,6 +144,7 @@
   void set_etag(const std::string& etag);
   void set_is_cors_cross_origin(bool is_cors_cross_origin);
   void set_has_access_control();
+  void set_passed_timing_allow_origin_check(bool);
   void set_mime_type(std::string mime_type);
 
   // A redirect has occurred (or we've found a better UrlData for the same
@@ -197,6 +202,9 @@
   const CorsMode cors_mode_;
   bool has_access_control_;
 
+  // Timing-allow-origin
+  bool passed_timing_allow_origin_check_;
+
   // Mime type category (stashed for UMA / metrics).
   std::string mime_type_;
 
diff --git a/third_party/blink/public/platform/web_media_player.h b/third_party/blink/public/platform/web_media_player.h
index da77c66..80801a7 100644
--- a/third_party/blink/public/platform/web_media_player.h
+++ b/third_party/blink/public/platform/web_media_player.h
@@ -239,6 +239,8 @@
   virtual uint64_t AudioDecodedByteCount() const = 0;
   virtual uint64_t VideoDecodedByteCount() const = 0;
 
+  virtual bool PassedTimingAllowOriginCheck() const = 0;
+
   // Set the volume multiplier to control audio ducking.
   // Output volume should be set to |player_volume| * |multiplier|. The range
   // of |multiplier| is [0, 1], where 1 indicates normal (non-ducked) playback.
diff --git a/third_party/blink/public/platform/web_media_player_client.h b/third_party/blink/public/platform/web_media_player_client.h
index a593218..f49537eb 100644
--- a/third_party/blink/public/platform/web_media_player_client.h
+++ b/third_party/blink/public/platform/web_media_player_client.h
@@ -211,6 +211,9 @@
   // TODO(crbug.com/1039252): Remove by merging this method into SizeChanged().
   virtual void DidPlayerSizeChange(const gfx::Size& size) = 0;
 
+  virtual void OnFirstFrame(base::TimeTicks first_frame,
+                            size_t bytes_to_first_frame) = 0;
+
   // Notify the client that one of the state used by Picture-in-Picture has
   // changed. The client will then have to poll the states from the associated
   // WebMediaPlayer.
diff --git a/third_party/blink/public/platform/web_url_response.h b/third_party/blink/public/platform/web_url_response.h
index c9d3e61..d6e7657 100644
--- a/third_party/blink/public/platform/web_url_response.h
+++ b/third_party/blink/public/platform/web_url_response.h
@@ -142,6 +142,7 @@
   void SetIsLegacyTLSVersion(bool);
   void SetHasRangeRequested(bool);
   void SetTimingAllowPassed(bool);
+  bool TimingAllowPassed() const;
 
   void SetSecurityStyle(SecurityStyle);
 
diff --git a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
index 08b60b7..f8c640d 100644
--- a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
+++ b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
@@ -168,6 +168,9 @@
   uint64_t AudioDecodedByteCount() const override;
   uint64_t VideoDecodedByteCount() const override;
 
+  // WebRTC doesn't need TAO checks, as the timing is already available through
+  // getStats().
+  bool PassedTimingAllowOriginCheck() const override { return true; }
   bool HasAvailableVideoFrame() const override;
 
   void SetVolumeMultiplier(double multiplier) override;
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index 00f2eae..568a63a 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -301,6 +301,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_orientation_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_picker_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_picker_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_display_media_stream_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_display_media_stream_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_document_picture_in_picture_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_document_picture_in_picture_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_double_range.cc",
@@ -953,6 +955,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_device_filter.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_device_request_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_device_request_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_media_stream_constraints.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_media_stream_constraints.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_configuration.cc",
@@ -2041,6 +2045,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_graph.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_graph.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_graph_builder.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_graph_builder.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni
index d70e388..6b6f0c0 100644
--- a/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -457,6 +457,7 @@
           "//third_party/blink/renderer/modules/ml/ml_tensor.idl",
           "//third_party/blink/renderer/modules/ml/ml_tensor_info.idl",
           "//third_party/blink/renderer/modules/ml/navigator_ml.idl",
+          "//third_party/blink/renderer/modules/ml/webnn/ml_graph.idl",
           "//third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl",
           "//third_party/blink/renderer/modules/ml/webnn/ml_operand_descriptor.idl",
           "//third_party/blink/renderer/modules/ml/webnn/ml_operand.idl",
diff --git a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
index f509718..4adcf81b 100755
--- a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
+++ b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
@@ -58,6 +58,7 @@
     'absl::optional<StyleOverflowClipMargin>',
     # Aligns like float
     'absl::optional<Length>',
+    'StyleInitialLetter',
     'StyleOffsetRotation',
     'TransformOrigin',
     'ScrollPadding',
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index c886cff..f6dff62 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1372,6 +1372,7 @@
   sources += rebase_path(blink_core_tests_url, "", "url")
   sources += rebase_path(blink_core_tests_workers, "", "workers")
   sources += rebase_path(blink_core_tests_xml, "", "xml")
+  sources += rebase_path(blink_core_tests_xmlhttprequest, "", "xmlhttprequest")
 
   configs += [
     ":blink_core_pch",
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index aabb2bb..80d08cb 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -2849,6 +2849,20 @@
       converter: "ConvertImageOrientation",
     },
     {
+      name: "initial-letter",
+      converter: "ConvertInitialLetter",
+      default_value: "StyleInitialLetter()",
+      field_group: "*",
+      field_template: "external",
+      include_paths: ["third_party/blink/renderer/core/style/style_initial_letter.h"],
+      inherited: false,
+      keywords: ["drop", "normal", "raise"],
+      property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      runtime_flag: "CSSInitialLetter",
+      type_name: "StyleInitialLetter",
+      valid_for_first_letter: true,
+    },
+    {
       name: "isolation",
       property_methods: ["CSSValueFromComputedStyleInternal"],
       field_group: "*",
diff --git a/third_party/blink/renderer/core/css/css_value_keywords.json5 b/third_party/blink/renderer/core/css/css_value_keywords.json5
index 06f26b0..79778e3 100644
--- a/third_party/blink/renderer/core/css/css_value_keywords.json5
+++ b/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -1551,6 +1551,10 @@
     "AAA",
     "AAA-large",
 
+    // initial-letter
+    "drop",
+    "raise",
+
     // basic-shape functions.
     "xywh",
 
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index 90f898e..fbff6a1 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -5617,6 +5617,51 @@
   return list;
 }
 
+CSSValue* ConsumeInitialLetter(CSSParserTokenRange& range,
+                               const CSSParserContext& context) {
+  if (auto* normal = ConsumeIdent<CSSValueID::kNormal>(range))
+    return CSSIdentifierValue::Create(CSSValueID::kNormal);
+
+  CSSValueList* const list = CSSValueList::CreateSpaceSeparated();
+  // ["drop" | "raise"] number[1,Inf]
+  if (auto* sink_type =
+          ConsumeIdent<CSSValueID::kDrop, CSSValueID::kRaise>(range)) {
+    if (auto* size = ConsumeNumber(
+            range, context, CSSPrimitiveValue::ValueRange::kNonNegative)) {
+      if (size->GetFloatValue() < 1)
+        return nullptr;
+      list->Append(*size);
+      list->Append(*sink_type);
+      return list;
+    }
+    return nullptr;
+  }
+
+  // number[1, Inf]
+  // number[1, Inf] ["drop" | "raise"]
+  // number[1, Inf] integer[1, Inf]
+  if (auto* size = ConsumeNumber(range, context,
+                                 CSSPrimitiveValue::ValueRange::kNonNegative)) {
+    if (size->GetFloatValue() < 1)
+      return nullptr;
+    list->Append(*size);
+    if (range.AtEnd())
+      return list;
+    if (auto* sink_type =
+            ConsumeIdent<CSSValueID::kDrop, CSSValueID::kRaise>(range)) {
+      list->Append(*sink_type);
+      return list;
+    }
+    if (auto* sink = ConsumeIntegerOrNumberCalc(
+            range, context, CSSPrimitiveValue::ValueRange::kPositiveInteger)) {
+      list->Append(*sink);
+      return list;
+    }
+  }
+
+  return nullptr;
+}
+
 bool ConsumeRadii(CSSValue* horizontal_radii[4],
                   CSSValue* vertical_radii[4],
                   CSSParserTokenRange& range,
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
index 650eb5c..f8fb1917 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
@@ -478,6 +478,7 @@
 CSSValue* ConsumeOffsetPath(CSSParserTokenRange&, const CSSParserContext&);
 CSSValue* ConsumePathOrNone(CSSParserTokenRange&);
 CSSValue* ConsumeOffsetRotate(CSSParserTokenRange&, const CSSParserContext&);
+CSSValue* ConsumeInitialLetter(CSSParserTokenRange&, const CSSParserContext&);
 
 CSSValue* ConsumeBasicShape(
     CSSParserTokenRange&,
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
index 7203c5f9..dee76f26 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -3679,6 +3679,34 @@
   return CSSIdentifierValue::Create(style.ImageRendering());
 }
 
+const CSSValue* InitialLetter::CSSValueFromComputedStyleInternal(
+    const ComputedStyle& style,
+    const LayoutObject*,
+    bool allow_visited_style) const {
+  const StyleInitialLetter initial_letter = style.InitialLetter();
+  if (initial_letter.IsNormal())
+    return CSSIdentifierValue::Create(CSSValueID::kNormal);
+  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+  list->Append(*CSSNumericLiteralValue::Create(
+      initial_letter.Size(), CSSPrimitiveValue::UnitType::kNumber));
+  if (initial_letter.IsIntegerSink()) {
+    list->Append(*CSSNumericLiteralValue::Create(
+        initial_letter.Sink(), CSSPrimitiveValue::UnitType::kInteger));
+  } else if (initial_letter.IsDrop()) {
+    list->Append(*CSSIdentifierValue::Create(CSSValueID::kDrop));
+  } else if (initial_letter.IsRaise()) {
+    list->Append(*CSSIdentifierValue::Create(CSSValueID::kRaise));
+  }
+  return list;
+}
+
+const CSSValue* InitialLetter::ParseSingleValue(
+    CSSParserTokenRange& range,
+    const CSSParserContext& context,
+    const CSSParserLocalContext&) const {
+  return css_parsing_utils::ConsumeInitialLetter(range, context);
+}
+
 const CSSValue* InlineSize::ParseSingleValue(
     CSSParserTokenRange& range,
     const CSSParserContext& context,
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index 0ea1607..a9fcf416 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -1407,6 +1407,39 @@
   return To<CSSCustomIdentValue>(value).Value();
 }
 
+StyleInitialLetter StyleBuilderConverter::ConvertInitialLetter(
+    StyleResolverState&,
+    const CSSValue& value) {
+  if (auto* normal_value = DynamicTo<CSSIdentifierValue>(value)) {
+    DCHECK_EQ(normal_value->GetValueID(), CSSValueID::kNormal);
+    return StyleInitialLetter::Normal();
+  }
+
+  const auto& list = To<CSSValueList>(value);
+  DCHECK(list.length() == 1 || list.length() == 2);
+  const float size = To<CSSPrimitiveValue>(list.Item(0)).GetFloatValue();
+  DCHECK_GE(size, 1);
+  if (list.length() == 1)
+    return StyleInitialLetter(size);
+
+  const CSSValue& second = list.Item(1);
+  if (auto* sink_type = DynamicTo<CSSIdentifierValue>(second)) {
+    if (sink_type->GetValueID() == CSSValueID::kDrop)
+      return StyleInitialLetter::Drop(size);
+    if (sink_type->GetValueID() == CSSValueID::kRaise)
+      return StyleInitialLetter::Raise(size);
+    NOTREACHED() << "Unexpected sink type " << sink_type;
+    return StyleInitialLetter::Normal();
+  }
+
+  if (auto* sink = DynamicTo<CSSPrimitiveValue>(second)) {
+    DCHECK_GE(sink->GetIntValue(), 1);
+    return StyleInitialLetter(size, sink->GetIntValue());
+  }
+
+  return StyleInitialLetter::Normal();
+}
+
 StyleOffsetRotation StyleBuilderConverter::ConvertOffsetRotate(
     StyleResolverState&,
     const CSSValue& value) {
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
index 3965771..5b14aaf1 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
@@ -189,6 +189,8 @@
                             const CSSValue&);  // clamps to [0,1]
   static AtomicString ConvertNoneOrCustomIdent(StyleResolverState&,
                                                const CSSValue&);
+  static StyleInitialLetter ConvertInitialLetter(StyleResolverState&,
+                                                 const CSSValue&);
   static StyleOffsetRotation ConvertOffsetRotate(StyleResolverState&,
                                                  const CSSValue&);
   static LengthPoint ConvertPosition(StyleResolverState&, const CSSValue&);
diff --git a/third_party/blink/renderer/core/exported/web_media_player_impl_unittest.cc b/third_party/blink/renderer/core/exported/web_media_player_impl_unittest.cc
index 3868fdb1..f2cf26f 100644
--- a/third_party/blink/renderer/core/exported/web_media_player_impl_unittest.cc
+++ b/third_party/blink/renderer/core/exported/web_media_player_impl_unittest.cc
@@ -205,6 +205,7 @@
   MOCK_METHOD1(OnRemotePlaybackDisabled, void(bool));
   MOCK_METHOD0(DidBufferUnderflow, void());
   MOCK_METHOD0(DidSeek, void());
+  MOCK_METHOD2(OnFirstFrame, void(base::TimeTicks, size_t));
   MOCK_METHOD0(OnRequestVideoFrameCallback, void());
   MOCK_METHOD0(GetTextTrackMetadata, Vector<TextTrackMetadata>());
 
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h
index 4f3baed9..2121470 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.h
+++ b/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -527,6 +527,8 @@
   void Repaint() final;
   void DurationChanged() final;
   void SizeChanged() final;
+  void OnFirstFrame(base::TimeTicks frame_time,
+                    size_t bytes_to_first_frame) override {}
 
   void SetCcLayer(cc::Layer*) final;
   WebMediaPlayer::TrackId AddAudioTrack(const WebString&,
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc
index dd5e560..c37e304 100644
--- a/third_party/blink/renderer/core/html/media/html_video_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -58,6 +58,8 @@
 #include "third_party/blink/renderer/core/layout/layout_video.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
 #include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/loader/resource/video_timing.h"
+#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
@@ -402,6 +404,29 @@
   return false;
 }
 
+void HTMLVideoElement::OnFirstFrame(base::TimeTicks frame_time,
+                                    size_t bytes_to_first_frame) {
+  DCHECK(GetWebMediaPlayer());
+  LayoutObject* layout_object = GetLayoutObject();
+  // HasLocalBorderBoxProperties will be false in some cases, specifically
+  // picture-in-picture video may return false here.
+  if (layout_object &&
+      layout_object->FirstFragment().HasLocalBorderBoxProperties()) {
+    VideoTiming* video_timing = MakeGarbageCollected<VideoTiming>();
+    video_timing->SetFirstVideoFrameTime(frame_time);
+    video_timing->SetIsSufficientContentLoadedForPaint();
+    video_timing->SetUrl(currentSrc());
+    video_timing->SetContentSizeForEntropy(bytes_to_first_frame);
+    video_timing->SetTimingAllowPassed(
+        GetWebMediaPlayer()->PassedTimingAllowOriginCheck());
+
+    PaintTimingDetector::NotifyImagePaint(
+        *layout_object, videoVisibleSize(), *video_timing,
+        layout_object->FirstFragment().LocalBorderBoxProperties(),
+        layout_object->AbsoluteBoundingBoxRect());
+  }
+}
+
 void HTMLVideoElement::webkitEnterFullscreen() {
   if (!IsFullscreen()) {
     FullscreenOptions* options = FullscreenOptions::Create();
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.h b/third_party/blink/renderer/core/html/media/html_video_element.h
index 3668036a..fb6a4db7 100644
--- a/third_party/blink/renderer/core/html/media/html_video_element.h
+++ b/third_party/blink/renderer/core/html/media/html_video_element.h
@@ -93,6 +93,9 @@
 
   bool HasAvailableVideoFrame() const;
 
+  void OnFirstFrame(base::TimeTicks frame_time,
+                    size_t bytes_to_first_frame) final;
+
   KURL PosterImageURL() const override;
 
   // Returns whether the current poster image URL is the default for the
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 838c6c5..8765c6e 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -7301,7 +7301,8 @@
       (Parent() && IsWritingModeRoot()) ||
       (IsFixedPositioned() && GetDocument().Printing() &&
        IsA<LayoutView>(Container())) ||
-      ShouldApplySizeContainment() || IsFrameSetIncludingNG())
+      ShouldApplySizeContainment() || IsFrameSetIncludingNG() ||
+      StyleRef().HasLineClamp())
     return kForbidBreaks;
 
   if (engine != kUnknownFragmentationEngine) {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
index 912c1818..5fc4b8f2 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
@@ -419,15 +419,18 @@
   }
 }
 
-void NGFragmentItemsBuilder::ToFragmentItems(const PhysicalSize& outer_size,
-                                             void* data) {
+absl::optional<PhysicalSize> NGFragmentItemsBuilder::ToFragmentItems(
+    const PhysicalSize& outer_size,
+    void* data) {
   DCHECK(text_content_);
   ConvertToPhysical(outer_size);
+  absl::optional<PhysicalSize> new_size;
   if (node_.IsSvgText()) {
-    NGSvgTextLayoutAlgorithm(node_, GetWritingMode())
-        .Layout(TextContent(false), items_);
+    new_size = NGSvgTextLayoutAlgorithm(node_, GetWritingMode())
+                   .Layout(TextContent(false), items_);
   }
   new (data) NGFragmentItems(this);
+  return new_size;
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
index 15b14291..574229a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
@@ -145,7 +145,11 @@
 
   // Build a |NGFragmentItems|. The builder cannot build twice because data set
   // to this builder may be cleared.
-  void ToFragmentItems(const PhysicalSize& outer_size, void* data);
+  //
+  // This function returns new size of the container if the container is an
+  // SVG <text>.
+  absl::optional<PhysicalSize> ToFragmentItems(const PhysicalSize& outer_size,
+                                               void* data);
 
  private:
   void MoveCurrentLogicalLineItemsToMap();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
index 66bc517..810f207 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -383,7 +383,10 @@
         const_cast<NGFragmentItems*>(ComputeItemsAddress());
     DCHECK_EQ(items_builder->GetWritingMode(), block_or_line_writing_mode);
     DCHECK_EQ(items_builder->Direction(), builder->Direction());
-    items_builder->ToFragmentItems(Size(), items);
+    absl::optional<PhysicalSize> new_size =
+        items_builder->ToFragmentItems(Size(), items);
+    if (new_size)
+      size_ = *new_size;
   }
 
   bit_field_.set<HasLayoutOverflowFlag>(has_layout_overflow);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
index 040a24c..a53d49a 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -701,7 +701,7 @@
   OutOfFlowData* CloneOutOfFlowData() const;
 
   Member<LayoutObject> layout_object_;
-  const PhysicalSize size_;
+  PhysicalSize size_;
 
   unsigned has_floating_descendants_for_paint_ : 1;
   unsigned has_adjoining_object_descendants_ : 1;
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
index 11607f04d..b003c77 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
+++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
@@ -228,10 +228,6 @@
   // If our bounds changed, notify the parents.
   if (UpdateTransformAfterLayout(bounds_changed) || bounds_changed)
     SetNeedsBoundariesUpdate();
-  if (bounds_changed) {
-    SetSize(LayoutSize(LayoutUnit(boundaries.right()),
-                       LayoutUnit(boundaries.bottom())));
-  }
 
   UpdateTransformAffectsVectorEffect();
 }
diff --git a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc
index adb3377b4..5a47931 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc
@@ -32,7 +32,7 @@
   DCHECK(node.IsSvgText());
 }
 
-void NGSvgTextLayoutAlgorithm::Layout(
+PhysicalSize NGSvgTextLayoutAlgorithm::Layout(
     const String& ifc_text_content,
     NGFragmentItemsBuilder::ItemWithOffsetList& items) {
   TRACE_EVENT0("blink", "NGSvgTextLayoutAlgorithm::Layout");
@@ -44,12 +44,12 @@
 
   // 1. Setup
   if (!Setup(ifc_text_content.length()))
-    return;
+    return PhysicalSize();
 
   // 2. Set flags and assign initial positions
   SetFlags(ifc_text_content, items);
   if (addressable_count_ == 0)
-    return;
+    return PhysicalSize();
 
   // 3. Resolve character positioning
   // This was already done in PrepareLayout() step. See
@@ -80,7 +80,7 @@
   // 8. Position on path
   PositionOnPath(items);
 
-  WriteBackToFragmentItems(items);
+  return WriteBackToFragmentItems(items);
 }
 
 bool NGSvgTextLayoutAlgorithm::Setup(wtf_size_t approximate_count) {
@@ -741,7 +741,7 @@
   }
 }
 
-void NGSvgTextLayoutAlgorithm::WriteBackToFragmentItems(
+PhysicalSize NGSvgTextLayoutAlgorithm::WriteBackToFragmentItems(
     NGFragmentItemsBuilder::ItemWithOffsetList& items) {
   gfx::RectF unscaled_visual_rect;
   for (const SvgPerCharacterInfo& info : result_) {
@@ -805,6 +805,8 @@
   DCHECK_EQ(base::ranges::find(items.begin() + 1, items.end(),
                                NGFragmentItem::kLine, &NGFragmentItem::Type),
             items.end());
+  return {LayoutUnit(unscaled_visual_rect.right()),
+          LayoutUnit(unscaled_visual_rect.bottom())};
 }
 
 float NGSvgTextLayoutAlgorithm::ScalingFactorAt(
diff --git a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.h
index ab6a2194a..ecaa2216 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.h
@@ -20,8 +20,8 @@
 
   // Apply SVG specific text layout algorithm to |items|.
   // Text items in |items| will be converted to kSVGText type.
-  void Layout(const String& ifc_text_content,
-              NGFragmentItemsBuilder::ItemWithOffsetList& items);
+  PhysicalSize Layout(const String& ifc_text_content,
+                      NGFragmentItemsBuilder::ItemWithOffsetList& items);
 
  private:
   // Returns false if we should skip the following steps.
@@ -41,7 +41,7 @@
   void ApplyAnchoring(const NGFragmentItemsBuilder::ItemWithOffsetList& items);
   void PositionOnPath(const NGFragmentItemsBuilder::ItemWithOffsetList& items);
 
-  void WriteBackToFragmentItems(
+  PhysicalSize WriteBackToFragmentItems(
       NGFragmentItemsBuilder::ItemWithOffsetList& items);
 
   float ScalingFactorAt(const NGFragmentItemsBuilder::ItemWithOffsetList& items,
diff --git a/third_party/blink/renderer/core/loader/build.gni b/third_party/blink/renderer/core/loader/build.gni
index ae4a5977..04d9959 100644
--- a/third_party/blink/renderer/core/loader/build.gni
+++ b/third_party/blink/renderer/core/loader/build.gni
@@ -127,6 +127,7 @@
   "resource/speculation_rules_resource.h",
   "resource/text_resource.cc",
   "resource/text_resource.h",
+  "resource/video_timing.h",
   "resource/xsl_style_sheet_resource.cc",
   "resource/xsl_style_sheet_resource.h",
   "resource_load_observer_for_frame.cc",
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
index 3d86f2df4..aa6087b 100644
--- a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
+++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
@@ -619,6 +619,10 @@
   info_->EmulateLoadStartedForInspector(fetcher, url, initiator_name);
 }
 
+void ImageResourceContent::SetIsSufficientContentLoadedForPaint() {
+  NOTREACHED();
+}
+
 bool ImageResourceContent::IsSufficientContentLoadedForPaint() const {
   return IsLoaded();
 }
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.h b/third_party/blink/renderer/core/loader/resource/image_resource_content.h
index c383c27..834a0dc 100644
--- a/third_party/blink/renderer/core/loader/resource/image_resource_content.h
+++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.h
@@ -114,6 +114,7 @@
   // ImageResourceContent::GetContentStatus() can be different from
   // ImageResource::GetStatus(). Use ImageResourceContent::GetContentStatus().
   ResourceStatus GetContentStatus() const;
+  void SetIsSufficientContentLoadedForPaint() override;
   bool IsSufficientContentLoadedForPaint() const override;
   bool IsLoaded() const;
   bool IsLoading() const;
@@ -122,6 +123,15 @@
   bool IsAnimatedImage() const override;
   bool IsPaintedFirstFrame() const override;
   bool TimingAllowPassed() const override;
+  base::TimeTicks GetFirstVideoFrameTime() const override {
+    // This returns a null time, which is currently used to signal that this is
+    // an animated image, rather than a video, and we should use the
+    // ImagePaintTimingDetector to set the first frame time in the ImageRecord
+    // instead.
+    // TODO(iclelland): Find a better way to set this from IPTD and use it, to
+    // use this for images as well as videos.
+    return base::TimeTicks();
+  }
 
   // Redirecting methods to Resource.
   const KURL& Url() const override;
diff --git a/third_party/blink/renderer/core/loader/resource/video_timing.h b/third_party/blink/renderer/core/loader/resource/video_timing.h
new file mode 100644
index 0000000..5e9de5d
--- /dev/null
+++ b/third_party/blink/renderer/core/loader/resource/video_timing.h
@@ -0,0 +1,66 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_VIDEO_TIMING_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_VIDEO_TIMING_H_
+
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/loader/fetch/media_timing.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+
+namespace blink {
+
+// This class specializes MediaTiming for video-specific timing data. Videos
+// are always considered animated, and have their first frame time set by the
+// HTMLVideoElement when the first frame is presented.
+class VideoTiming final : public GarbageCollected<VideoTiming>,
+                          public MediaTiming {
+ public:
+  VideoTiming() = default;
+
+  void Trace(Visitor* visitor) const override { MediaTiming::Trace(visitor); }
+
+  void SetUrl(const KURL& url) { url_ = url; }
+  const KURL& Url() const override { return url_; }
+
+  void SetIsSufficientContentLoadedForPaint() override { is_loaded_ = true; }
+  bool IsSufficientContentLoadedForPaint() const override { return is_loaded_; }
+
+  bool IsAnimatedImage() const override { return true; }
+  bool IsPaintedFirstFrame() const override {
+    return !first_frame_time_.is_null();
+  }
+  void SetFirstVideoFrameTime(base::TimeTicks time) override {
+    first_frame_time_ = time;
+  }
+  base::TimeTicks GetFirstVideoFrameTime() const override {
+    return first_frame_time_;
+  }
+
+  void SetTimingAllowPassed(bool timing_allow_passed) {
+    timing_allow_passed_ = timing_allow_passed;
+  }
+  bool TimingAllowPassed() const override { return timing_allow_passed_; }
+
+  uint64_t ContentSizeForEntropy() const override {
+    // We don't do anything clever here to try to isolate the encoded size of
+    // just the first frame; if we're calling this, then at least enough data
+    // has been received to display that frame. This will result in a more
+    // lenient entropy estimate for LCP purposes.
+    return content_size_;
+  }
+
+  void SetContentSizeForEntropy(size_t length) { content_size_ = length; }
+
+ private:
+  KURL url_;
+  bool is_loaded_ = false;
+  base::TimeTicks first_frame_time_;
+  bool timing_allow_passed_ = false;
+  size_t content_size_ = 0;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_VIDEO_TIMING_H_
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
index e48681f..7e3444d 100644
--- a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
@@ -332,8 +332,10 @@
         gfx::RectF mapped_visual_rect =
             frame_view_->GetPaintTimingDetector().CalculateVisualRect(
                 image_border, current_paint_chunk_properties);
-        visualizer->DumpImageDebuggingRect(object, mapped_visual_rect,
-                                           media_timing);
+        visualizer->DumpImageDebuggingRect(
+            object, mapped_visual_rect,
+            media_timing.IsSufficientContentLoadedForPaint(),
+            media_timing.Url());
       }
       return true;
     }
@@ -377,8 +379,9 @@
     const MediaTiming& media_timing) {
   if (absl::optional<PaintTimingVisualizer>& visualizer =
           frame_view_->GetPaintTimingDetector().Visualizer()) {
-    visualizer->DumpImageDebuggingRect(object, mapped_visual_rect,
-                                       media_timing);
+    visualizer->DumpImageDebuggingRect(
+        object, mapped_visual_rect,
+        media_timing.IsSufficientContentLoadedForPaint(), media_timing.Url());
   }
   uint64_t rect_size = mapped_visual_rect.size().GetArea();
   // Transform visual rect to window before calling downscale.
@@ -433,7 +436,15 @@
     unsigned current_frame_index) {
   base::WeakPtr<ImageRecord> record = GetPendingImage(record_id);
   DCHECK(record);
-  if (record->first_animated_frame_time.is_null()) {
+  if (!record->media_timing->GetFirstVideoFrameTime().is_null()) {
+    // If this is a video record, then we can get the first frame time from the
+    // MediaTiming object, and can use that to set the first frame time in the
+    // ImageRecord object.
+    record->first_animated_frame_time =
+        record->media_timing->GetFirstVideoFrameTime();
+  } else if (record->first_animated_frame_time.is_null()) {
+    // Otherwise, this is an animated images, and so we should wait for the
+    // presentation callback to fire to set the first frame presentation time.
     record->queue_animated_paint = true;
     QueueToMeasurePaintTime(record_id, record, current_frame_index);
     return true;
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.cc b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
index 772e8f84..9ed8215 100644
--- a/third_party/blink/renderer/core/paint/paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
@@ -280,11 +280,16 @@
     // TODO(yoav): Once we'd enable the kLCPAnimatedImagesReporting flag by
     // default, we'd be able to use the value of
     // largest_image_record->first_animated_frame_time directly.
-    if (image_record && image_record->media_timing &&
-        image_record->media_timing->IsPaintedFirstFrame()) {
-      // Set the animated image flag.
-      largest_contentful_paint_type_ |=
-          blink::LargestContentfulPaintType::kAnimatedImage;
+    if (image_record && image_record->media_timing) {
+      if (!image_record->media_timing->GetFirstVideoFrameTime().is_null()) {
+        // Set the video flag.
+        largest_contentful_paint_type_ |=
+            blink::LargestContentfulPaintType::kVideo;
+      } else if (image_record->media_timing->IsPaintedFirstFrame()) {
+        // Set the animated image flag.
+        largest_contentful_paint_type_ |=
+            blink::LargestContentfulPaintType::kAnimatedImage;
+      }
     }
   }
   largest_image_paint_time_ = image_paint_time;
diff --git a/third_party/blink/renderer/core/paint/paint_timing_visualizer.cc b/third_party/blink/renderer/core/paint/paint_timing_visualizer.cc
index ad52bba6..392cf4d 100644
--- a/third_party/blink/renderer/core/paint/paint_timing_visualizer.cc
+++ b/third_party/blink/renderer/core/paint/paint_timing_visualizer.cc
@@ -61,18 +61,17 @@
   DumpTrace(std::move(value));
 }
 
-void PaintTimingVisualizer::DumpImageDebuggingRect(
-    const LayoutObject& object,
-    const gfx::RectF& rect,
-    const MediaTiming& media_timing) {
+void PaintTimingVisualizer::DumpImageDebuggingRect(const LayoutObject& object,
+                                                   const gfx::RectF& rect,
+                                                   bool is_loaded,
+                                                   const KURL& url) {
   std::unique_ptr<TracedValue> value = std::make_unique<TracedValue>();
   RecordObject(object, value);
   RecordRects(gfx::ToRoundedRect(rect), value);
   value->SetBoolean("is_image", true);
   value->SetBoolean("is_svg", object.IsSVG());
-  value->SetBoolean("is_image_loaded",
-                    media_timing.IsSufficientContentLoadedForPaint());
-  value->SetString("image_url", media_timing.Url().StrippedForUseAsReferrer());
+  value->SetBoolean("is_image_loaded", is_loaded);
+  value->SetString("image_url", url.StrippedForUseAsReferrer());
   DumpTrace(std::move(value));
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_timing_visualizer.h b/third_party/blink/renderer/core/paint/paint_timing_visualizer.h
index 80f3fda..99b4145 100644
--- a/third_party/blink/renderer/core/paint/paint_timing_visualizer.h
+++ b/third_party/blink/renderer/core/paint/paint_timing_visualizer.h
@@ -17,7 +17,7 @@
 
 class LayoutObject;
 class LocalFrameView;
-class MediaTiming;
+class KURL;
 
 // While Largest Contentful Paint only concerns about the largest contentful
 // rect, the smaller rects used in its computation are helpful for debugging
@@ -33,7 +33,8 @@
   void DumpTextDebuggingRect(const LayoutObject&, const gfx::RectF&);
   void DumpImageDebuggingRect(const LayoutObject&,
                               const gfx::RectF&,
-                              const MediaTiming&);
+                              bool is_loaded,
+                              const KURL& url);
   void RecordMainFrameViewport(LocalFrameView& frame_view);
   inline void OnViewportChanged() { need_recording_viewport = true; }
 
diff --git a/third_party/blink/renderer/core/style/build.gni b/third_party/blink/renderer/core/style/build.gni
index 414c960..2a57383c 100644
--- a/third_party/blink/renderer/core/style/build.gni
+++ b/third_party/blink/renderer/core/style/build.gni
@@ -84,6 +84,8 @@
   "style_inherited_variables.h",
   "style_initial_data.cc",
   "style_initial_data.h",
+  "style_initial_letter.cc",
+  "style_initial_letter.h",
   "style_intrinsic_length.h",
   "style_name.h",
   "style_name_or_keyword.h",
diff --git a/third_party/blink/renderer/core/style/style_initial_letter.cc b/third_party/blink/renderer/core/style/style_initial_letter.cc
new file mode 100644
index 0000000..cf396af
--- /dev/null
+++ b/third_party/blink/renderer/core/style/style_initial_letter.cc
@@ -0,0 +1,53 @@
+// Copyright 2022 The Chromium Authors.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/style/style_initial_letter.h"
+
+#include "base/check_op.h"
+
+namespace blink {
+
+StyleInitialLetter::StyleInitialLetter() = default;
+
+StyleInitialLetter::StyleInitialLetter(float size)
+    : size_(size), sink_(std::floor(size)), sink_type_(kOmitted) {
+  DCHECK_GE(size_, 1);
+  DCHECK_GE(sink_, 1);
+}
+
+StyleInitialLetter::StyleInitialLetter(float size, int sink)
+    : size_(size), sink_(sink), sink_type_(kInteger) {
+  DCHECK_GE(size_, 1);
+  DCHECK_GE(sink_, 1);
+}
+
+StyleInitialLetter::StyleInitialLetter(float size, SinkType sink_type)
+    : size_(size),
+      sink_(sink_type == kDrop ? std::floor(size) : 1),
+      sink_type_(sink_type) {
+  DCHECK_GE(size_, 1);
+  DCHECK_GE(sink_, 1);
+  DCHECK(sink_type_ == kDrop || sink_type_ == kRaise);
+}
+
+bool StyleInitialLetter::operator==(const StyleInitialLetter& other) const {
+  return size_ == other.size_ && sink_ == other.sink_ &&
+         sink_type_ == other.sink_type_;
+}
+
+bool StyleInitialLetter::operator!=(const StyleInitialLetter& other) const {
+  return !operator==(other);
+}
+
+// static
+StyleInitialLetter StyleInitialLetter::Drop(float size) {
+  return StyleInitialLetter(size, kDrop);
+}
+
+// static
+StyleInitialLetter StyleInitialLetter::Raise(float size) {
+  return StyleInitialLetter(size, kRaise);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_initial_letter.h b/third_party/blink/renderer/core/style/style_initial_letter.h
new file mode 100644
index 0000000..700324f
--- /dev/null
+++ b/third_party/blink/renderer/core/style/style_initial_letter.h
@@ -0,0 +1,54 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_INITIAL_LETTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_INITIAL_LETTER_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class CORE_EXPORT StyleInitialLetter {
+  DISALLOW_NEW();
+
+ public:
+  StyleInitialLetter();
+  explicit StyleInitialLetter(float size);
+  StyleInitialLetter(float size, int sink);
+
+  bool operator==(const StyleInitialLetter& other) const;
+  bool operator!=(const StyleInitialLetter& other) const;
+
+  bool IsDrop() const { return sink_type_ == kDrop; }
+  bool IsIntegerSink() const { return sink_type_ == kInteger; }
+  bool IsNormal() const { return !size_; }
+  bool IsRaise() const { return sink_type_ == kRaise; }
+
+  int Sink() const { return sink_; }
+  float Size() const { return size_; }
+
+  static StyleInitialLetter Normal() { return StyleInitialLetter(); }
+  static StyleInitialLetter Drop(float size);
+  static StyleInitialLetter Raise(float size);
+
+ private:
+  enum SinkType {
+    kNone,
+    kOmitted,
+    kInteger,
+    kDrop,
+    kRaise,
+  };
+
+  StyleInitialLetter(float size, SinkType sink_type);
+
+  float size_ = 0;
+  int sink_ = 0;
+  SinkType sink_type_ = kNone;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_INITIAL_LETTER_H_
diff --git a/third_party/blink/renderer/core/timing/performance_navigation_timing.cc b/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
index 6106088..f876407 100644
--- a/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
@@ -384,6 +384,8 @@
           ExecutionContext::From(builder.GetScriptState()))) {
     builder.Add("notRestoredReasons",
                 notRestoredReasons(builder.GetScriptState()));
+    ExecutionContext::From(builder.GetScriptState())
+        ->CountUse(WebFeature::kBackForwardCacheNotRestoredReasons);
   }
 }
 
diff --git a/third_party/blink/renderer/core/xmlhttprequest/build.gni b/third_party/blink/renderer/core/xmlhttprequest/build.gni
index 464e17d..0bb63f1 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/build.gni
+++ b/third_party/blink/renderer/core/xmlhttprequest/build.gni
@@ -11,3 +11,5 @@
   "xml_http_request_upload.cc",
   "xml_http_request_upload.h",
 ]
+
+blink_core_tests_xmlhttprequest = [ "xml_http_request_test.cc" ]
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
index 218f292..6be9820c 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -1483,11 +1483,7 @@
        it != response_.HttpHeaderFields().end(); ++it) {
     // Hide any headers whose name is a forbidden response-header name.
     // This is required for all kinds of filtered responses.
-    //
-    // TODO: Consider removing canLoadLocalResources() call.
-    // crbug.com/567527
-    if (FetchUtils::IsForbiddenResponseHeaderName(it->key) &&
-        !GetExecutionContext()->GetSecurityOrigin()->CanLoadLocalResources()) {
+    if (FetchUtils::IsForbiddenResponseHeaderName(it->key)) {
       continue;
     }
 
@@ -1522,9 +1518,7 @@
   if (state_ < kHeadersReceived || error_)
     return g_null_atom;
 
-  // See comment in getAllResponseHeaders above.
-  if (FetchUtils::IsForbiddenResponseHeaderName(name) &&
-      !GetExecutionContext()->GetSecurityOrigin()->CanLoadLocalResources()) {
+  if (FetchUtils::IsForbiddenResponseHeaderName(name)) {
     LogConsoleError(GetExecutionContext(),
                     "Refused to get unsafe header \"" + name + "\"");
     return g_null_atom;
@@ -2064,6 +2058,10 @@
   ExecutionContextLifecycleObserver::Trace(visitor);
 }
 
+bool XMLHttpRequest::HasRequestHeaderForTesting(AtomicString name) const {
+  return request_headers_.Contains(name);
+}
+
 std::ostream& operator<<(std::ostream& ostream, const XMLHttpRequest* xhr) {
   return ostream << "XMLHttpRequest " << static_cast<const void*>(xhr);
 }
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
index a09ce201..11fdc0f 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
@@ -33,6 +33,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_trust_token.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
+#include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/document_parser_client.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
@@ -72,11 +73,12 @@
 class URLSearchParams;
 class XMLHttpRequestUpload;
 
-class XMLHttpRequest final : public XMLHttpRequestEventTarget,
-                             public ThreadableLoaderClient,
-                             public DocumentParserClient,
-                             public ActiveScriptWrappable<XMLHttpRequest>,
-                             public ExecutionContextLifecycleObserver {
+class CORE_EXPORT XMLHttpRequest final
+    : public XMLHttpRequestEventTarget,
+      public ThreadableLoaderClient,
+      public DocumentParserClient,
+      public ActiveScriptWrappable<XMLHttpRequest>,
+      public ExecutionContextLifecycleObserver {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
@@ -176,6 +178,8 @@
   void Trace(Visitor*) const override;
   const char* NameInHeapSnapshot() const override { return "XMLHttpRequest"; }
 
+  bool HasRequestHeaderForTesting(AtomicString name) const;
+
  private:
   class BlobLoader;
 
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_test.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_test.cc
new file mode 100644
index 0000000..edce8482
--- /dev/null
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_test.cc
@@ -0,0 +1,37 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+
+namespace blink {
+namespace {
+
+class XMLHttpRequestTest : public PageTestBase {
+ protected:
+};
+
+// An XHR with an origin with `CanLoadLocalResources` set cannot set forbidden
+// request headers. It was historically allowed, and this is a regression test.
+// See https://crbug.com/567527 for details.
+TEST_F(XMLHttpRequestTest, ForbiddenRequestHeaderWithLocalOrigin) {
+  GetFrame().DomWindow()->GetMutableSecurityOrigin()->GrantLoadLocalResources();
+
+  auto* xhr = XMLHttpRequest::Create(ToScriptStateForMainWorld(&GetFrame()));
+
+  xhr->open("GET", "https://example.com/", ASSERT_NO_EXCEPTION);
+  xhr->setRequestHeader("host", "example.com", ASSERT_NO_EXCEPTION);
+  EXPECT_FALSE(xhr->HasRequestHeaderForTesting("host"));
+}
+
+}  // namespace
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc
index f19e72fc..e968fa2 100644
--- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc
+++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc
@@ -17,18 +17,24 @@
 namespace blink {
 
 PressureObserver::PressureObserver(V8PressureUpdateCallback* observer_callback,
-                                   PressureObserverOptions* options)
-    // TODO(crbug.com/1356529): sampleRate in PressureObserverOptions needs to
-    // be processed and passed to lower stacks for compute pressure
-    // implementation.
-    : observer_callback_(observer_callback), options_(options) {}
+                                   PressureObserverOptions* options,
+                                   ExceptionState& exception_state)
+    : observer_callback_(observer_callback),
+      sample_rate_(options->sampleRate()) {
+  if (sample_rate_ <= 0.0) {
+    exception_state.ThrowRangeError("sampleRate must be positive");
+    return;
+  }
+}
 
 PressureObserver::~PressureObserver() = default;
 
 // static
 PressureObserver* PressureObserver::Create(V8PressureUpdateCallback* callback,
-                                           PressureObserverOptions* options) {
-  return MakeGarbageCollected<PressureObserver>(callback, options);
+                                           PressureObserverOptions* options,
+                                           ExceptionState& exception_state) {
+  return MakeGarbageCollected<PressureObserver>(callback, options,
+                                                exception_state);
 }
 
 // static
@@ -88,7 +94,6 @@
 
 void PressureObserver::Trace(blink::Visitor* visitor) const {
   visitor->Trace(manager_);
-  visitor->Trace(options_);
   visitor->Trace(observer_callback_);
   for (const auto& last_record : last_record_map_)
     visitor->Trace(last_record);
@@ -101,6 +106,9 @@
                                 V8PressureState::Enum state,
                                 const Vector<V8PressureFactor>& factors,
                                 DOMHighResTimeStamp timestamp) {
+  if (!PassesRateTest(source, timestamp))
+    return;
+
   if (!HasChangeInData(source, state, factors))
     return;
 
@@ -151,6 +159,20 @@
   return records;
 }
 
+// https://wicg.github.io/compute-pressure/#dfn-passes-rate-test
+bool PressureObserver::PassesRateTest(
+    V8PressureSource::Enum source,
+    const DOMHighResTimeStamp& timestamp) const {
+  const auto& last_record = last_record_map_[static_cast<size_t>(source)];
+
+  if (!last_record)
+    return true;
+
+  const double time_delta_milliseconds = timestamp - last_record->time();
+  const double interval_seconds = 1.0 / sample_rate_;
+  return (time_delta_milliseconds / 1000.0) >= interval_seconds;
+}
+
 // https://wicg.github.io/compute-pressure/#dfn-has-change-in-data
 bool PressureObserver::HasChangeInData(
     V8PressureSource::Enum source,
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h
index 13f6e97..2aaacce 100644
--- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h
+++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h
@@ -36,11 +36,14 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  PressureObserver(V8PressureUpdateCallback*, PressureObserverOptions*);
+  PressureObserver(V8PressureUpdateCallback*,
+                   PressureObserverOptions*,
+                   ExceptionState&);
   ~PressureObserver() override;
 
   static PressureObserver* Create(V8PressureUpdateCallback*,
-                                  PressureObserverOptions*);
+                                  PressureObserverOptions*,
+                                  ExceptionState&);
 
   // PressureObserver IDL implementation.
   void observe(ScriptState*, V8PressureSource, ExceptionState&);
@@ -63,6 +66,9 @@
                 DOMHighResTimeStamp);
 
  private:
+  // Verifies if the latest update was at least longer than the sample period.
+  bool PassesRateTest(V8PressureSource::Enum, const DOMHighResTimeStamp&) const;
+
   // Verifies if there is data change in between last update and new one.
   bool HasChangeInData(V8PressureSource::Enum,
                        V8PressureState::Enum,
@@ -77,8 +83,9 @@
   // The callback that receives pressure state updates.
   Member<V8PressureUpdateCallback> observer_callback_;
 
-  // Options for the observer.
-  Member<PressureObserverOptions> options_;
+  // Requested sample rate from the user.
+  // https://wicg.github.io/compute-pressure/#dfn-samplerate
+  double sample_rate_;
 
   // The last valid record received from the observer manager.
   // Stored to avoid sending updates whenever the new record is the same.
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.idl b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.idl
index 6726082..9be1acb 100644
--- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.idl
+++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.idl
@@ -14,7 +14,8 @@
     SecureContext
 ] interface PressureObserver {
   [
-    MeasureAs=PressureObserver_Constructor
+    MeasureAs=PressureObserver_Constructor,
+    RaisesException
   ] constructor(PressureUpdateCallback callback,
                 optional PressureObserverOptions options = {});
 
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.cc b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.cc
index e58d7ec5..f309725 100644
--- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.cc
+++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.cc
@@ -148,10 +148,11 @@
     }
     // TODO(crbug.com/1342184): Consider other sources.
     // For now, "cpu" is the only source.
-    observer->OnUpdate(
-        GetExecutionContext(), V8PressureSource::Enum::kCpu,
-        PressureStateToV8PressureState(update->state), std::move(v8_factors),
-        static_cast<DOMHighResTimeStamp>(update->timestamp.ToDoubleT()));
+    observer->OnUpdate(GetExecutionContext(), V8PressureSource::Enum::kCpu,
+                       PressureStateToV8PressureState(update->state),
+                       std::move(v8_factors),
+                       static_cast<DOMHighResTimeStamp>(
+                           update->timestamp.ToJsTimeIgnoringNull()));
   }
 }
 
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_options.idl b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_options.idl
index 50798346..aae5ef3 100644
--- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_options.idl
+++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_options.idl
@@ -7,5 +7,5 @@
     Exposed=Window,
     SecureContext
 ] dictionary PressureObserverOptions {
-  double sampleRate;
+  double sampleRate = 1.0;
 };
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
index 31612c17..1696124 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
@@ -87,6 +87,7 @@
   void SuspendForFrameClosed() override {}
 
   void SetWouldTaintOrigin(bool taint) { would_taint_origin_ = taint; }
+  bool PassedTimingAllowOriginCheck() const override { return true; }
 
   void Paint(cc::PaintCanvas* canvas,
              const gfx::Rect& rect,
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.cc b/third_party/blink/renderer/modules/mediastream/media_devices.cc
index d76e8e9..c40a6c9 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -20,9 +20,11 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_capture_handle_config.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_display_media_stream_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_constraints.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_supported_constraints.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_union_domexception_overconstrainederror.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_user_media_stream_constraints.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/execution_context/agent.h"
@@ -169,6 +171,36 @@
   base::UmaHistogramTimes("WebRTC.EnumerateDevices.Latency", elapsed);
 }
 
+MediaStreamConstraints* ToMediaStreamConstraints(
+    const UserMediaStreamConstraints* source) {
+  MediaStreamConstraints* options = MediaStreamConstraints::Create();
+  if (source->hasAudio())
+    options->setAudio(source->audio());
+  if (source->hasVideo())
+    options->setVideo(source->video());
+  return options;
+}
+
+MediaStreamConstraints* ToMediaStreamConstraints(
+    const DisplayMediaStreamOptions* source) {
+  MediaStreamConstraints* options = MediaStreamConstraints::Create();
+  if (source->hasAudio())
+    options->setAudio(source->audio());
+  if (source->hasVideo())
+    options->setVideo(source->video());
+  if (source->hasPreferCurrentTab())
+    options->setPreferCurrentTab(source->preferCurrentTab());
+  if (source->hasAutoSelectAllScreens())
+    options->setAutoSelectAllScreens(source->autoSelectAllScreens());
+  if (source->hasSystemAudio())
+    options->setSystemAudio(source->systemAudio());
+  if (source->hasSelfBrowserSurface())
+    options->setSelfBrowserSurface(source->selfBrowserSurface());
+  if (source->hasSurfaceSwitching())
+    options->setSurfaceSwitching(source->surfaceSwitching());
+  return options;
+}
+
 }  // namespace
 
 const char MediaDevices::kSupplementName[] = "MediaDevices";
@@ -220,11 +252,13 @@
   return MediaTrackSupportedConstraints::Create();
 }
 
-ScriptPromise MediaDevices::getUserMedia(ScriptState* script_state,
-                                         const MediaStreamConstraints* options,
-                                         ExceptionState& exception_state) {
+ScriptPromise MediaDevices::getUserMedia(
+    ScriptState* script_state,
+    const UserMediaStreamConstraints* options,
+    ExceptionState& exception_state) {
   return SendUserMediaRequest(script_state, UserMediaRequestType::kUserMedia,
-                              options, exception_state);
+                              ToMediaStreamConstraints(options),
+                              exception_state);
 }
 
 ScriptPromise MediaDevices::SendUserMediaRequest(
@@ -294,7 +328,7 @@
 
 ScriptPromise MediaDevices::getDisplayMediaSet(
     ScriptState* script_state,
-    const MediaStreamConstraints* options,
+    const DisplayMediaStreamOptions* options,
     ExceptionState& exception_state) {
   ExecutionContext* const context = GetExecutionContext();
   if (!context) {
@@ -304,14 +338,14 @@
     return ScriptPromise();
   }
 
-  return SendUserMediaRequest(script_state,
-                              UserMediaRequestType::kDisplayMediaSet, options,
-                              exception_state);
+  return SendUserMediaRequest(
+      script_state, UserMediaRequestType::kDisplayMediaSet,
+      ToMediaStreamConstraints(options), exception_state);
 }
 
 ScriptPromise MediaDevices::getDisplayMedia(
     ScriptState* script_state,
-    const MediaStreamConstraints* options,
+    const DisplayMediaStreamOptions* options,
     ExceptionState& exception_state) {
   LocalDOMWindow* const window = DomWindow();
   if (!window) {
@@ -351,7 +385,8 @@
   }
 
   return SendUserMediaRequest(script_state, UserMediaRequestType::kDisplayMedia,
-                              options, exception_state);
+                              ToMediaStreamConstraints(options),
+                              exception_state);
 }
 
 void MediaDevices::setCaptureHandleConfig(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.h b/third_party/blink/renderer/modules/mediastream/media_devices.h
index a38fef17..1596851 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.h
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.h
@@ -29,14 +29,15 @@
 namespace blink {
 
 class CaptureHandleConfig;
+class DisplayMediaStreamOptions;
 class ExceptionState;
 class LocalFrame;
 class Navigator;
-class MediaStreamConstraints;
 class MediaTrackSupportedConstraints;
 class ScriptPromise;
 class ScriptPromiseResolver;
 class ScriptState;
+class UserMediaStreamConstraints;
 
 class MODULES_EXPORT MediaDevices final
     : public EventTargetWithInlineData,
@@ -55,7 +56,7 @@
   ScriptPromise enumerateDevices(ScriptState*, ExceptionState&);
   MediaTrackSupportedConstraints* getSupportedConstraints() const;
   ScriptPromise getUserMedia(ScriptState*,
-                             const MediaStreamConstraints*,
+                             const UserMediaStreamConstraints*,
                              ExceptionState&);
   ScriptPromise SendUserMediaRequest(ScriptState*,
                                      UserMediaRequestType,
@@ -63,11 +64,11 @@
                                      ExceptionState&);
 
   ScriptPromise getDisplayMediaSet(ScriptState*,
-                                   const MediaStreamConstraints*,
+                                   const DisplayMediaStreamOptions*,
                                    ExceptionState&);
 
   ScriptPromise getDisplayMedia(ScriptState*,
-                                const MediaStreamConstraints*,
+                                const DisplayMediaStreamOptions*,
                                 ExceptionState&);
 
   void setCaptureHandleConfig(ScriptState*,
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.idl b/third_party/blink/renderer/modules/mediastream/media_devices.idl
index 3d0f9c4..a6b0c8b 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.idl
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.idl
@@ -20,19 +20,19 @@
     [
       CallWith = ScriptState, RaisesException, HighEntropy, MeasureAs = GetUserMediaPromise
     ] Promise<MediaStream>
-    getUserMedia(optional MediaStreamConstraints constraints = {});
+    getUserMedia(optional UserMediaStreamConstraints constraints = {});
 
     // https://w3c.github.io/mediacapture-screen-share/#dom-mediadevices-getdisplaymedia
     [
       RuntimeEnabled = GetDisplayMedia, CallWith = ScriptState, RaisesException,
       MeasureAs = GetDisplayMedia
     ] Promise<MediaStream>
-    getDisplayMedia(optional MediaStreamConstraints constraints = {});
+    getDisplayMedia(optional DisplayMediaStreamOptions constraints = {});
 
     [
       RuntimeEnabled = GetDisplayMediaSet, CallWith = ScriptState, RaisesException
     ] Promise<sequence<MediaStream>>
-    getDisplayMediaSet(optional MediaStreamConstraints constraints = {});
+    getDisplayMediaSet(optional DisplayMediaStreamOptions constraints = {});
 
     // https://w3c.github.io/mediacapture-handle/identity/
     // Allows an application APP to opt-in to exposing certain information to
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
index 31042449..229dac139 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
@@ -22,7 +22,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_capture_handle_config.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_crop_target.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_constraints.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_user_media_stream_constraints.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
 #include "third_party/blink/renderer/core/testing/null_execution_context.h"
@@ -351,7 +351,8 @@
 
 TEST_F(MediaDevicesTest, GetUserMediaCanBeCalled) {
   V8TestingScope scope;
-  MediaStreamConstraints* constraints = MediaStreamConstraints::Create();
+  UserMediaStreamConstraints* constraints =
+      UserMediaStreamConstraints::Create();
   ScriptPromise promise =
       GetMediaDevices(scope.GetWindow())
           ->getUserMedia(scope.GetScriptState(), constraints,
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl b/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl
index f9e5ee5..41489ec 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl
@@ -21,9 +21,18 @@
 };
 
 // https://w3c.github.io/mediacapture-main/#idl-def-mediastreamconstraints
-dictionary MediaStreamConstraints {
+// The name differs from the spec because the name MediaStreamConstraints
+// is used internally to hold all media stream constraints from getUserMedia()
+// and getDisplayMedia().
+dictionary UserMediaStreamConstraints {
     (boolean or MediaTrackConstraints) video = false;
     (boolean or MediaTrackConstraints) audio = false;
+};
+
+// https://www.w3.org/TR/screen-capture/#dom-displaymediastreamoptions
+dictionary DisplayMediaStreamOptions {
+    (boolean or MediaTrackConstraints) video = true;
+    (boolean or MediaTrackConstraints) audio = false;
 
     // https://wicg.github.io/prefer-current-tab/#prefer-current-tab
     boolean preferCurrentTab = false;
@@ -47,3 +56,18 @@
       RuntimeEnabled = SurfaceSwitchingConstraint
     ] SurfaceSwitchingPreferenceEnum surfaceSwitching;
 };
+
+// This dictionnary is used internally to hold all members from
+// UserMediaStreamConstraints and DisplayMediaStreamOptions dictionary
+// passed respectively to getUserMedia() and getDisplayMedia().
+// UserMediaStreamConstraints and DisplayMediaStreamOptions are converted to
+// MediaStreamConstraints and consumed by MediaDevices::SendUserMediaRequest().
+dictionary MediaStreamConstraints {
+    (boolean or MediaTrackConstraints) video = false;
+    (boolean or MediaTrackConstraints) audio = false;
+    boolean preferCurrentTab = false;
+    boolean autoSelectAllScreens = false;
+    SystemAudioPreferenceEnum systemAudio;
+    SelfCapturePreferenceEnum selfBrowserSurface;
+    SurfaceSwitchingPreferenceEnum surfaceSwitching;
+};
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
index e62466e..b42f5a0 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
@@ -540,6 +540,7 @@
   void DurationChanged() override {}
   void SizeChanged() override;
   void SetCcLayer(cc::Layer* layer) override;
+  void OnFirstFrame(base::TimeTicks, size_t) override {}
   WebMediaPlayer::TrackId AddAudioTrack(const WebString& id,
                                         AudioTrackKind,
                                         const WebString& label,
diff --git a/third_party/blink/renderer/modules/ml/webnn/BUILD.gn b/third_party/blink/renderer/modules/ml/webnn/BUILD.gn
index 2395721..c9ac88b 100644
--- a/third_party/blink/renderer/modules/ml/webnn/BUILD.gn
+++ b/third_party/blink/renderer/modules/ml/webnn/BUILD.gn
@@ -6,6 +6,8 @@
 
 blink_modules_sources("webnn") {
   sources = [
+    "ml_graph.cc",
+    "ml_graph.h",
     "ml_graph_builder.cc",
     "ml_graph_builder.h",
     "ml_operand.cc",
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph.cc
new file mode 100644
index 0000000..7423cde
--- /dev/null
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph.cc
@@ -0,0 +1,129 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/ml/webnn/ml_graph.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/modules/ml/ml_context.h"
+#include "third_party/blink/renderer/modules/ml/webnn/ml_operand.h"
+#include "third_party/blink/renderer/modules/ml/webnn/ml_operator.h"
+#include "third_party/blink/renderer/platform/wtf/deque.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+
+namespace blink {
+
+MLGraph::MLGraph(MLContext* context) : ml_context_(context) {}
+
+MLGraph::~MLGraph() = default;
+
+void MLGraph::Trace(Visitor* visitor) const {
+  visitor->Trace(ml_context_);
+  ScriptWrappable::Trace(visitor);
+}
+
+const HashMap<String, MLGraph::ResourceInfo>& MLGraph::GetInputResourcesInfo()
+    const {
+  DCHECK(resources_info_initialized_);
+  return input_resources_info_;
+}
+
+const HashMap<String, MLGraph::ResourceInfo>& MLGraph::GetOutputResourcesInfo()
+    const {
+  DCHECK(resources_info_initialized_);
+  return output_resources_info_;
+}
+
+void MLGraph::BuildAsync(const MLNamedOperands& named_outputs,
+                         ScriptPromiseResolver* resolver) {
+  String error_message;
+  if (!ValidateAndInitializeResourcesInfo(named_outputs, error_message)) {
+    resolver->Reject(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kDataError, error_message));
+    return;
+  }
+  BuildAsyncImpl(named_outputs, resolver);
+}
+
+bool MLGraph::ValidateAndInitializeResourcesInfo(
+    const MLNamedOperands& named_outputs,
+    String& error_message) {
+  DCHECK(!resources_info_initialized_);
+
+  // The outputs should not be empty.
+  if (named_outputs.empty()) {
+    error_message = "At least one output needs to be provided.";
+    return false;
+  }
+
+  // The queue and visited set of operators that help implement the
+  // breadth-first graph traversal:
+  // https://en.wikipedia.org/wiki/Breadth-first_search
+  Deque<Member<const MLOperator>> operators_queue;
+  HashSet<Member<const MLOperator>> visited_operators;
+
+  // Validate the named outputs, setup corresponding output resource info and
+  // initialize the queue and visited set with their dependent operators.
+  for (const auto& output : named_outputs) {
+    const auto& name = output.first;
+    const auto& operand = output.second;
+    // Validate whether it is an output operand.
+    if (operand->Kind() != MLOperand::OperandKind::kOutput) {
+      error_message = String::Format(
+          "The operand with name \"%s\" is not an output operand.",
+          name.Utf8().c_str());
+      return false;
+    }
+    // Setup resource info for this output operand.
+    output_resources_info_.insert(
+        name, ResourceInfo({.type = operand->Type(),
+                            .byte_length = operand->ByteLength()}));
+    // Mark its dependent operator is visited.
+    visited_operators.insert(operand->Operator());
+    // Enqueue its dependent operator.
+    operators_queue.push_back(operand->Operator());
+  }
+
+  while (operators_queue.size() > 0) {
+    // If the queue is not empty, dequeue an operator from the queue.
+    const auto& current_operator = operators_queue.front();
+    operators_queue.pop_front();
+    // Enumerate the current operator's input operands.
+    for (const auto& operand : current_operator->Inputs()) {
+      switch (operand->Kind()) {
+        case MLOperand::OperandKind::kOutput:
+          DCHECK(operand->Operator());
+          // If the operand is an output operand and its dependent operator is
+          // not visited, mark the dependent operator is visited and enqueue it.
+          if (!visited_operators.Contains(operand->Operator())) {
+            visited_operators.insert(operand->Operator());
+            operators_queue.push_back(operand->Operator());
+          }
+          break;
+        case MLOperand::OperandKind::kInput:
+          // If the operand is an input operand, validate whether its name is
+          // unique.
+          if (input_resources_info_.Contains(operand->Name())) {
+            error_message =
+                String::Format("The input name \"%s\" is duplicated.",
+                               operand->Name().Utf8().c_str());
+            return false;
+          }
+          // Setup resource info for this input operand.
+          input_resources_info_.insert(
+              operand->Name(),
+              ResourceInfo({.type = operand->Type(),
+                            .byte_length = operand->ByteLength()}));
+          break;
+        case MLOperand::OperandKind::kConstant:
+          // If the operand is a constant operand, there is no check needed.
+          break;
+      }
+    }
+  }
+  resources_info_initialized_ = true;
+  return true;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph.h
new file mode 100644
index 0000000..6ae7559
--- /dev/null
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph.h
@@ -0,0 +1,82 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_GRAPH_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_GRAPH_H_
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ml_operand_descriptor.h"
+#include "third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+
+namespace blink {
+
+class MLContext;
+class ScriptPromiseResolver;
+
+class MODULES_EXPORT MLGraph : public ScriptWrappable {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  MLGraph(const MLGraph&) = delete;
+  MLGraph& operator=(const MLGraph&) = delete;
+
+  ~MLGraph() override;
+
+  void Trace(Visitor* visitor) const override;
+
+  // The members of ResourceInfo are used to validate the inputs and outputs of
+  // an MLGraph execution. The validation steps are described by WebNN spec of
+  // MLContext.computeAsync() and MLContext.compute() methods:
+  // https://www.w3.org/TR/webnn/#api-mlcontext-async-execution
+  // https://www.w3.org/TR/webnn/#api-mlcontext-sync-execution
+  // The plain struct ResourceInfo is introduced instead of using
+  // MLOperandDescriptor because neither byte length calculation from dimensions
+  // nor GC support is needed for the implementation.
+  struct ResourceInfo {
+    V8MLOperandType::Enum type;
+    size_t byte_length;
+  };
+  const HashMap<String, ResourceInfo>& GetInputResourcesInfo() const;
+  const HashMap<String, ResourceInfo>& GetOutputResourcesInfo() const;
+
+ protected:
+  explicit MLGraph(MLContext* context);
+
+  // BuildAsync() should be called right after constructing a concrete
+  // MLGraph object. FakeMLGraphBackend::ValidateAndBuildAsync() in
+  // ml_graph_builder_test.cc gives an example. BuildAsync() validates the named
+  // outputs and initializes the input and output resources info. If there are
+  // no errors, it calls BuildAsyncImpl() implemented by an MLGraph backend that
+  // builds the platform specific graph.
+  void BuildAsync(const MLNamedOperands& named_outputs,
+                  ScriptPromiseResolver* resolver);
+
+  // An MLGraph backend should implement this method to build and compile a
+  // platform specific graph asynchronously. The actual graph construction and
+  // compilation work should be handled by a worker thread without blocking the
+  // main thread. Once the platform graph is compiled, the resolver should be
+  // resolved with a concrete MLGraph object. Otherwise, the resolver should be
+  // rejected with a DOMException accordingly.
+  virtual void BuildAsyncImpl(const MLNamedOperands& outputs,
+                              ScriptPromiseResolver* resolver) = 0;
+
+  Member<MLContext> ml_context_;
+  bool resources_info_initialized_{false};
+  HashMap<String, ResourceInfo> input_resources_info_;
+  HashMap<String, ResourceInfo> output_resources_info_;
+
+ private:
+  // This helper method is called by BuildAsync(). It validates named outputs
+  // and initializes the input and output resources info by graph traversal.
+  bool ValidateAndInitializeResourcesInfo(const MLNamedOperands& named_outputs,
+                                          String& error_message);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_GRAPH_H_
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph.idl b/third_party/blink/renderer/modules/ml/webnn/ml_graph.idl
new file mode 100644
index 0000000..481b5e5
--- /dev/null
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph.idl
@@ -0,0 +1,11 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://www.w3.org/TR/webnn/
+
+[
+  RuntimeEnabled=MachineLearningNeuralNetwork,
+  Exposed=Window
+] interface MLGraph {
+};
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
index f2faa76..dca8648 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
@@ -8,12 +8,15 @@
 
 #include "base/numerics/checked_math.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_clamp_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_gemm_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_operand_descriptor.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/modules/ml/ml_context.h"
+#include "third_party/blink/renderer/modules/ml/webnn/ml_graph.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_operand.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 
@@ -176,30 +179,40 @@
     const uint32_t beginning_padding,
     const uint32_t ending_padding,
     const uint32_t stride,
-    const uint32_t dilation) {
+    const uint32_t dilation,
+    String& error_message) {
   // Calculate the dilated filter sizes.
-  auto checked_dilated_filter_size =
+  auto checked_effective_filter_size =
       (base::MakeCheckedNum<uint32_t>(filter_size) - 1) * dilation + 1;
-  if (!checked_dilated_filter_size.IsValid()) {
+  if (!checked_effective_filter_size.IsValid()) {
+    error_message = "The effective filter size is too large.";
     return absl::nullopt;
   }
 
   // Calculate the output size in double precision floating point number that
   // ensures all dimension values of type uint32_t can be exactly represented.
   // https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Precision_limitations_on_integer_values
+  // The max value of checked_output_size should be 3 * UINT_MAX + 1, assert it
+  // is less than max integer value of double type.
   auto checked_output_size =
-      (base::MakeCheckedNum<double>(input_size) - checked_dilated_filter_size +
-       beginning_padding + ending_padding) /
+      (base::MakeCheckedNum<double>(input_size) -
+       checked_effective_filter_size + beginning_padding + ending_padding) /
           stride +
       1;
 
-  // Check if the value is valid for rounding to uint32_t type.
-  double float_output_size;
-  if (!checked_output_size.IsValid<uint32_t>() ||
-      !checked_output_size.AssignIfValid(&float_output_size)) {
+  if (checked_output_size.ValueOrDie() < 0) {
+    error_message =
+        "The input size is too small to fill the convolution window.";
     return absl::nullopt;
   }
-  return float_output_size;
+
+  // Check if the value is valid for rounding to uint32_t type.
+  if (!checked_output_size.IsValid<uint32_t>()) {
+    error_message = "The output size is too large.";
+    return absl::nullopt;
+  }
+
+  return checked_output_size.ValueOrDie();
 }
 
 struct FloatSize2D {
@@ -319,23 +332,24 @@
     padding_ending_width = padding_sizes_width.value().end;
   }
 
+  String error_message;
   auto float_output_height = CalculateConv2dOutputSize(
       input_height, filter_height, padding_beginning_height,
-      padding_ending_height, stride_height, dilation_height);
+      padding_ending_height, stride_height, dilation_height, error_message);
   if (!float_output_height) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kDataError,
-        "Overflow occurred when calculating the output height.");
+        "Failed to calculate the output height: " + error_message);
     return absl::nullopt;
   }
 
   auto float_output_width = CalculateConv2dOutputSize(
       input_width, filter_width, padding_beginning_width, padding_ending_width,
-      stride_width, dilation_width);
+      stride_width, dilation_width, error_message);
   if (!float_output_width) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kDataError,
-        "Overflow occurred when calculating the output width.");
+        "Failed to calculate the output width: " + error_message);
     return absl::nullopt;
   }
 
@@ -534,6 +548,10 @@
   ScriptWrappable::Trace(visitor);
 }
 
+MLContext* MLGraphBuilder::GetContext() const {
+  return ml_context_;
+}
+
 MLOperand* MLGraphBuilder::input(String name,
                                  const MLOperandDescriptor* desc,
                                  ExceptionState& exception_state) {
@@ -1067,4 +1085,25 @@
   return output;
 }
 
+ScriptPromise MLGraphBuilder::buildAsync(ScriptState* script_state,
+                                         const MLNamedOperands& named_outputs,
+                                         ExceptionState& exception_state) {
+  if (!script_state->ContextIsValid()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                      "Invalid script state");
+    return ScriptPromise();
+  }
+
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+  auto promise = resolver->Promise();
+
+  // TODO(ningxin.hu@intel.com): Create a concrete MLGraph object that builds
+  // the platform specific graph for hardware acceleration. For example:
+  // MLGraphXnnpack::ValidateAndBuildAsync(ml_context_, outputs, resolver);
+
+  resolver->Reject(MakeGarbageCollected<DOMException>(
+      DOMExceptionCode::kNotSupportedError, "Not implemented"));
+  return promise;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h
index 89f274e..f44505c 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_GRAPH_BUILDER_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_GRAPH_BUILDER_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_operator.h"
@@ -42,6 +43,8 @@
 
   void Trace(Visitor* visitor) const override;
 
+  MLContext* GetContext() const;
+
   // ml_graph_builder.idl
   MLOperand* input(String name,
                    const MLOperandDescriptor* desc,
@@ -107,6 +110,10 @@
 
   MLOperand* softmax(const MLOperand* input, ExceptionState& exception_state);
 
+  ScriptPromise buildAsync(ScriptState* script_state,
+                           const MLNamedOperands& outputs,
+                           ExceptionState& exception_state);
+
  private:
   Member<MLContext> ml_context_;
 };
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl
index a47e6ce..7c5ec5b 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl
@@ -91,4 +91,6 @@
   [RaisesException] MLOperand reshape(MLOperand input, sequence<long> newShape);
 
   [RaisesException] MLOperand softmax(MLOperand input);
+
+  [CallWith=ScriptState, RaisesException] Promise<MLGraph> buildAsync(MLNamedOperands outputs);
 };
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
index 3797fb2..fa8876114 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
@@ -10,17 +10,32 @@
 #include "base/numerics/checked_math.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_context_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_gemm_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_operand_descriptor.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
 #include "third_party/blink/renderer/modules/ml/ml.h"
 #include "third_party/blink/renderer/modules/ml/ml_context.h"
+#include "third_party/blink/renderer/modules/ml/webnn/ml_graph.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_operand.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_operator.h"
+#include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
+#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/wtf/deque.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
 
 namespace blink {
 
@@ -304,12 +319,27 @@
   V8TestingScope scope;
   auto* builder = CreateMLGraphBuilder(scope);
   {
-    // Test conv2d without padding.
+    // Test conv2d with default options.
     auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
                              V8MLOperandType::Enum::kFloat32);
     auto* filter = BuildConstant(scope, builder, {1, 1, 3, 3},
                                  V8MLOperandType::Enum::kFloat32);
-    auto* output = BuildConv2d(scope, builder, input, filter);
+    auto* options = MLConv2dOptions::Create();
+    EXPECT_TRUE(options->hasAutoPad());
+    EXPECT_EQ(options->autoPad(), V8MLAutoPad::Enum::kExplicit);
+    EXPECT_FALSE(options->hasBias());
+    EXPECT_FALSE(options->hasDilations());
+    EXPECT_FALSE(options->hasActivation());
+    EXPECT_TRUE(options->hasFilterLayout());
+    EXPECT_EQ(options->filterLayout(),
+              V8MLConv2dFilterOperandLayout::Enum::kOihw);
+    EXPECT_TRUE(options->hasInputLayout());
+    EXPECT_EQ(options->inputLayout(), V8MLInputOperandLayout::Enum::kNchw);
+    EXPECT_TRUE(options->hasGroups());
+    EXPECT_EQ(options->groups(), 1);
+    EXPECT_FALSE(options->hasPadding());
+    EXPECT_FALSE(options->hasStrides());
+    auto* output = BuildConv2d(scope, builder, input, filter, options);
     EXPECT_EQ(output->Dimensions(), Vector<uint32_t>({1, 1, 3, 3}));
   }
   {
@@ -542,6 +572,408 @@
     EXPECT_EQ(scope.GetExceptionState().Message(),
               "Invalid output operand: The byte length is too large.");
   }
+  {
+    // Test throwing exception when the input is not a 4-D tensor.
+    auto* input = BuildInput(scope, builder, "input", {1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 2, 2, 1},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The input should be a 4-D tensor.");
+  }
+  {
+    // Test throwing exception when the filter is not a 4-D tensor.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter =
+        BuildConstant(scope, builder, {2, 2}, V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The filter should be a 4-D tensor.");
+  }
+  {
+    // Test throwing exception when the filter type doesn't match the input
+    // type.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kInt32);
+    auto* options = MLConv2dOptions::Create();
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The filter type doesn't match the input type.");
+  }
+  {
+    // Test throwing exception when the length of padding is not 4.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setPadding({2, 2});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The length of padding should be 4.");
+  }
+  {
+    // Test throwing exception when one padding value is smaller than 0.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setPadding({0, 1, 2, -2});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "All paddings should be greater than or equal to 0.");
+  }
+  {
+    // Test throwing exception when the length of strides is not 2.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setStrides({2});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The length of strides should be 2.");
+  }
+  {
+    // Test throwing exception when one stride value is smaller than 1.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setStrides({1, 0});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "All strides should be greater than or equal to 1.");
+  }
+  {
+    // Test throwing exception when the length of dilations is not 2.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setDilations({1});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The length of dilations should be 2.");
+  }
+  {
+    // Test throwing exception when the one dilation value is smaller than 1.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setDilations({1, -1});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "All dilations should be greater than or equal to 1.");
+  }
+  {
+    // Test throwing exception when input_channels % groups() != 0.
+    auto* input = BuildInput(scope, builder, "input", {1, 4, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setGroups(3);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The groups must evenly divide the input "
+              "channels to filter input channels.");
+  }
+  {
+    // Test throwing exception when filter_input_channels != input_channels /
+    // groups().
+    auto* input = BuildInput(scope, builder, "input", {1, 4, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setGroups(2);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The groups must evenly divide the input "
+              "channels to filter input channels.");
+  }
+  {
+    // Test throwing exception when the groups is smaller than 1.
+    auto* input = BuildInput(scope, builder, "input", {1, 4, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setGroups(0);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The groups should be greater than or equal to 1.");
+  }
+  {
+    // Test throwing exception due to overflow when calculating the padding
+    // along the height dimension.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 23567, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setStrides({193232, 3});
+    options->setDilations({232328, 2});
+    options->setAutoPad(V8MLAutoPad::Enum::kSameUpper);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "Overflow occurred when calculating "
+              "the padding along the height dimension.");
+  }
+  {
+    // Test throwing exception due to overflow when calculating the padding
+    // along the width dimension.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 28476},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setStrides({1, 284234});
+    options->setDilations({1, 434329});
+    options->setAutoPad(V8MLAutoPad::Enum::kSameLower);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "Overflow occurred when calculating "
+              "the padding along the width dimension.");
+  }
+  {
+    // Test throwing exception due to overflow when calculating the effective
+    // filter height.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 434983, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setDilations({328442, 1});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(
+        scope.GetExceptionState().Message(),
+        "Failed to calculate the output height: The effective filter size is "
+        "too large.");
+  }
+  {
+    // Test throwing exception due to overflow when calculating the effective
+    // filter width.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 234545},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setDilations({2, 843452});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(
+        scope.GetExceptionState().Message(),
+        "Failed to calculate the output width: The effective filter size is "
+        "too large.");
+  }
+  {
+    // Test throwing exception due to underflow when calculating the output
+    // height.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 4, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setDilations({4, 1});
+    options->setPadding({1, 1, 1, 1});
+    options->setStrides({2, 2});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "Failed to calculate the output height: The input size is too "
+              "small to fill the convolution window.");
+  }
+  {
+    // Test throwing exception due to underflow when calculating the output
+    // width.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 8},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    options->setDilations({1, 4});
+    options->setPadding({1, 1, 1, 1});
+    options->setStrides({2, 2});
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "Failed to calculate the output width: The input size is too "
+              "small to fill the convolution window.");
+  }
+  {
+    // Test throwing exception when the bias is not a 1-D tensor.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    auto* bias =
+        BuildConstant(scope, builder, {1, 2}, V8MLOperandType::Enum::kFloat32);
+    options->setBias(bias);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The bias should be a 1-D tensor.");
+  }
+  {
+    // Test throwing exception when the bias is not a 1-D tensor.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    auto* bias =
+        BuildConstant(scope, builder, {1, 2}, V8MLOperandType::Enum::kFloat32);
+    options->setBias(bias);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The bias should be a 1-D tensor.");
+  }
+  {
+    // Test throwing exception when the bias is not a 1-D tensor.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    auto* bias =
+        BuildConstant(scope, builder, {1, 2}, V8MLOperandType::Enum::kFloat32);
+    options->setBias(bias);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The bias should be a 1-D tensor.");
+  }
+  {
+    // Test throwing exception when the bias shape is not equal to
+    // [output_channels].
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    auto* bias =
+        BuildConstant(scope, builder, {2}, V8MLOperandType::Enum::kFloat32);
+    options->setBias(bias);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The bias shape should be [1].");
+  }
+  {
+    // Test throwing exception when the bias type doesn't match input type.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 2, 2},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* options = MLConv2dOptions::Create();
+    auto* bias =
+        BuildConstant(scope, builder, {1}, V8MLOperandType::Enum::kInt32);
+    options->setBias(bias);
+    auto* output =
+        builder->conv2d(input, filter, options, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The bias type doesn't match input type.");
+  }
 }
 
 enum class Pool2dKind { kAverage, kMax };
@@ -1210,4 +1642,193 @@
   }
 }
 
+class FakeMLGraphBackend final : public MLGraph {
+ public:
+  // Create and build a FakeMLGraphBackend object. Resolve the promise with
+  // this concrete object if no errors.
+  static void ValidateAndBuildAsync(MLContext* context,
+                                    const MLNamedOperands& named_outputs,
+                                    ScriptPromiseResolver* resolver) {
+    auto* graph = MakeGarbageCollected<FakeMLGraphBackend>(context);
+    graph->BuildAsync(named_outputs, resolver);
+  }
+
+  // The constructor shouldn't be called directly. The callers should use
+  // ValidateAndBuildAsync() method instead.
+  explicit FakeMLGraphBackend(MLContext* context) : MLGraph(context) {}
+
+  ~FakeMLGraphBackend() override = default;
+
+ private:
+  // Simpliy resolve the promise with this FakeMLGraphBackend object for testing
+  // the input and output resources info.
+  void BuildAsyncImpl(const MLNamedOperands& named_outputs,
+                      ScriptPromiseResolver* resolver) override {
+    resolver->Resolve(this);
+  }
+};
+
+FakeMLGraphBackend* ToFakeMLGraphBackend(V8TestingScope* scope,
+                                         ScriptValue value) {
+  return NativeValueTraits<FakeMLGraphBackend>::NativeValue(
+      scope->GetIsolate(), value.V8Value(), scope->GetExceptionState());
+}
+
+TEST_F(MLGraphBuilderTest, BuildAsyncTest) {
+  V8TestingScope scope;
+  auto* builder = CreateMLGraphBuilder(scope);
+  auto* script_state = scope.GetScriptState();
+  {
+    // Test throwing exception if the named outputs is empty.
+    MLNamedOperands named_outputs;
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+    ScriptPromiseTester tester(script_state, resolver->Promise());
+    FakeMLGraphBackend::ValidateAndBuildAsync(builder->GetContext(),
+                                              named_outputs, resolver);
+    tester.WaitUntilSettled();
+    EXPECT_TRUE(tester.IsRejected());
+    auto* exception = V8DOMException::ToImplWithTypeCheck(
+        scope.GetIsolate(), tester.Value().V8Value());
+    EXPECT_NE(exception, nullptr);
+    EXPECT_EQ(exception->name(), "DataError");
+    EXPECT_EQ(exception->message(),
+              "At least one output needs to be provided.");
+  }
+  {
+    // Test throwing exception if the named output is an input operand.
+    auto* input = BuildInput(scope, builder, "input", {3, 4, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+    ScriptPromiseTester tester(script_state, resolver->Promise());
+    FakeMLGraphBackend::ValidateAndBuildAsync(builder->GetContext(),
+                                              {{"output", input}}, resolver);
+    tester.WaitUntilSettled();
+    EXPECT_TRUE(tester.IsRejected());
+    auto* exception = V8DOMException::ToImplWithTypeCheck(
+        scope.GetIsolate(), tester.Value().V8Value());
+    EXPECT_NE(exception, nullptr);
+    EXPECT_EQ(exception->name(), "DataError");
+    EXPECT_EQ(exception->message(),
+              "The operand with name \"output\" is not an output operand.");
+  }
+  {
+    // Test throwing exception if the named output is a constant operand.
+    auto* constant = BuildConstant(scope, builder, {3, 4, 5},
+                                   V8MLOperandType::Enum::kFloat32);
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+    ScriptPromiseTester tester(script_state, resolver->Promise());
+    FakeMLGraphBackend::ValidateAndBuildAsync(builder->GetContext(),
+                                              {{"output", constant}}, resolver);
+    tester.WaitUntilSettled();
+    EXPECT_TRUE(tester.IsRejected());
+    auto* exception = V8DOMException::ToImplWithTypeCheck(
+        scope.GetIsolate(), tester.Value().V8Value());
+    EXPECT_NE(exception, nullptr);
+    EXPECT_EQ(exception->name(), "DataError");
+    EXPECT_EQ(exception->message(),
+              "The operand with name \"output\" is not an output operand.");
+  }
+  {
+    // Test throwing exception if the named outputs is a mix of input and
+    // constant operands.
+    auto* input = BuildInput(scope, builder, "input", {3, 4, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* constant = BuildConstant(scope, builder, {3, 4, 5},
+                                   V8MLOperandType::Enum::kFloat32);
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+    ScriptPromiseTester tester(script_state, resolver->Promise());
+    FakeMLGraphBackend::ValidateAndBuildAsync(
+        builder->GetContext(), {{"output1", input}, {"output2", constant}},
+        resolver);
+    tester.WaitUntilSettled();
+    EXPECT_TRUE(tester.IsRejected());
+    auto* exception = V8DOMException::ToImplWithTypeCheck(
+        scope.GetIsolate(), tester.Value().V8Value());
+    EXPECT_NE(exception, nullptr);
+    EXPECT_EQ(exception->name(), "DataError");
+    EXPECT_EQ(exception->message(),
+              "The operand with name \"output1\" is not an output operand.");
+  }
+  {
+    // Test throwing exception if two inputs have the same name.
+    auto* a = BuildInput(scope, builder, "a", {3, 4, 5},
+                         V8MLOperandType::Enum::kFloat32);
+    auto* b = BuildInput(scope, builder, "a", {3, 4, 5},
+                         V8MLOperandType::Enum::kFloat32);
+    auto* c = builder->add(a, b, scope.GetExceptionState());
+    ASSERT_NE(c, nullptr);
+
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+    ScriptPromiseTester tester(script_state, resolver->Promise());
+    FakeMLGraphBackend::ValidateAndBuildAsync(builder->GetContext(), {{"c", c}},
+                                              resolver);
+    tester.WaitUntilSettled();
+    EXPECT_TRUE(tester.IsRejected());
+    auto* exception = V8DOMException::ToImplWithTypeCheck(
+        scope.GetIsolate(), tester.Value().V8Value());
+    EXPECT_NE(exception, nullptr);
+    EXPECT_EQ(exception->name(), "DataError");
+    EXPECT_EQ(exception->message(), "The input name \"a\" is duplicated.");
+  }
+  {
+    // Test building a fake graph with two inputs, one gemm operation and one
+    // output.
+    auto* a = BuildInput(scope, builder, "a", {3, 4},
+                         V8MLOperandType::Enum::kFloat32);
+    auto* b = BuildInput(scope, builder, "b", {4, 3},
+                         V8MLOperandType::Enum::kFloat32);
+    auto* c = BuildGemm(scope, builder, a, b);
+
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+    ScriptPromiseTester tester(script_state, resolver->Promise());
+    FakeMLGraphBackend::ValidateAndBuildAsync(builder->GetContext(), {{"c", c}},
+                                              resolver);
+    tester.WaitUntilSettled();
+    EXPECT_TRUE(tester.IsFulfilled());
+    auto* graph = ToFakeMLGraphBackend(&scope, tester.Value());
+    EXPECT_NE(graph, nullptr);
+    const auto& inputs = graph->GetInputResourcesInfo();
+    EXPECT_EQ(inputs.size(), static_cast<uint32_t>(2));
+    EXPECT_EQ(inputs.at("a").type, a->Type());
+    EXPECT_EQ(inputs.at("a").byte_length, a->ByteLength());
+    EXPECT_EQ(inputs.at("b").type, b->Type());
+    EXPECT_EQ(inputs.at("b").byte_length, b->ByteLength());
+    const auto& outputs = graph->GetOutputResourcesInfo();
+    EXPECT_EQ(outputs.size(), static_cast<uint32_t>(1));
+    EXPECT_EQ(outputs.at("c").type, c->Type());
+    EXPECT_EQ(outputs.at("c").byte_length, c->ByteLength());
+  }
+  {
+    // Test building a fake graph with conv2d, add and relu operations.
+    auto* input = BuildInput(scope, builder, "input", {1, 1, 5, 5},
+                             V8MLOperandType::Enum::kFloat32);
+    auto* filter = BuildConstant(scope, builder, {1, 1, 3, 3},
+                                 V8MLOperandType::Enum::kFloat32);
+    auto* conv2d = BuildConv2d(scope, builder, input, filter);
+    auto* bias =
+        BuildConstant(scope, builder, {1}, V8MLOperandType::Enum::kFloat32);
+    auto* add = builder->add(conv2d, bias, scope.GetExceptionState());
+    ASSERT_NE(add, nullptr);
+    auto* output = builder->relu(add, scope.GetExceptionState());
+    ASSERT_NE(output, nullptr);
+
+    auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+    ScriptPromiseTester tester(script_state, resolver->Promise());
+    FakeMLGraphBackend::ValidateAndBuildAsync(builder->GetContext(),
+                                              {{"output", output}}, resolver);
+    tester.WaitUntilSettled();
+    EXPECT_TRUE(tester.IsFulfilled());
+    auto* graph = ToFakeMLGraphBackend(&scope, tester.Value());
+    EXPECT_NE(graph, nullptr);
+    const auto& inputs = graph->GetInputResourcesInfo();
+    EXPECT_EQ(inputs.size(), static_cast<uint32_t>(1));
+    EXPECT_EQ(inputs.at("input").type, input->Type());
+    EXPECT_EQ(inputs.at("input").byte_length, input->ByteLength());
+    const auto& outputs = graph->GetOutputResourcesInfo();
+    EXPECT_EQ(outputs.size(), static_cast<uint32_t>(1));
+    EXPECT_EQ(outputs.at("output").type, output->Type());
+    EXPECT_EQ(outputs.at("output").byte_length, output->ByteLength());
+  }
+}
+
 }  // namespace blink
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 484d147..68507d8 100644
--- a/third_party/blink/renderer/platform/exported/web_url_response.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -229,6 +229,10 @@
   resource_response_->SetHasRangeRequested(value);
 }
 
+bool WebURLResponse::TimingAllowPassed() const {
+  return resource_response_->TimingAllowPassed();
+}
+
 void WebURLResponse::SetTimingAllowPassed(bool value) {
   resource_response_->SetTimingAllowPassed(value);
 }
diff --git a/third_party/blink/renderer/platform/fonts/font_metrics.h b/third_party/blink/renderer/platform/fonts/font_metrics.h
index 67c67a6e..a993384 100644
--- a/third_party/blink/renderer/platform/fonts/font_metrics.h
+++ b/third_party/blink/renderer/platform/fonts/font_metrics.h
@@ -66,6 +66,9 @@
 
   float FloatHeight() const { return float_ascent_ + float_descent_; }
 
+  float CapHeight() const { return cap_height_; }
+  void SetCapHeight(float cap_height) { cap_height_ = cap_height; }
+
   float FloatLineGap() const { return line_gap_; }
   void SetLineGap(float line_gap) { line_gap_ = line_gap; }
 
@@ -188,6 +191,7 @@
 
   void Reset() {
     units_per_em_ = kGDefaultUnitsPerEm;
+    cap_height_ = 0;
     float_ascent_ = 0;
     float_descent_ = 0;
     int_ascent_ = 0;
@@ -205,6 +209,7 @@
   PLATFORM_EXPORT int IntAscentInternal(FontBaseline baseline_type) const;
 
   unsigned units_per_em_ = kGDefaultUnitsPerEm;
+  float cap_height_ = 0;
   float float_ascent_ = 0;
   float float_descent_ = 0;
   float line_gap_ = 0;
diff --git a/third_party/blink/renderer/platform/fonts/font_test.cc b/third_party/blink/renderer/platform/fonts/font_test.cc
index 2a04c477..75fe34d6 100644
--- a/third_party/blink/renderer/platform/fonts/font_test.cc
+++ b/third_party/blink/renderer/platform/fonts/font_test.cc
@@ -57,6 +57,31 @@
   }
 };
 
+TEST_F(FontTest, FonteMetricsCapHeight) {
+  const auto cap_height_of = [](const char* font_path, float size) {
+    Font font =
+        CreateTestFont("test", test::PlatformTestDataPath(font_path), size);
+    const SimpleFontData* const font_data = font.PrimaryFont();
+    return font_data->GetFontMetrics().CapHeight();
+  };
+
+  EXPECT_FLOAT_EQ(80.0f, cap_height_of("Ahem.woff", 100));
+  EXPECT_FLOAT_EQ(160.0f, cap_height_of("Ahem.woff", 200));
+
+#if BUILDFLAG(IS_WIN)
+  EXPECT_FLOAT_EQ(
+      70.9961f, cap_height_of("third_party/Roboto/roboto-regular.woff2", 100));
+  EXPECT_FLOAT_EQ(
+      141.99219f,
+      cap_height_of("third_party/Roboto/roboto-regular.woff2", 200));
+#else
+  EXPECT_FLOAT_EQ(
+      71.09375f, cap_height_of("third_party/Roboto/roboto-regular.woff2", 100));
+  EXPECT_FLOAT_EQ(
+      142.1875f, cap_height_of("third_party/Roboto/roboto-regular.woff2", 200));
+#endif
+}
+
 TEST_F(FontTest, IdeographicFullWidthAhem) {
   Font font =
       CreateTestFont("Ahem", test::PlatformTestDataPath("Ahem.woff"), 16);
diff --git a/third_party/blink/renderer/platform/fonts/simple_font_data.cc b/third_party/blink/renderer/platform/fonts/simple_font_data.cc
index 7fbce91..89a77ac 100644
--- a/third_party/blink/renderer/platform/fonts/simple_font_data.cc
+++ b/third_party/blink/renderer/platform/fonts/simple_font_data.cc
@@ -94,6 +94,7 @@
 
   font_metrics_.SetAscent(ascent);
   font_metrics_.SetDescent(descent);
+  font_metrics_.SetCapHeight(metrics.fCapHeight);
 
   float skia_underline_value;
   if (metrics.hasUnderlinePosition(&skia_underline_value))
diff --git a/third_party/blink/renderer/platform/link_hash.h b/third_party/blink/renderer/platform/link_hash.h
index d1b1db6..ebb4f3d2 100644
--- a/third_party/blink/renderer/platform/link_hash.h
+++ b/third_party/blink/renderer/platform/link_hash.h
@@ -44,16 +44,6 @@
   static unsigned GetHash(LinkHash key) { return static_cast<unsigned>(key); }
   static bool Equal(LinkHash a, LinkHash b) { return a == b; }
   static const bool safe_to_compare_to_empty_or_deleted = true;
-
-  // See AlreadyHashed::avoidDeletedValue.
-  static unsigned AvoidDeletedValue(LinkHash hash64) {
-    DCHECK(hash64);
-    unsigned hash = static_cast<unsigned>(hash64);
-    unsigned new_hash = hash | (!(hash + 1) << 31);
-    DCHECK(new_hash);
-    DCHECK_NE(new_hash, 0xFFFFFFFF);
-    return new_hash;
-  }
 };
 
 // Resolves the potentially relative URL "attributeURL" relative to the given
diff --git a/third_party/blink/renderer/platform/loader/fetch/media_timing.h b/third_party/blink/renderer/platform/loader/fetch/media_timing.h
index cba7c5b..571a6a09 100644
--- a/third_party/blink/renderer/platform/loader/fetch/media_timing.h
+++ b/third_party/blink/renderer/platform/loader/fetch/media_timing.h
@@ -19,6 +19,8 @@
   // Request URL of the media resource content.
   virtual const KURL& Url() const = 0;
 
+  virtual void SetIsSufficientContentLoadedForPaint() = 0;
+
   // True if enough of the media resource content has been loaded to decode and
   // display a frame. (The entire image for static media, and the first frame
   // for animated media.)
@@ -42,6 +44,9 @@
   // decoded and rendered.
   // TODO(iclelland): Change this so that it applies to static images as well.
   virtual bool IsPaintedFirstFrame() const = 0;
+
+  virtual void SetFirstVideoFrameTime(base::TimeTicks) { NOTREACHED(); }
+  virtual base::TimeTicks GetFirstVideoFrameTime() const = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source.cc b/third_party/blink/renderer/platform/media/multi_buffer_data_source.cc
index 2201f930..35e37b0 100644
--- a/third_party/blink/renderer/platform/media/multi_buffer_data_source.cc
+++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source.cc
@@ -294,6 +294,10 @@
   return url_data_->has_access_control();
 }
 
+bool MultiBufferDataSource::PassedTimingAllowOriginCheck() {
+  return url_data_->passed_timing_allow_origin_check();
+}
+
 UrlData::CorsMode MultiBufferDataSource::cors_mode() const {
   return url_data_->cors_mode();
 }
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source.h b/third_party/blink/renderer/platform/media/multi_buffer_data_source.h
index fd7d59b..28789ff8 100644
--- a/third_party/blink/renderer/platform/media/multi_buffer_data_source.h
+++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source.h
@@ -95,6 +95,8 @@
   // header (that is not "null").
   bool HasAccessControl() const;
 
+  bool PassedTimingAllowOriginCheck();
+
   // Returns the CorsMode of the underlying UrlData.
   UrlData::CorsMode cors_mode() const;
 
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
index 076bb32..9971a56 100644
--- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
+++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
@@ -318,6 +318,9 @@
     destination_url_data->set_mime_type(response.MimeType().Utf8());
   }
 
+  destination_url_data->set_passed_timing_allow_origin_check(
+      response.TimingAllowPassed());
+
   if (destination_url_data != url_data_) {
     // At this point, we've encountered a redirect, or found a better url data
     // instance for the data that we're about to download.
diff --git a/third_party/blink/renderer/platform/media/url_index.cc b/third_party/blink/renderer/platform/media/url_index.cc
index 4164b5a0d..fa203d69 100644
--- a/third_party/blink/renderer/platform/media/url_index.cc
+++ b/third_party/blink/renderer/platform/media/url_index.cc
@@ -122,6 +122,11 @@
   mime_type_ = std::move(mime_type);
 }
 
+void UrlData::set_passed_timing_allow_origin_check(
+    bool passed_timing_allow_origin_check) {
+  passed_timing_allow_origin_check_ = passed_timing_allow_origin_check;
+}
+
 void UrlData::RedirectTo(const scoped_refptr<UrlData>& url_data) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   // Copy any cached data over to the new location.
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
index 71eb06ca..9961397 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -382,8 +382,6 @@
 
 }  // namespace
 
-class BufferedDataSourceHostImpl;
-
 STATIC_ASSERT_ENUM(WebMediaPlayer::kCorsModeUnspecified,
                    UrlData::CORS_UNSPECIFIED);
 STATIC_ASSERT_ENUM(WebMediaPlayer::kCorsModeAnonymous, UrlData::CORS_ANONYMOUS);
@@ -3916,9 +3914,15 @@
   media_metrics_provider_->SetTimeToFirstFrame(elapsed);
   RecordTimingUMA("Media.TimeToFirstFrame", elapsed);
 
-  // Needed to signal HTMLVideoElement that it should remove the poster image.
-  if (client_ && has_poster_)
-    client_->Repaint();
+  media::PipelineStatistics ps = GetPipelineStatistics();
+  if (client_) {
+    client_->OnFirstFrame(frame_time, ps.video_bytes_decoded);
+
+    // Needed to signal HTMLVideoElement that it should remove the poster image.
+    if (has_poster_) {
+      client_->Repaint();
+    }
+  }
 }
 
 void WebMediaPlayerImpl::RecordTimingUMA(const std::string& key,
@@ -4088,4 +4092,10 @@
   }
 }
 
+bool WebMediaPlayerImpl::PassedTimingAllowOriginCheck() const {
+  if (mb_data_source_)
+    return mb_data_source_->PassedTimingAllowOriginCheck();
+  return true;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.h b/third_party/blink/renderer/platform/media/web_media_player_impl.h
index e082339..31b94dd 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl.h
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.h
@@ -232,6 +232,8 @@
   uint64_t AudioDecodedByteCount() const override;
   uint64_t VideoDecodedByteCount() const override;
 
+  bool PassedTimingAllowOriginCheck() const override;
+
   void SetVolumeMultiplier(double multiplier) override;
   void SetPersistentState(bool persistent) override;
   void SetPowerExperimentState(bool state) override;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 7b966eb..afb8be6 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -342,6 +342,9 @@
       name: "BackForwardCacheNotRestoredReasons",
       status: "experimental",
       origin_trial_feature_name: "BackForwardCacheNotRestoredReasons",
+      base_feature: "BackForwardCacheSendNotRestoredReasons",
+      base_feature_status: "enabled",
+      copied_from_base_feature_if: "overridden",
       public: true,
     },
     {
@@ -706,6 +709,12 @@
       status: "stable",
     },
     {
+        // http://crbug.com/1276900
+        name: "CSSInitialLetter",
+        depends_on: ["LayoutNG"],
+        status: "test",
+    },
+    {
       name: "CSSLastBaseline",
       status: "stable",
     },
diff --git a/third_party/blink/renderer/platform/testing/empty_web_media_player.h b/third_party/blink/renderer/platform/testing/empty_web_media_player.h
index d93cfbe..44d8892 100644
--- a/third_party/blink/renderer/platform/testing/empty_web_media_player.h
+++ b/third_party/blink/renderer/platform/testing/empty_web_media_player.h
@@ -77,6 +77,7 @@
   }
   void RegisterFrameSinkHierarchy() override {}
   void UnregisterFrameSinkHierarchy() override {}
+  bool PassedTimingAllowOriginCheck() const override { return true; }
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/wtf/hash_traits.h b/third_party/blink/renderer/platform/wtf/hash_traits.h
index 5b921a2..31710543 100644
--- a/third_party/blink/renderer/platform/wtf/hash_traits.h
+++ b/third_party/blink/renderer/platform/wtf/hash_traits.h
@@ -100,8 +100,6 @@
     static const bool value = !std::is_pod<T>::value;
   };
 
-  static constexpr bool kCanHaveDeletedValue = true;
-
   // The kCanTraceConcurrently value is used by Oilpan concurrent marking. Only
   // type for which HashTraits<T>::kCanTraceConcurrently is true can be traced
   // on a concurrent thread.
diff --git a/third_party/blink/renderer/platform/wtf/text/string_hash.h b/third_party/blink/renderer/platform/wtf/text/string_hash.h
index eeb0450..ff1c5f57 100644
--- a/third_party/blink/renderer/platform/wtf/text/string_hash.h
+++ b/third_party/blink/renderer/platform/wtf/text/string_hash.h
@@ -76,18 +76,6 @@
 struct AlreadyHashed : IntHash<unsigned> {
   STATIC_ONLY(AlreadyHashed);
   static unsigned GetHash(unsigned key) { return key; }
-
-  // To use a hash value as a key for a hash table, we need to eliminate the
-  // "deleted" value, which is negative one. That could be done by changing
-  // the string hash function to never generate negative one, but this works
-  // and is still relatively efficient.
-  static unsigned AvoidDeletedValue(unsigned hash) {
-    DCHECK(hash);
-    unsigned new_hash = hash | (!(hash + 1) << 31);
-    DCHECK(new_hash);
-    DCHECK_NE(new_hash, 0xFFFFFFFF);
-    return new_hash;
-  }
 };
 
 }  // namespace WTF
diff --git a/third_party/blink/renderer/platform/wtf/vector_traits.h b/third_party/blink/renderer/platform/wtf/vector_traits.h
index 1df967f..0eaf247 100644
--- a/third_party/blink/renderer/platform/wtf/vector_traits.h
+++ b/third_party/blink/renderer/platform/wtf/vector_traits.h
@@ -64,10 +64,6 @@
     static const bool value = IsTraceable<T>::value;
   };
 
-  // Vectors do not support deleting values.
-  static constexpr bool kCanHaveDeletedValue = false;
-  static bool IsDeletedValue(const T& value) { return false; }
-
   // The kCanTraceConcurrently value is used by Oilpan concurrent marking.
   // Only type for which VectorTraits<T>::kCanTraceConcurrently is true can
   // be traced on a concurrent thread.
@@ -154,10 +150,6 @@
         IsTraceableInCollectionTrait<SecondTraits>::value;
   };
 
-  // Vectors do not support deleting values.
-  static constexpr bool kCanHaveDeletedValue = false;
-  static bool IsDeletedValue(std::pair<First, Second> value) { return false; }
-
   static constexpr bool kCanTraceConcurrently = false;
 };
 
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index a00397b1..b88d44a 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -1780,8 +1780,10 @@
 crbug.com/1196419 external/wpt/compute-pressure/compute_pressure_multiple.tentative.https.window.html [ Skip ]
 crbug.com/1196419 external/wpt/compute-pressure/compute_pressure_observe_idempotent.tentative.https.window.html [ Skip ]
 crbug.com/1196419 external/wpt/compute-pressure/compute_pressure_observe_unobserve_failure.tentative.https.window.html [ Skip ]
+crbug.com/1196419 external/wpt/compute-pressure/compute_pressure_options.tentative.https.window.html [ Skip ]
 crbug.com/1196419 external/wpt/compute-pressure/compute_pressure_supported_sources.tentative.https.window.html [ Skip ]
 crbug.com/1196419 external/wpt/compute-pressure/compute_pressure_take_records.tentative.https.window.html [ Skip ]
+crbug.com/1196419 external/wpt/compute-pressure/compute_pressure_timestamp.tentative.https.window.html [ Skip ]
 crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_basic.tentative.https.window.html [ Pass ]
 crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_basic_async.tentative.https.window.html [ Pass ]
 crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_detached_iframe.tentative.https.html [ Pass ]
@@ -1796,8 +1798,10 @@
 crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_multiple.tentative.https.window.html [ Pass ]
 crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_observe_idempotent.tentative.https.window.html [ Pass ]
 crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_observe_unobserve_failure.tentative.https.window.html [ Pass ]
+crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_options.tentative.https.window.html [ Pass ]
 crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_supported_sources.tentative.https.window.html [ Pass ]
 crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_take_records.tentative.https.window.html [ Pass ]
+crbug.com/1196419 virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_timestamp.tentative.https.window.html [ Pass ]
 
 # text-orientation:upright
 crbug.com/1005518 external/wpt/css/css-writing-modes/table-progression-vlr-003.html [ Skip ]
@@ -1954,7 +1958,3 @@
 # Experimental JS shared memory features
 crbug.com/1351118 wpt_internal/js/shared_memory/* [ Skip ]
 crbug.com/1351118 virtual/js-shared-memory/wpt_internal/js/shared_memory/* [ Pass ]
-
-# Feature is not yet launched, so skip the base.
-crbug.com/1326344 external/wpt/performance-timeline/not-restored-reasons/* [ Skip ]
-crbug.com/1326344 virtual/not-restored-reasons/external/wpt/performance-timeline/not-restored-reasons/* [ Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 4cd0890..a272b33 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -6040,11 +6040,6 @@
 # Sheriff 2021-07-29
 crbug.com/626703 http/tests/security/cross-frame-access-put.html [ Failure Pass ]
 
-# Sheriff 2021-07-30
-crbug.com/1234619 external/wpt/screen-capture/permissions-policy-audio+video.https.sub.html [ Failure ]
-crbug.com/1234619 external/wpt/screen-capture/permissions-policy-audio.https.sub.html [ Failure ]
-crbug.com/1234619 external/wpt/screen-capture/permissions-policy-video.https.sub.html [ Failure ]
-
 # Sheriff 2021-08-02
 crbug.com/1215390 [ Linux ] external/wpt/pointerevents/pointerevent_pointerId_scope.html [ Failure Pass ]
 
@@ -7237,7 +7232,7 @@
 crbug.com/1363138 http/tests/inspector-protocol/cachestorage/read-cached-response.js [ Skip ]
 
 # Investigate the flake
-crbug.com/1371395 virtual/not-restored-reasons/external/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.window.html [ Failure Pass ]
+crbug.com/1371395 external/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.window.js [ Failure Pass ]
 
 # Disable top flakes trigger step failure on builders
 crbug.com/1371949 [ Mac12 ] virtual/low-priority-script-loading/http/tests/devtools/network/resource-priority.js [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 04658f7..0f61b0d 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -860,7 +860,7 @@
     "bases": [ "external/wpt/speculation-rules/prerender",
                "wpt_internal/prerender",
                "http/tests/inspector-protocol/prerender"],
-    "args": [ "--enable-features=Prerender2" ]
+    "args": [ "--enable-features=SameSiteCrossOriginForSpeculationRulesPrerender" ]
   },
   {
     "prefix": "no-different-origin-dialogs",
@@ -1320,11 +1320,5 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/custom-elements/scoped-registry"],
     "args": ["--disable-blink-features=ScopedCustomElementRegistry"]
-  },
-  {
-    "prefix": "not-restored-reasons",
-    "platforms": ["Linux", "Mac", "Win"],
-    "bases": ["external/wpt/performance-timeline/not-restored-reasons/"],
-    "args": ["--enable-features=BackForwardCacheSendNotRestoredReasons"]
   }
 ]
diff --git a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_options.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_options.tentative.https.window.js
new file mode 100644
index 0000000..d142ecc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_options.tentative.https.window.js
@@ -0,0 +1,23 @@
+'use strict';
+
+test(t => {
+  assert_throws_js(RangeError, () => {
+    new PressureObserver(() => {}, {sampleRate: 0});
+  });
+}, 'PressureObserver constructor requires a non-zero sampleRate');
+
+test(t => {
+  assert_throws_js(RangeError, () => {
+    new PressureObserver(() => {}, {sampleRate: -2});
+  });
+}, 'PressureObserver constructor requires a positive sampleRate');
+
+test(t => {
+  const observer = new PressureObserver(() => {}, {sampleRate: 0.5});
+  assert_equals(typeof observer, 'object');
+}, 'PressureObserver constructor doesnt throw error on positive sampleRate');
+
+test(t => {
+  const observer = new PressureObserver(() => {}, {});
+  assert_equals(typeof observer, 'object');
+}, 'PressureObserver constructor succeeds on empty sampleRate');
diff --git a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_timestamp.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_timestamp.tentative.https.window.js
new file mode 100644
index 0000000..be53b0e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_timestamp.tentative.https.window.js
@@ -0,0 +1,43 @@
+// META: script=/resources/test-only-api.js
+// META: script=resources/pressure-helpers.js
+
+'use strict';
+
+pressure_test(async (t, mockPressureService) => {
+  const readings = ['nominal', 'fair', 'serious', 'critical'];
+
+  const sampleRate = 4.0;
+  const pressureChanges = await new Promise(async resolve => {
+    const observerChanges = [];
+    const observer = new PressureObserver(changes => {
+      observerChanges.push(changes);
+    }, {sampleRate});
+    observer.observe('cpu');
+
+    mockPressureService.startPlatformCollector(sampleRate * 2);
+    let i = 0;
+    // mockPressureService.updatesDelivered() does not necessarily match
+    // pressureChanges.length, as system load and browser optimizations can
+    // cause the actual timer used by mockPressureService to deliver readings
+    // to be a bit slower or faster than requested.
+    while (observerChanges.length < 4) {
+      mockPressureService.setPressureUpdate(readings[i++ % readings.length]);
+      await t.step_wait(
+          () => mockPressureService.updatesDelivered() >= i,
+          `At least ${i} readings have been delivered`);
+    }
+    observer.disconnect();
+    resolve(observerChanges);
+  });
+
+  assert_equals(pressureChanges.length, 4);
+  assert_greater_than_equal(
+      pressureChanges[1][0].time - pressureChanges[0][0].time,
+      (1 / sampleRate * 1000));
+  assert_greater_than_equal(
+      pressureChanges[2][0].time - pressureChanges[1][0].time,
+      (1 / sampleRate * 1000));
+  assert_greater_than_equal(
+      pressureChanges[3][0].time - pressureChanges[2][0].time,
+      (1 / sampleRate * 1000));
+}, 'Faster collector: Timestamp difference between two changes should be higher or equal to the observer sample rate');
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/backgrounds/background-intrinsic-004.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/backgrounds/background-intrinsic-004.xht.ini
new file mode 100644
index 0000000..5c34090
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/backgrounds/background-intrinsic-004.xht.ini
@@ -0,0 +1,2 @@
+[background-intrinsic-004.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/backgrounds/background-intrinsic-006.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/backgrounds/background-intrinsic-006.xht.ini
new file mode 100644
index 0000000..0c7d04c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/backgrounds/background-intrinsic-006.xht.ini
@@ -0,0 +1,2 @@
+[background-intrinsic-006.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/cascade/inherit-computed-001.html.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/cascade/inherit-computed-001.html.ini
new file mode 100644
index 0000000..12e8c800
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/cascade/inherit-computed-001.html.ini
@@ -0,0 +1,2 @@
+[inherit-computed-001.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-3-ref.html.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-3-ref.html.ini
new file mode 100644
index 0000000..b73dfd8d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-3-ref.html.ini
@@ -0,0 +1,2 @@
+[float-nowrap-3-ref.html]
+  expected: CRASH
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-4.html.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-4.html.ini
new file mode 100644
index 0000000..46013258
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-4.html.ini
@@ -0,0 +1,2 @@
+[float-nowrap-4.html]
+  expected: CRASH
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-7.html.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-7.html.ini
new file mode 100644
index 0000000..d3a5d2c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-7.html.ini
@@ -0,0 +1,2 @@
+[float-nowrap-7.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-8.html.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-8.html.ini
new file mode 100644
index 0000000..8e07c478
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-8.html.ini
@@ -0,0 +1,2 @@
+[float-nowrap-8.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-9.html.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-9.html.ini
new file mode 100644
index 0000000..8eab0f65
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-nowrap-9.html.ini
@@ -0,0 +1,2 @@
+[float-nowrap-9.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht.ini
new file mode 100644
index 0000000..5a03f09f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht.ini
@@ -0,0 +1,2 @@
+[floats-rule3-outside-left-002.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002.xht.ini
new file mode 100644
index 0000000..cbad66d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002.xht.ini
@@ -0,0 +1,2 @@
+[floats-rule3-outside-right-002.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule7-outside-left-001.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule7-outside-left-001.xht.ini
new file mode 100644
index 0000000..8ed9f3c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule7-outside-left-001.xht.ini
@@ -0,0 +1,2 @@
+[floats-rule7-outside-left-001.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001.xht.ini
new file mode 100644
index 0000000..0a1b241c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001.xht.ini
@@ -0,0 +1,2 @@
+[floats-rule7-outside-right-001.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-wrap-bfc-006.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-wrap-bfc-006.xht.ini
new file mode 100644
index 0000000..382770ac
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/floats-wrap-bfc-006.xht.ini
@@ -0,0 +1,2 @@
+[floats-wrap-bfc-006.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-002.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-002.xht.ini
new file mode 100644
index 0000000..3b6420d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-002.xht.ini
@@ -0,0 +1,2 @@
+[inline-formatting-context-002.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-003.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-003.xht.ini
new file mode 100644
index 0000000..394620b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-003.xht.ini
@@ -0,0 +1,2 @@
+[inline-formatting-context-003.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-004.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-004.xht.ini
new file mode 100644
index 0000000..ecad8c49
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-004.xht.ini
@@ -0,0 +1,2 @@
+[inline-formatting-context-004.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-005.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-005.xht.ini
new file mode 100644
index 0000000..75606e2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-005.xht.ini
@@ -0,0 +1,2 @@
+[inline-formatting-context-005.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-006.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-006.xht.ini
new file mode 100644
index 0000000..e98a1b5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-006.xht.ini
@@ -0,0 +1,2 @@
+[inline-formatting-context-006.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-007.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-007.xht.ini
new file mode 100644
index 0000000..a59ef6c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-formatting-context-007.xht.ini
@@ -0,0 +1,2 @@
+[inline-formatting-context-007.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-sub-001.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-sub-001.xht.ini
new file mode 100644
index 0000000..6089c80d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-sub-001.xht.ini
@@ -0,0 +1,2 @@
+[vertical-align-sub-001.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-super-001.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-super-001.xht.ini
new file mode 100644
index 0000000..ab61c75
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-super-001.xht.ini
@@ -0,0 +1,2 @@
+[vertical-align-super-001.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/max-width-applies-to-005.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/max-width-applies-to-005.xht.ini
new file mode 100644
index 0000000..53ce267
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/max-width-applies-to-005.xht.ini
@@ -0,0 +1,2 @@
+[max-width-applies-to-005.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/max-width-applies-to-006.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/max-width-applies-to-006.xht.ini
new file mode 100644
index 0000000..7d62d81
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/max-width-applies-to-006.xht.ini
@@ -0,0 +1,2 @@
+[max-width-applies-to-006.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-001.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-001.xht.ini
new file mode 100644
index 0000000..d4c4ce6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-001.xht.ini
@@ -0,0 +1,2 @@
+[replaced-intrinsic-001.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-002.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-002.xht.ini
new file mode 100644
index 0000000..bf85cf0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-002.xht.ini
@@ -0,0 +1,2 @@
+[replaced-intrinsic-002.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/position-relative-035.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/position-relative-035.xht.ini
new file mode 100644
index 0000000..1d21cdc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/position-relative-035.xht.ini
@@ -0,0 +1,2 @@
+[position-relative-035.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/column-visibility-004.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/column-visibility-004.xht.ini
new file mode 100644
index 0000000..a8f26b3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/column-visibility-004.xht.ini
@@ -0,0 +1,2 @@
+[column-visibility-004.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-079.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-079.xht.ini
new file mode 100644
index 0000000..be62975
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-079.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-079.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-080.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-080.xht.ini
new file mode 100644
index 0000000..85071f93
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-080.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-080.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-081.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-081.xht.ini
new file mode 100644
index 0000000..f23dd59d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-081.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-081.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-082.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-082.xht.ini
new file mode 100644
index 0000000..67e1503
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-082.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-082.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-083.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-083.xht.ini
new file mode 100644
index 0000000..b255b53
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-083.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-083.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-084.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-084.xht.ini
new file mode 100644
index 0000000..fe4e599
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-084.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-084.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-085.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-085.xht.ini
new file mode 100644
index 0000000..ed053430
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-085.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-085.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-086.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-086.xht.ini
new file mode 100644
index 0000000..46c00c6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-086.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-086.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-093.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-093.xht.ini
new file mode 100644
index 0000000..59ca4a7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-093.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-093.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-094.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-094.xht.ini
new file mode 100644
index 0000000..6838b84
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-094.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-094.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-095.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-095.xht.ini
new file mode 100644
index 0000000..1a1dbde
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-095.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-095.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-096.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-096.xht.ini
new file mode 100644
index 0000000..f3e247c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-096.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-096.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-097.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-097.xht.ini
new file mode 100644
index 0000000..c4f894e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-097.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-097.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-098.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-098.xht.ini
new file mode 100644
index 0000000..f09a440
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-098.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-098.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-103.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-103.xht.ini
new file mode 100644
index 0000000..8e24928f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-103.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-103.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-104.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-104.xht.ini
new file mode 100644
index 0000000..a53d0914
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-104.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-104.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-125.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-125.xht.ini
new file mode 100644
index 0000000..96f6e497
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-125.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-125.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-126.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-126.xht.ini
new file mode 100644
index 0000000..c9a5ac19
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-126.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-126.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-127.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-127.xht.ini
new file mode 100644
index 0000000..976c52b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-127.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-127.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-128.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-128.xht.ini
new file mode 100644
index 0000000..3c189d61
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-128.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-128.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-129.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-129.xht.ini
new file mode 100644
index 0000000..663d86f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-129.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-129.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-130.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-130.xht.ini
new file mode 100644
index 0000000..6d0b010
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-130.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-130.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-131.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-131.xht.ini
new file mode 100644
index 0000000..dce0b114
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-131.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-131.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-132.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-132.xht.ini
new file mode 100644
index 0000000..692aca7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-132.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-132.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-155.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-155.xht.ini
new file mode 100644
index 0000000..4447e3b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-155.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-155.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-156.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-156.xht.ini
new file mode 100644
index 0000000..b78c375
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-156.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-156.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-157.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-157.xht.ini
new file mode 100644
index 0000000..cc84e04
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-157.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-157.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-158.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-158.xht.ini
new file mode 100644
index 0000000..e36e94f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-158.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-158.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-167.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-167.xht.ini
new file mode 100644
index 0000000..a3a684b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-167.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-167.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-168.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-168.xht.ini
new file mode 100644
index 0000000..57cab47
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-168.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-168.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-171.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-171.xht.ini
new file mode 100644
index 0000000..f1975bc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-171.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-171.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-172.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-172.xht.ini
new file mode 100644
index 0000000..29da376c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-172.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-172.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-181.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-181.xht.ini
new file mode 100644
index 0000000..a48bdf7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-181.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-181.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-182.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-182.xht.ini
new file mode 100644
index 0000000..5df7c5d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-182.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-182.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-183.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-183.xht.ini
new file mode 100644
index 0000000..5b8b29c7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-183.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-183.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-184.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-184.xht.ini
new file mode 100644
index 0000000..a1198c6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-184.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-184.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-185.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-185.xht.ini
new file mode 100644
index 0000000..f77f68b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-185.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-185.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-186.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-186.xht.ini
new file mode 100644
index 0000000..62dde949
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-186.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-186.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-187.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-187.xht.ini
new file mode 100644
index 0000000..b1ea0e0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-187.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-187.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-188.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-188.xht.ini
new file mode 100644
index 0000000..48ab699
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-188.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-188.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-199.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-199.xht.ini
new file mode 100644
index 0000000..e67617bc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-199.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-199.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-200.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-200.xht.ini
new file mode 100644
index 0000000..df79062
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-200.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-200.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-201.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-201.xht.ini
new file mode 100644
index 0000000..7df8c8b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-201.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-201.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-202.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-202.xht.ini
new file mode 100644
index 0000000..3445d39
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-202.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-202.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-203.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-203.xht.ini
new file mode 100644
index 0000000..b21a61a1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-203.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-203.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-204.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-204.xht.ini
new file mode 100644
index 0000000..e8115dc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-204.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-204.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-211.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-211.xht.ini
new file mode 100644
index 0000000..b970506
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/table-anonymous-objects-211.xht.ini
@@ -0,0 +1,2 @@
+[table-anonymous-objects-211.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/letter-spacing-080.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/text/letter-spacing-080.xht.ini
new file mode 100644
index 0000000..36e78cb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/letter-spacing-080.xht.ini
@@ -0,0 +1,2 @@
+[letter-spacing-080.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-align-white-space-003.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-align-white-space-003.xht.ini
new file mode 100644
index 0000000..629be9f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-align-white-space-003.xht.ini
@@ -0,0 +1,2 @@
+[text-align-white-space-003.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-decoration-va-length-001.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-decoration-va-length-001.xht.ini
new file mode 100644
index 0000000..0428506
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-decoration-va-length-001.xht.ini
@@ -0,0 +1,2 @@
+[text-decoration-va-length-001.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-transform-bicameral-007.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-transform-bicameral-007.xht.ini
new file mode 100644
index 0000000..5610ec93
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-transform-bicameral-007.xht.ini
@@ -0,0 +1,2 @@
+[text-transform-bicameral-007.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-collapsing-bidi-001.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-collapsing-bidi-001.xht.ini
new file mode 100644
index 0000000..83500dd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-collapsing-bidi-001.xht.ini
@@ -0,0 +1,2 @@
+[white-space-collapsing-bidi-001.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-mixed-001.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-mixed-001.xht.ini
new file mode 100644
index 0000000..b1cf457
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-mixed-001.xht.ini
@@ -0,0 +1,2 @@
+[white-space-mixed-001.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-048.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-048.xht.ini
new file mode 100644
index 0000000..d6fae45e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-048.xht.ini
@@ -0,0 +1,2 @@
+[white-space-processing-048.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-049.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-049.xht.ini
new file mode 100644
index 0000000..8f4f940
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/white-space-processing-049.xht.ini
@@ -0,0 +1,2 @@
+[white-space-processing-049.xht]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/box-decoration-break-clone-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/box-decoration-break-clone-001.html.ini
new file mode 100644
index 0000000..559906ee
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/box-decoration-break-clone-001.html.ini
@@ -0,0 +1,2 @@
+[box-decoration-break-clone-001.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/box-decoration-break-clone-002.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/box-decoration-break-clone-002.html.ini
new file mode 100644
index 0000000..bba7ca6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/box-decoration-break-clone-002.html.ini
@@ -0,0 +1,2 @@
+[box-decoration-break-clone-002.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/box-decoration-break-clone-004.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/box-decoration-break-clone-004.html.ini
new file mode 100644
index 0000000..fdaa2c73
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/box-decoration-break-clone-004.html.ini
@@ -0,0 +1,2 @@
+[box-decoration-break-clone-004.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-058.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-058.html.ini
new file mode 100644
index 0000000..7f0ce76
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-058.html.ini
@@ -0,0 +1,2 @@
+[multi-line-row-flex-fragmentation-058.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-043.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-043.html.ini
new file mode 100644
index 0000000..3b1824f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-043.html.ini
@@ -0,0 +1,2 @@
+[single-line-column-flex-fragmentation-043.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/grid/grid-item-fragmentation-039.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/grid/grid-item-fragmentation-039.html.ini
new file mode 100644
index 0000000..5f8c1d3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/grid/grid-item-fragmentation-039.html.ini
@@ -0,0 +1,2 @@
+[grid-item-fragmentation-039.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/inheritance.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/inheritance.html.ini
new file mode 100644
index 0000000..2923803
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/inheritance.html.ini
@@ -0,0 +1,6 @@
+[inheritance.html]
+  [Property box-decoration-break has initial value slice]
+    expected: FAIL
+
+  [Property box-decoration-break does not inherit]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/parsing/box-decoration-break-computed.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/box-decoration-break-computed.html.ini
new file mode 100644
index 0000000..dac3832
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/box-decoration-break-computed.html.ini
@@ -0,0 +1,6 @@
+[box-decoration-break-computed.html]
+  [Property box-decoration-break value 'slice']
+    expected: FAIL
+
+  [Property box-decoration-break value 'clone']
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/parsing/box-decoration-break-valid.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/box-decoration-break-valid.html.ini
new file mode 100644
index 0000000..957a8bd5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/box-decoration-break-valid.html.ini
@@ -0,0 +1,6 @@
+[box-decoration-break-valid.html]
+  [e.style['box-decoration-break'\] = "slice" should set the property value]
+    expected: FAIL
+
+  [e.style['box-decoration-break'\] = "clone" should set the property value]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-after-computed.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-after-computed.html.ini
new file mode 100644
index 0000000..f2b3f9a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-after-computed.html.ini
@@ -0,0 +1,6 @@
+[break-after-computed.html]
+  [Property break-after value 'avoid-region']
+    expected: FAIL
+
+  [Property break-after value 'region']
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-after-valid.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-after-valid.html.ini
new file mode 100644
index 0000000..ff0d464b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-after-valid.html.ini
@@ -0,0 +1,6 @@
+[break-after-valid.html]
+  [e.style['break-after'\] = "avoid-region" should set the property value]
+    expected: FAIL
+
+  [e.style['break-after'\] = "region" should set the property value]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-before-computed.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-before-computed.html.ini
new file mode 100644
index 0000000..a5cb8e05
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-before-computed.html.ini
@@ -0,0 +1,6 @@
+[break-before-computed.html]
+  [Property break-before value 'avoid-region']
+    expected: FAIL
+
+  [Property break-before value 'region']
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-before-valid.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-before-valid.html.ini
new file mode 100644
index 0000000..c8f229e8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-before-valid.html.ini
@@ -0,0 +1,6 @@
+[break-before-valid.html]
+  [e.style['break-before'\] = "avoid-region" should set the property value]
+    expected: FAIL
+
+  [e.style['break-before'\] = "region" should set the property value]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-inside-computed.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-inside-computed.html.ini
new file mode 100644
index 0000000..c5e6858e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-inside-computed.html.ini
@@ -0,0 +1,3 @@
+[break-inside-computed.html]
+  [Property break-inside value 'avoid-region']
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-inside-valid.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-inside-valid.html.ini
new file mode 100644
index 0000000..bc94263
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/parsing/break-inside-valid.html.ini
@@ -0,0 +1,3 @@
+[break-inside-valid.html]
+  [e.style['break-inside'\] = "avoid-region" should set the property value]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/transform-007.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/transform-007.html.ini
new file mode 100644
index 0000000..cf25f3d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/transform-007.html.ini
@@ -0,0 +1,2 @@
+[transform-007.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/transform-009.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/transform-009.html.ini
new file mode 100644
index 0000000..cad216fb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/transform-009.html.ini
@@ -0,0 +1,2 @@
+[transform-009.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/widows-orphans-017.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/widows-orphans-017.html.ini
new file mode 100644
index 0000000..a2b8899
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/widows-orphans-017.html.ini
@@ -0,0 +1,2 @@
+[widows-orphans-017.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-cascade/OWNERS
index 54387d3..77c044d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-cascade/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/OWNERS
@@ -1,4 +1,3 @@
 futhark@chromium.org
 andruud@chromium.org
 ericwilligers@chromium.org
-shend@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/css-conditional/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-conditional/OWNERS
index 54387d3..1d83d3d3 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-conditional/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/css/css-conditional/OWNERS
@@ -1,4 +1,3 @@
 futhark@chromium.org
 andruud@chromium.org
-ericwilligers@chromium.org
-shend@chromium.org
+ericwilligers@chromium.org
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-initial-letter/initial-letter-computed.html b/third_party/blink/web_tests/external/wpt/css/css-initial-letter/initial-letter-computed.html
new file mode 100644
index 0000000..e463062
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-initial-letter/initial-letter-computed.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>Tests parsing of the initial-letter property</title>
+<link rel="author" title="Google LLC" href="https://www.google.com/">
+<link rel="help" href="https://https://w3c.github.io/csswg-drafts/css-inline-3/#sizing-drop-initials">
+<meta name="assert" content="initial-letter supports the full grammar 'normal | <number [1,∞]> <integer [1,∞]> | <number [1,∞]> && [ drop | raise ]?'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+
+<div id="target"></div>
+<div id="scratch"></div>
+
+<script>
+test_computed_value('initial-letter', 'normal');
+test_computed_value('initial-letter', '1.23');
+test_computed_value('initial-letter', '1.23 456');
+test_computed_value('initial-letter', '1.23 calc(45.6)', '1.23 46');
+test_computed_value('initial-letter', '1.23 drop');
+test_computed_value('initial-letter', '1.23 raise');
+test_computed_value('initial-letter', 'drop 1.23', '1.23 drop');
+test_computed_value('initial-letter', 'raise 1.23', '1.23 raise');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-initial-letter/initial-letter-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-initial-letter/initial-letter-invalid.html
new file mode 100644
index 0000000..574a347
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-initial-letter/initial-letter-invalid.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Tests parsing of the initial-letter property</title>
+<link rel="author" title="Google LLC" href="https://www.google.com/">
+<link rel="help" href="https://https://w3c.github.io/csswg-drafts/css-inline-3/#sizing-drop-initials">
+<meta name="assert" content="initial-letter supports the full grammar 'normal | <number [1,∞]> <integer [1,∞]> | <number [1,∞]> && [ drop | raise ]?'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+
+<script>
+test_invalid_value('initial-letter', 'foobar');
+test_invalid_value('initial-letter', 'drop');
+test_invalid_value('initial-letter', 'raise');
+test_invalid_value('initial-letter', 'drop 1 2');
+test_invalid_value('initial-letter', 'raise 1 2');
+test_invalid_value('initial-letter', '-1');
+test_invalid_value('initial-letter', '0');
+test_invalid_value('initial-letter', '0.5');
+test_invalid_value('initial-letter', '1 -1');
+test_invalid_value('initial-letter', '1 0');
+test_invalid_value('initial-letter', '1 0.5');
+test_invalid_value('initial-letter', '1 1.5');
+test_invalid_value('initial-letter', '1 2 3');
+test_invalid_value('initial-letter', '1 drop 3');
+test_invalid_value('initial-letter', '1 raise 3');
+test_invalid_value('initial-letter', '1 foobar 3');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-initial-letter/initial-letter-valid.html b/third_party/blink/web_tests/external/wpt/css/css-initial-letter/initial-letter-valid.html
new file mode 100644
index 0000000..3c1e3281
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-initial-letter/initial-letter-valid.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Tests parsing of the initial-letter property</title>
+<link rel="author" title="Google LLC" href="https://www.google.com/">
+<link rel="help" href="https://https://w3c.github.io/csswg-drafts/css-inline-3/#sizing-drop-initials">
+<meta name="assert" content="initial-letter supports the full grammar 'normal | <number [1,∞]> <integer [1,∞]> | <number [1,∞]> && [ drop | raise ]?'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+
+<script>
+test_valid_value('initial-letter', 'normal');
+test_valid_value('initial-letter', '1.23');
+test_valid_value('initial-letter', '1.23 456');
+test_valid_value('initial-letter', '1.23 calc(45.6)');
+test_valid_value('initial-letter', '1.23 drop');
+test_valid_value('initial-letter', '1.23 raise');
+test_valid_value('initial-letter', 'drop 1.23', '1.23 drop');
+test_valid_value('initial-letter', 'raise 1.23', '1.23 raise');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-namespaces/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-namespaces/OWNERS
index 54387d3..1d83d3d3 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-namespaces/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/css/css-namespaces/OWNERS
@@ -1,4 +1,3 @@
 futhark@chromium.org
 andruud@chromium.org
-ericwilligers@chromium.org
-shend@chromium.org
+ericwilligers@chromium.org
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/webkit-line-clamp-041-crash.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/webkit-line-clamp-041-crash.html
new file mode 100644
index 0000000..3f4bf3c8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/webkit-line-clamp-041-crash.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1372637">
+<div style="columns:2; column-fill:auto; line-height:20px; height:40px; orphans:2; widows:2;">
+  <div style="-webkit-line-clamp:2; display:-webkit-box; -webkit-box-orient:vertical;">
+    <br><br><br>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/webkit-line-clamp-042-crash.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/webkit-line-clamp-042-crash.html
new file mode 100644
index 0000000..1a5fe2e2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/webkit-line-clamp-042-crash.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1372637">
+<div style="columns:3; column-fill:auto; height:100px;">
+  <div style="display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; line-height:20px;">
+    Line 1<br>
+    Line 2<br>
+    Line 3<br>
+    Line 4<br>
+    Line 5<br>
+  </div>
+  <div style="break-before:avoid; break-inside:avoid; height:50px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/webkit-line-clamp-043.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/webkit-line-clamp-043.html
new file mode 100644
index 0000000..54f0ac53
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/webkit-line-clamp-043.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:3; column-fill:auto; gap:0; width:300px; height:250px;">
+  <div style="display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; overflow:clip; line-height:50px; color:transparent; background:green;">
+    <br>
+    <br>
+    <span style="color:red;">
+      FAIL<br>
+      FAIL<br>
+      FAIL<br>
+      FAIL<br>
+      FAIL<br>
+      FAIL<br>
+      FAIL<br>
+      FAIL<br>
+      FAIL<br>
+      FAIL<br>
+    </span>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-detached-subtree-expected.txt b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-detached-subtree-expected.txt
index 49adafd..ed6c7d9 100644
--- a/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-detached-subtree-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-detached-subtree-expected.txt
@@ -1,9 +1,9 @@
 This is a testharness.js-based test.
 PASS getComputedStyle returns no style for detached element
-FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) assert_equals: expected 0 but got 365
-FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) from iframe's window assert_equals: expected 0 but got 365
-FAIL getComputedStyle returns no style for element outside the flat tree assert_equals: expected 0 but got 365
-FAIL getComputedStyle returns no style for descendant outside the flat tree assert_equals: expected 0 but got 365
+FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) assert_equals: expected 0 but got 366
+FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) from iframe's window assert_equals: expected 0 but got 366
+FAIL getComputedStyle returns no style for element outside the flat tree assert_equals: expected 0 but got 366
+FAIL getComputedStyle returns no style for descendant outside the flat tree assert_equals: expected 0 but got 366
 PASS getComputedStyle returns no style for shadow tree outside of flattened tree
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-pseudo-expected.txt b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-pseudo-expected.txt
index 5ab221b..0fe62f5 100644
--- a/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-pseudo-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-pseudo-expected.txt
@@ -7,6 +7,6 @@
 PASS Item-based blockification of nonexistent pseudo-elements
 PASS display: contents on pseudo-elements
 PASS Dynamically change to display: contents on pseudo-elements
-FAIL Unknown pseudo-elements assert_equals: Should return an empty style for unknown pseudo-elements starting with double-colon expected 0 but got 365
+FAIL Unknown pseudo-elements assert_equals: Should return an empty style for unknown pseudo-elements starting with double-colon expected 0 but got 366
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/animated/observe-video.tentative.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/animated/observe-video.tentative.html
new file mode 100644
index 0000000..49bdd98
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/animated/observe-video.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset=utf-8>
+  <title>Largest Contentful Paint: observe video.</title>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script src="../resources/largest-contentful-paint-helpers.js"></script>
+</head>
+<body>
+  <script>
+    promise_test(async () => {
+      assert_implements(window.LargestContentfulPaint,
+                        "LargestContentfulPaint is not implemented");
+      const beforeLoad = performance.now();
+      // 136 is the size of the animated GIF up until the first frame.
+      // The trickle pipe delays the response after the first frame by 1 second.
+      const url = window.location.origin +
+                  `/media/test-1s.webm?pipe=trickle(1500:d${delay_pipe_value})`;
+      const entry = await load_video_and_observe(url);
+      // Video is 320 x 184.
+      const size = 320 * 184;
+      // TODO(yoav): Validate size as well as load and render times. "skip" is
+      // currently causing those checks to be skipped.
+      checkImage(entry, url, 'video_id', size, beforeLoad, ["skip"]);
+    }, "Same origin animated image is observable and has a first frame.");
+  </script>
+</body>
+</html>
+
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/largest-contentful-paint-helpers.js b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/largest-contentful-paint-helpers.js
index 5012faf..de359eb 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/largest-contentful-paint-helpers.js
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/largest-contentful-paint-helpers.js
@@ -19,6 +19,9 @@
   assert_equals(entry.id, expectedID, "Entry ID matches expected one");
   assert_equals(entry.element, document.getElementById(expectedID),
     "Entry element is expected one");
+  if (options.includes('skip')) {
+    return;
+  }
   if (options.includes('renderTimeIs0')) {
     assert_equals(entry.renderTime, 0, 'renderTime should be 0');
     assert_between_exclusive(entry.loadTime, timeLowerBound, performance.now(),
@@ -66,3 +69,22 @@
     document.body.appendChild(img);
   });
 };
+
+const load_video_and_observe = url => {
+  return new Promise(resolve => {
+    (new PerformanceObserver(entryList => {
+      for (let entry of entryList.getEntries()) {
+        if (entry.url == url) {
+          resolve(entryList.getEntries()[0]);
+        }
+      }
+    })).observe({type: 'largest-contentful-paint', buffered: true});
+    const video = document.createElement("video");
+    video.id = 'video_id';
+    video.src = url;
+    video.autoplay = true;
+    video.muted = true;
+    video.loop = true;
+    document.body.appendChild(video);
+  });
+};
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js b/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js
index 27a684e1..15bd657 100644
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js
+++ b/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js
@@ -57,7 +57,7 @@
       return;
 
     if (this.pressureServiceReadingTimerId_ != null)
-      stopPlatformCollector();
+      this.stopPlatformCollector();
 
     // The following code for calculating the timestamp was taken from
     // https://source.chromium.org/chromium/chromium/src/+/main:third_party/
diff --git a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt
index baa9eb8..c0c5706 100644
--- a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt
@@ -1,12 +1,11 @@
 This is a testharness.js-based test.
-Found 56 tests; 51 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 56 tests; 52 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS getDisplayMedia in navigator.mediaDevices
 FAIL getDisplayMedia() must require user activation assert_unreached: Should have rejected: getDisplayMedia should have returned an already-rejected promise. Reached unreachable code
 FAIL getDisplayMedia() must adhere to frameRate if set assert_greater_than_equal: expected a number greater than or equal to 2.5 but got NaN
 PASS getDisplayMedia({"video":true}) must succeed with video
 PASS getDisplayMedia({"video":true,"audio":false}) must succeed with video
 PASS getDisplayMedia({"audio":false}) must succeed with video
-FAIL getDisplayMedia({"audio":true}) must succeed with video promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio only requests are not supported"
 PASS getDisplayMedia({}) must succeed with video
 PASS getDisplayMedia(undefined) must succeed with video
 FAIL getDisplayMedia({"video":false}) must fail with TypeError assert_unreached: Should have rejected: getDisplayMedia should have returned an already-rejected promise. Reached unreachable code
@@ -19,6 +18,7 @@
 PASS getDisplayMedia({"video":{"frameRate":{"exact":4}}}) must fail with TypeError
 PASS getDisplayMedia({"video":false,"audio":true}) must fail with TypeError
 PASS getDisplayMedia({"video":true,"audio":true}) must succeed with video maybe audio
+PASS getDisplayMedia({"audio":true}) must succeed with video maybe audio
 PASS getDisplayMedia({video: {"width":{"max":360}}}) must be constrained
 PASS getDisplayMedia({video: {"height":{"max":240}}}) must be constrained
 PASS getDisplayMedia({video: {"width":{"max":360},"height":{"max":240}}}) must be constrained
diff --git a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html
index c92a7154..1c9eb44 100644
--- a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html
+++ b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html
@@ -59,7 +59,6 @@
  {video: true},
  {video: true, audio: false},
  {audio: false},
- {audio: true},
  {},
  undefined
 ].forEach(constraints => promise_test(async t => {
@@ -93,6 +92,7 @@
 
 [
  {video: true, audio: true},
+ {audio: true},
 ].forEach(constraints => promise_test(async t => {
   const stream = await getDisplayMedia(constraints);
   t.add_cleanup(() => stopTracks(stream));
diff --git a/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt b/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
new file mode 100644
index 0000000..7e8bb68
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
+PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
+FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: Failed to execute 'getDisplayMedia' on 'MediaDevices': Access to the feature "display-capture" is disallowed by permission policy.. expected "NotAllowedError" but got "SecurityError"
+PASS permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute.
+FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: Failed to execute 'getDisplayMedia' on 'MediaDevices': Access to the feature "display-capture" is disallowed by permission policy.. expected "NotAllowedError" but got "SecurityError"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt b/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt
index 0e83229..7e8bb68 100644
--- a/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt
@@ -1,8 +1,8 @@
 This is a testharness.js-based test.
-FAIL Default "display-capture" permissions policy ["self"] allows the top-level document. promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio only requests are not supported"
-FAIL Default "display-capture" permissions policy ["self"] allows same-origin iframes. assert_equals: expected "#OK" but got "#TypeError"
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#TypeError"
-FAIL permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute. assert_equals: expected "#OK" but got "#TypeError"
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#TypeError"
+PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
+PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
+FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: Failed to execute 'getDisplayMedia' on 'MediaDevices': Access to the feature "display-capture" is disallowed by permission policy.. expected "NotAllowedError" but got "SecurityError"
+PASS permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute.
+FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: Failed to execute 'getDisplayMedia' on 'MediaDevices': Access to the feature "display-capture" is disallowed by permission policy.. expected "NotAllowedError" but got "SecurityError"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt b/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt
index 669a9527..7e8bb68 100644
--- a/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt
@@ -1,8 +1,8 @@
 This is a testharness.js-based test.
 PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
 PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#OK"
+FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: Failed to execute 'getDisplayMedia' on 'MediaDevices': Access to the feature "display-capture" is disallowed by permission policy.. expected "NotAllowedError" but got "SecurityError"
 PASS permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute.
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#OK"
+FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: Failed to execute 'getDisplayMedia' on 'MediaDevices': Access to the feature "display-capture" is disallowed by permission policy.. expected "NotAllowedError" but got "SecurityError"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/credentialed-prerender-not-opt-in.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/credentialed-prerender-not-opt-in.html
new file mode 100644
index 0000000..8c797b8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/credentialed-prerender-not-opt-in.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>same-site cross-origin prerendering not opt in</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js"></script>
+<script src="resources/utils.js"></script>
+
+<script>
+setup(() => assertSpeculationRulesIsSupported());
+
+promise_test(async t => {
+  const rcHelper = new RemoteContextHelper();
+  const referrerRC = await rcHelper.addWindow({origin: 'HTTPS_ORIGIN'}, { features: 'noopener' });
+  const prerenderedRC = await addPrerenderRC(referrerRC, {origin: 'HTTPS_REMOTE_ORIGIN'});
+
+  // Because the prerender doesn't use opt-in header, it is expected to be canceled.
+  // And the navigation is expected to create another page instead of activation.
+  referrerRC.navigateTo(prerenderedRC.url);
+  assert_equals(await getActivationStart(prerenderedRC), 0);
+});
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/credentialed-prerender-opt-in.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/credentialed-prerender-opt-in.html
new file mode 100644
index 0000000..eb8fd3cd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/credentialed-prerender-opt-in.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>same-site cross-origin prerendering opt in</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js"></script>
+<script src="resources/utils.js"></script>
+
+<script>
+setup(() => assertSpeculationRulesIsSupported());
+
+promise_test(async t => {
+  const rcHelper = new RemoteContextHelper();
+  const referrerRC = await rcHelper.addWindow({origin: 'HTTPS_ORIGIN'}, { features: 'noopener' });
+  const prerenderedRC = await addPrerenderRC(referrerRC, {origin: 'HTTPS_REMOTE_ORIGIN', headers: [['Supports-Loading-Mode', 'credentialed-prerender']] });
+
+  await activatePrerenderRC(referrerRC, prerenderedRC);
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js
index d47ca7f..d945924 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js
@@ -295,7 +295,7 @@
  *
  * See
  * /html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
- * for more details on the `RemoteContextWrapper` framework.
+ * for more details on the `RemoteContextWrapper` framework, and supported fields for extraConfig.
  *
  * The returned `RemoteContextWrapper` for the prerendered remote
  * context will have an extra `url` property, which is used by
@@ -304,9 +304,10 @@
  * a prerendered page after creating it.)
  *
  * @param {RemoteContextWrapper} referrerRemoteContext
+ * @param {RemoteContextConfig|object} extraConfig
  * @returns {Promise<RemoteContextWrapper>}
  */
-async function addPrerenderRC(referrerRemoteContext) {
+async function addPrerenderRC(referrerRemoteContext, extraConfig) {
   let savedURL;
   const prerenderedRC = await referrerRemoteContext.helper.createContext({
     executorCreator(url) {
@@ -327,7 +328,7 @@
         });
         document.head.append(script);
       }, [url]);
-    }
+    }, extraConfig
   });
 
   prerenderedRC.url = savedURL;
@@ -383,6 +384,13 @@
   );
 }
 
+async function getActivationStart(prerenderedRC) {
+  return await prerenderedRC.executeScript(() => {
+    const entry = performance.getEntriesByType("navigation")[0];
+    return entry.activationStart;
+  });;
+}
+
 // Used by the opened window, to tell the main test runner to terminate a
 // failed test.
 function failTest(reason, uid) {
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-001-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-001-expected.txt
index ca973cf..26a808f 100644
--- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-001-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-001-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 304 tests; 302 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 307 tests; 305 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testAccumulation function
 PASS align-content: "flex-end" onto "flex-start"
@@ -304,5 +304,8 @@
 PASS image-orientation (type: discrete) has testAccumulation function
 PASS image-orientation: "from-image" onto "none"
 PASS image-orientation: "none" onto "from-image"
+PASS initial-letter (type: discrete) has testAccumulation function
+PASS initial-letter: "3 4" onto "1 2"
+PASS initial-letter: "1 2" onto "3 4"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-001-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-001-expected.txt
index a711accf..43fd0879 100644
--- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-001-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-001-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 304 tests; 302 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 307 tests; 305 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testAddition function
 PASS align-content: "flex-end" onto "flex-start"
@@ -304,5 +304,8 @@
 PASS image-orientation (type: discrete) has testAddition function
 PASS image-orientation: "from-image" onto "none"
 PASS image-orientation: "none" onto "from-image"
+PASS initial-letter (type: discrete) has testAddition function
+PASS initial-letter: "3 4" onto "1 2"
+PASS initial-letter: "1 2" onto "3 4"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-001-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-001-expected.txt
index b9f21595f..c48c09d 100644
--- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-001-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-001-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 377 tests; 365 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 381 tests; 369 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testInterpolation function
 PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
@@ -377,5 +377,9 @@
 PASS image-orientation uses discrete animation when animating between "none" and "from-image" with linear easing
 PASS image-orientation uses discrete animation when animating between "none" and "from-image" with effect easing
 PASS image-orientation uses discrete animation when animating between "none" and "from-image" with keyframe easing
+PASS initial-letter (type: discrete) has testInterpolation function
+PASS initial-letter uses discrete animation when animating between "1 2" and "3 4" with linear easing
+PASS initial-letter uses discrete animation when animating between "1 2" and "3 4" with effect easing
+PASS initial-letter uses discrete animation when animating between "1 2" and "3 4" with keyframe easing
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/webnn/idlharness.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/idlharness.https.any-expected.txt
index 8f3597f75..d3ff6ff3 100644
--- a/third_party/blink/web_tests/external/wpt/webnn/idlharness.https.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webnn/idlharness.https.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 389 tests; 157 PASS, 232 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 389 tests; 164 PASS, 225 FAIL, 0 TIMEOUT, 0 NOTRUN.
 FAIL idl_test setup promise_test: Unhandled rejection with value: object "TypeError: Failed to construct 'MLGraphBuilder': parameter 1 is not of type 'MLContext'."
 PASS idl_test validation
 PASS Partial interface MLContext: original interface defined
@@ -163,7 +163,7 @@
 FAIL MLGraphBuilder interface: operation constant(MLOperandDescriptor, MLBufferView) assert_equals: property has wrong .length expected 1 but got 2
 FAIL MLGraphBuilder interface: operation constant(double, optional MLOperandType) assert_equals: property has wrong .length expected 1 but got 2
 PASS MLGraphBuilder interface: member build
-FAIL MLGraphBuilder interface: operation buildAsync(MLNamedOperands) assert_own_property: interface prototype object missing non-static operation expected property "buildAsync" missing
+PASS MLGraphBuilder interface: operation buildAsync(MLNamedOperands)
 FAIL MLGraphBuilder interface: operation batchNormalization(MLOperand, MLOperand, MLOperand, optional MLBatchNormalizationOptions) assert_own_property: interface prototype object missing non-static operation expected property "batchNormalization" missing
 PASS MLGraphBuilder interface: operation clamp(MLOperand, optional MLClampOptions)
 PASS MLGraphBuilder interface: operation clamp(optional MLClampOptions)
@@ -374,12 +374,12 @@
 FAIL MLGraphBuilder interface: builder must inherit property "tanh()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: builder is not defined"
 FAIL MLGraphBuilder interface: builder must inherit property "transpose(MLOperand, optional MLTransposeOptions)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: builder is not defined"
 FAIL MLGraphBuilder interface: calling transpose(MLOperand, optional MLTransposeOptions) on builder with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: builder is not defined"
-FAIL MLGraph interface: existence and properties of interface object assert_own_property: self does not have own property "MLGraph" expected property "MLGraph" missing
-FAIL MLGraph interface object length assert_own_property: self does not have own property "MLGraph" expected property "MLGraph" missing
-FAIL MLGraph interface object name assert_own_property: self does not have own property "MLGraph" expected property "MLGraph" missing
-FAIL MLGraph interface: existence and properties of interface prototype object assert_own_property: self does not have own property "MLGraph" expected property "MLGraph" missing
-FAIL MLGraph interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "MLGraph" expected property "MLGraph" missing
-FAIL MLGraph interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "MLGraph" expected property "MLGraph" missing
+PASS MLGraph interface: existence and properties of interface object
+PASS MLGraph interface object length
+PASS MLGraph interface object name
+PASS MLGraph interface: existence and properties of interface prototype object
+PASS MLGraph interface: existence and properties of interface prototype object's "constructor" property
+PASS MLGraph interface: existence and properties of interface prototype object's @@unscopables property
 FAIL MLGraph must be primary interface of graph assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: graph is not defined"
 FAIL Stringification of graph assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: graph is not defined"
 FAIL MLCommandEncoder interface: existence and properties of interface object assert_own_property: self does not have own property "MLCommandEncoder" expected property "MLCommandEncoder" missing
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/constructor.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/constructor.html.ini
new file mode 100644
index 0000000..60f815f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/constructor.html.ini
@@ -0,0 +1,6 @@
+[constructor.html]
+  [VTTCue(), initial values]
+    expected: FAIL
+
+  [VTTCue(), unbounded end time]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/getCueAsHTML.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/getCueAsHTML.html.ini
new file mode 100644
index 0000000..d31292f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/getCueAsHTML.html.ini
@@ -0,0 +1,3 @@
+[getCueAsHTML.html]
+  [VTTCue.getCueAsHTML(), x\\0]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/lineAlign.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/lineAlign.html.ini
new file mode 100644
index 0000000..0fb67d6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/lineAlign.html.ini
@@ -0,0 +1,3 @@
+[lineAlign.html]
+  [VTTCue.lineAlign, script-created cue]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/positionAlign.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/positionAlign.html.ini
new file mode 100644
index 0000000..a05ab835
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/positionAlign.html.ini
@@ -0,0 +1,3 @@
+[positionAlign.html]
+  [VTTCue.positionAlign, script-created cue]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/region.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/region.html.ini
new file mode 100644
index 0000000..7c459fc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/api/VTTCue/region.html.ini
@@ -0,0 +1,3 @@
+[region.html]
+  [VTTCue.region, script-created cue]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/api/idlharness.window.js.ini b/third_party/blink/web_tests/external/wpt/webvtt/api/idlharness.window.js.ini
new file mode 100644
index 0000000..c5a097b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/api/idlharness.window.js.ini
@@ -0,0 +1,12 @@
+[idlharness.window.html]
+  [VTTCue interface: attribute lineAlign]
+    expected: FAIL
+
+  [VTTCue interface: attribute positionAlign]
+    expected: FAIL
+
+  [VTTCue interface: new VTTCue(0, 0, "") must inherit property "lineAlign" with the proper type]
+    expected: FAIL
+
+  [VTTCue interface: new VTTCue(0, 0, "") must inherit property "positionAlign" with the proper type]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/regions-id.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/regions-id.html.ini
new file mode 100644
index 0000000..7210e89
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/regions-id.html.ini
@@ -0,0 +1,3 @@
+[regions-id.html]
+  [regions, id]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/regions-lines.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/regions-lines.html.ini
new file mode 100644
index 0000000..34a94ce
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/regions-lines.html.ini
@@ -0,0 +1,3 @@
+[regions-lines.html]
+  [regions, lines]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/settings-line.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/settings-line.html.ini
new file mode 100644
index 0000000..40340c9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/settings-line.html.ini
@@ -0,0 +1,3 @@
+[settings-line.html]
+  [settings, line]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/settings-position.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/settings-position.html.ini
new file mode 100644
index 0000000..e08fa57
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/parsing/file-parsing/tests/settings-position.html.ini
@@ -0,0 +1,3 @@
+[settings-position.html]
+  [settings, position]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html.ini
new file mode 100644
index 0000000..6892bcb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html.ini
@@ -0,0 +1,2 @@
+[2_cues_overlapping_completely_move_up.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html.ini
new file mode 100644
index 0000000..6ec3e67
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html.ini
@@ -0,0 +1,2 @@
+[2_cues_overlapping_partially_move_down.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_up.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_up.html.ini
new file mode 100644
index 0000000..6437cad
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_up.html.ini
@@ -0,0 +1,2 @@
+[2_cues_overlapping_partially_move_up.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_tracks.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_tracks.html.ini
new file mode 100644
index 0000000..c4e6639
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/2_tracks.html.ini
@@ -0,0 +1,2 @@
+[2_tracks.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/3_tracks.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/3_tracks.html.ini
new file mode 100644
index 0000000..62f6650
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/3_tracks.html.ini
@@ -0,0 +1,2 @@
+[3_tracks.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center.html.ini
new file mode 100644
index 0000000..9f1e261
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center.html.ini
@@ -0,0 +1,2 @@
+[align_center.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_50.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_50.html.ini
new file mode 100644
index 0000000..43907ec
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_50.html.ini
@@ -0,0 +1,2 @@
+[align_center_position_50.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_gt_50.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_gt_50.html.ini
new file mode 100644
index 0000000..e479266
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_gt_50.html.ini
@@ -0,0 +1,2 @@
+[align_center_position_gt_50.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_gt_50_size_gt_maximum_size.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_gt_50_size_gt_maximum_size.html.ini
new file mode 100644
index 0000000..c2ba0fe
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_gt_50_size_gt_maximum_size.html.ini
@@ -0,0 +1,2 @@
+[align_center_position_gt_50_size_gt_maximum_size.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_lt_50.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_lt_50.html.ini
new file mode 100644
index 0000000..82893345
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_lt_50.html.ini
@@ -0,0 +1,2 @@
+[align_center_position_lt_50.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_lt_50_size_gt_maximum_size.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_lt_50_size_gt_maximum_size.html.ini
new file mode 100644
index 0000000..fec6adb8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_position_lt_50_size_gt_maximum_size.html.ini
@@ -0,0 +1,2 @@
+[align_center_position_lt_50_size_gt_maximum_size.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_wrapped.html.ini
new file mode 100644
index 0000000..3175a4d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_center_wrapped.html.ini
@@ -0,0 +1,2 @@
+[align_center_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end.html.ini
new file mode 100644
index 0000000..db18437
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end.html.ini
@@ -0,0 +1,2 @@
+[align_end.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end_wrapped.html.ini
new file mode 100644
index 0000000..7b9ce4a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end_wrapped.html.ini
@@ -0,0 +1,2 @@
+[align_end_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start.html.ini
new file mode 100644
index 0000000..e6275575
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start.html.ini
@@ -0,0 +1,2 @@
+[align_start.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start_wrapped.html.ini
new file mode 100644
index 0000000..42468adf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start_wrapped.html.ini
@@ -0,0 +1,2 @@
+[align_start_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/basic.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/basic.html.ini
new file mode 100644
index 0000000..71c924c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/basic.html.ini
@@ -0,0 +1,2 @@
+[basic.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/bidi_ruby.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/bidi_ruby.html.ini
new file mode 100644
index 0000000..7f0b73a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/bidi_ruby.html.ini
@@ -0,0 +1,2 @@
+[bidi_ruby.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/start_alignment.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/start_alignment.html.ini
new file mode 100644
index 0000000..c7258a44
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/start_alignment.html.ini
@@ -0,0 +1,2 @@
+[start_alignment.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_LF_u05D0.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_LF_u05D0.html.ini
new file mode 100644
index 0000000..d06c91f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_LF_u05D0.html.ini
@@ -0,0 +1,2 @@
+[u002E_LF_u05D0.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2028_u05D0.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2028_u05D0.html.ini
new file mode 100644
index 0000000..8d4a9cd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2028_u05D0.html.ini
@@ -0,0 +1,2 @@
+[u002E_u2028_u05D0.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2029_u05D0.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2029_u05D0.html.ini
new file mode 100644
index 0000000..1a83940
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2029_u05D0.html.ini
@@ -0,0 +1,2 @@
+[u002E_u2029_u05D0.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u0041_first.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u0041_first.html.ini
new file mode 100644
index 0000000..f67556a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u0041_first.html.ini
@@ -0,0 +1,2 @@
+[u0041_first.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u05D0_first.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u05D0_first.html.ini
new file mode 100644
index 0000000..097c6c7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u05D0_first.html.ini
@@ -0,0 +1,2 @@
+[u05D0_first.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u0628_first.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u0628_first.html.ini
new file mode 100644
index 0000000..c9921f1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u0628_first.html.ini
@@ -0,0 +1,2 @@
+[u0628_first.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u06E9_no_strong_dir.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u06E9_no_strong_dir.html.ini
new file mode 100644
index 0000000..7896b16
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/u06E9_no_strong_dir.html.ini
@@ -0,0 +1,2 @@
+[u06E9_no_strong_dir.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_lr.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_lr.html.ini
new file mode 100644
index 0000000..7b1a53ab
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_lr.html.ini
@@ -0,0 +1,2 @@
+[vertical_lr.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_rl.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_rl.html.ini
new file mode 100644
index 0000000..195bd7e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_rl.html.ini
@@ -0,0 +1,2 @@
+[vertical_rl.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/cue_too_long.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/cue_too_long.html.ini
new file mode 100644
index 0000000..27d8e577
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/cue_too_long.html.ini
@@ -0,0 +1,2 @@
+[cue_too_long.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/decode_escaped_entities.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/decode_escaped_entities.html.ini
new file mode 100644
index 0000000..37e271e2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/decode_escaped_entities.html.ini
@@ -0,0 +1,2 @@
+[decode_escaped_entities.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/disable_controls_reposition.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/disable_controls_reposition.html.ini
new file mode 100644
index 0000000..e05ee8bd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/disable_controls_reposition.html.ini
@@ -0,0 +1,2 @@
+[disable_controls_reposition.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size.html.ini
new file mode 100644
index 0000000..0985c534
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size.html.ini
@@ -0,0 +1,2 @@
+[dom_override_cue_align_position_line_size.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size_while_paused.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size_while_paused.html.ini
new file mode 100644
index 0000000..a648314d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size_while_paused.html.ini
@@ -0,0 +1,2 @@
+[dom_override_cue_align_position_line_size_while_paused.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_line.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_line.html.ini
new file mode 100644
index 0000000..9e5ce273
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_line.html.ini
@@ -0,0 +1,2 @@
+[dom_override_cue_line.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text.html.ini
new file mode 100644
index 0000000..0879cf29
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text.html.ini
@@ -0,0 +1,2 @@
+[dom_override_cue_text.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text_while_paused.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text_while_paused.html.ini
new file mode 100644
index 0000000..3815b4f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text_while_paused.html.ini
@@ -0,0 +1,2 @@
+[dom_override_cue_text_while_paused.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/enable_controls_reposition.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/enable_controls_reposition.html.ini
new file mode 100644
index 0000000..ec1a8ee2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/enable_controls_reposition.html.ini
@@ -0,0 +1,2 @@
+[enable_controls_reposition.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely.html.ini
new file mode 100644
index 0000000..929cd75d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely.html.ini
@@ -0,0 +1,2 @@
+[9_cues_overlapping_completely.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely_all_cues_have_same_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely_all_cues_have_same_timestamp.html.ini
new file mode 100644
index 0000000..38ebba6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely_all_cues_have_same_timestamp.html.ini
@@ -0,0 +1,2 @@
+[9_cues_overlapping_completely_all_cues_have_same_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/media_height_19.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/media_height_19.html.ini
new file mode 100644
index 0000000..64882286
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/media_height_19.html.ini
@@ -0,0 +1,2 @@
+[media_height_19.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/single_quote.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/single_quote.html.ini
new file mode 100644
index 0000000..d5d4df5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/single_quote.html.ini
@@ -0,0 +1,2 @@
+[single_quote.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/size_90.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/size_90.html.ini
new file mode 100644
index 0000000..c6c388f7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/size_90.html.ini
@@ -0,0 +1,2 @@
+[size_90.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/size_99.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/size_99.html.ini
new file mode 100644
index 0000000..a6312947
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/evil/size_99.html.ini
@@ -0,0 +1,2 @@
+[size_99.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_-2_wrapped_cue_grow_upwards.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_-2_wrapped_cue_grow_upwards.html.ini
new file mode 100644
index 0000000..589205a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_-2_wrapped_cue_grow_upwards.html.ini
@@ -0,0 +1,2 @@
+[line_-2_wrapped_cue_grow_upwards.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_0_is_top.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_0_is_top.html.ini
new file mode 100644
index 0000000..92f67736
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_0_is_top.html.ini
@@ -0,0 +1,2 @@
+[line_0_is_top.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_1_wrapped_cue_grow_downwards.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_1_wrapped_cue_grow_downwards.html.ini
new file mode 100644
index 0000000..37e84c5d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_1_wrapped_cue_grow_downwards.html.ini
@@ -0,0 +1,2 @@
+[line_1_wrapped_cue_grow_downwards.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_50_percent.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_50_percent.html.ini
new file mode 100644
index 0000000..a849999
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_50_percent.html.ini
@@ -0,0 +1,2 @@
+[line_50_percent.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap.html.ini
new file mode 100644
index 0000000..074470b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap.html.ini
@@ -0,0 +1,2 @@
+[line_integer_and_percent_mixed_overlap.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap_move_up.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap_move_up.html.ini
new file mode 100644
index 0000000..158c703
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap_move_up.html.ini
@@ -0,0 +1,2 @@
+[line_integer_and_percent_mixed_overlap_move_up.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap.html.ini
new file mode 100644
index 0000000..496732b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap.html.ini
@@ -0,0 +1,2 @@
+[line_percent_and_integer_mixed_overlap.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap_move_up.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap_move_up.html.ini
new file mode 100644
index 0000000..559d092
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap_move_up.html.ini
@@ -0,0 +1,2 @@
+[line_percent_and_integer_mixed_overlap_move_up.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/media_height400_with_controls.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/media_height400_with_controls.html.ini
new file mode 100644
index 0000000..18e3a2e7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/media_height400_with_controls.html.ini
@@ -0,0 +1,2 @@
+[media_height400_with_controls.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/media_with_controls.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/media_with_controls.html.ini
new file mode 100644
index 0000000..62064606
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/media_with_controls.html.ini
@@ -0,0 +1,2 @@
+[media_with_controls.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/navigate_cue_position.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/navigate_cue_position.html.ini
new file mode 100644
index 0000000..d0a4880
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/navigate_cue_position.html.ini
@@ -0,0 +1,2 @@
+[navigate_cue_position.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/one_line_cue_plus_wrapped_cue.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/one_line_cue_plus_wrapped_cue.html.ini
new file mode 100644
index 0000000..dc85737
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/one_line_cue_plus_wrapped_cue.html.ini
@@ -0,0 +1,2 @@
+[one_line_cue_plus_wrapped_cue.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/basic.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/basic.html.ini
new file mode 100644
index 0000000..71c924c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/basic.html.ini
@@ -0,0 +1,2 @@
+[basic.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/regionanchor_x_50_percent.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/regionanchor_x_50_percent.html.ini
new file mode 100644
index 0000000..e6ff2c1f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/regionanchor_x_50_percent.html.ini
@@ -0,0 +1,2 @@
+[regionanchor_x_50_percent.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/regionanchor_y_50_percent.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/regionanchor_y_50_percent.html.ini
new file mode 100644
index 0000000..85ccf3bc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/regionanchor_y_50_percent.html.ini
@@ -0,0 +1,2 @@
+[regionanchor_y_50_percent.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/scroll_up.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/scroll_up.html.ini
new file mode 100644
index 0000000..923f5eb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/scroll_up.html.ini
@@ -0,0 +1,2 @@
+[scroll_up.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/single_line_top_left.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/single_line_top_left.html.ini
new file mode 100644
index 0000000..a970f9d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/single_line_top_left.html.ini
@@ -0,0 +1,2 @@
+[single_line_top_left.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/viewportanchor_x_50_percent.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/viewportanchor_x_50_percent.html.ini
new file mode 100644
index 0000000..e50c027
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/viewportanchor_x_50_percent.html.ini
@@ -0,0 +1,2 @@
+[viewportanchor_x_50_percent.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/viewportanchor_y_50_percent.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/viewportanchor_y_50_percent.html.ini
new file mode 100644
index 0000000..c26599df
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/viewportanchor_y_50_percent.html.ini
@@ -0,0 +1,2 @@
+[viewportanchor_y_50_percent.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/width_50_percent.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/width_50_percent.html.ini
new file mode 100644
index 0000000..6d91bc0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/width_50_percent.html.ini
@@ -0,0 +1,2 @@
+[width_50_percent.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/repaint.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/repaint.html.ini
new file mode 100644
index 0000000..14541dd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/repaint.html.ini
@@ -0,0 +1,2 @@
+[repaint.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue-region/font_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue-region/font_properties.html.ini
new file mode 100644
index 0000000..d1743fc6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue-region/font_properties.html.ini
@@ -0,0 +1,2 @@
+[font_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue-region_function/font_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue-region_function/font_properties.html.ini
new file mode 100644
index 0000000..d1743fc6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue-region_function/font_properties.html.ini
@@ -0,0 +1,2 @@
+[font_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_properties.html.ini
new file mode 100644
index 0000000..1c4067b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_properties.html.ini
@@ -0,0 +1,2 @@
+[background_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand.html.ini
new file mode 100644
index 0000000..c668922
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand.html.ini
@@ -0,0 +1,2 @@
+[background_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand_css_relative_url.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand_css_relative_url.html.ini
new file mode 100644
index 0000000..2784c4f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand_css_relative_url.html.ini
@@ -0,0 +1,2 @@
+[background_shorthand_css_relative_url.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hex.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hex.html.ini
new file mode 100644
index 0000000..dd33dbd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hex.html.ini
@@ -0,0 +1,2 @@
+[color_hex.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hsla.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hsla.html.ini
new file mode 100644
index 0000000..1967248
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hsla.html.ini
@@ -0,0 +1,2 @@
+[color_hsla.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_rgba.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_rgba.html.ini
new file mode 100644
index 0000000..c0bb173c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_rgba.html.ini
@@ -0,0 +1,2 @@
+[color_rgba.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/cue_selector_single_colon.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/cue_selector_single_colon.html.ini
new file mode 100644
index 0000000..3d3a2d7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/cue_selector_single_colon.html.ini
@@ -0,0 +1,2 @@
+[cue_selector_single_colon.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_properties.html.ini
new file mode 100644
index 0000000..d1743fc6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_properties.html.ini
@@ -0,0 +1,2 @@
+[font_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_shorthand.html.ini
new file mode 100644
index 0000000..07bef8fa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_shorthand.html.ini
@@ -0,0 +1,2 @@
+[font_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/inherit_values_from_media_element.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/inherit_values_from_media_element.html.ini
new file mode 100644
index 0000000..de9ddf4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/inherit_values_from_media_element.html.ini
@@ -0,0 +1,2 @@
+[inherit_values_from_media_element.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_properties.html.ini
new file mode 100644
index 0000000..4d8e07a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_properties.html.ini
@@ -0,0 +1,2 @@
+[outline_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_shorthand.html.ini
new file mode 100644
index 0000000..13b2417
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_shorthand.html.ini
@@ -0,0 +1,2 @@
+[outline_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_line-through.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_line-through.html.ini
new file mode 100644
index 0000000..a63ffd3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_line-through.html.ini
@@ -0,0 +1,2 @@
+[text-decoration_line-through.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline.html.ini
new file mode 100644
index 0000000..74ff2291
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline.html.ini
@@ -0,0 +1,2 @@
+[text-decoration_overline.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline_underline_line-through.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline_underline_line-through.html.ini
new file mode 100644
index 0000000..9ec52d7f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline_underline_line-through.html.ini
@@ -0,0 +1,2 @@
+[text-decoration_overline_underline_line-through.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_underline.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_underline.html.ini
new file mode 100644
index 0000000..2b298de9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_underline.html.ini
@@ -0,0 +1,2 @@
+[text-decoration_underline.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-shadow.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-shadow.html.ini
new file mode 100644
index 0000000..567ce6d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-shadow.html.ini
@@ -0,0 +1,2 @@
+[text-shadow.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/vertical_ruby-position.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/vertical_ruby-position.html.ini
new file mode 100644
index 0000000..a9f04d24
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/vertical_ruby-position.html.ini
@@ -0,0 +1,2 @@
+[vertical_ruby-position.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/vertical_text-combine-upright.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/vertical_text-combine-upright.html.ini
new file mode 100644
index 0000000..5fa1bc9f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/vertical_text-combine-upright.html.ini
@@ -0,0 +1,2 @@
+[vertical_text-combine-upright.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_normal_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_normal_wrapped.html.ini
new file mode 100644
index 0000000..8992a83
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_normal_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_normal_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_nowrap_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_nowrap_wrapped.html.ini
new file mode 100644
index 0000000..ae503769
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_nowrap_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_nowrap_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-line_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-line_wrapped.html.ini
new file mode 100644
index 0000000..d7d36df
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-line_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_pre-line_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-wrap_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-wrap_wrapped.html.ini
new file mode 100644
index 0000000..e4ddc89
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-wrap_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_pre-wrap_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre.html.ini
new file mode 100644
index 0000000..d8fd7318
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre.html.ini
@@ -0,0 +1,2 @@
+[white-space_pre.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre_wrapped.html.ini
new file mode 100644
index 0000000..b88a5e26
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_pre_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_box.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_box.html.ini
new file mode 100644
index 0000000..568758c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_box.html.ini
@@ -0,0 +1,2 @@
+[background_box.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_properties.html.ini
new file mode 100644
index 0000000..1c4067b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_properties.html.ini
@@ -0,0 +1,2 @@
+[background_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand.html.ini
new file mode 100644
index 0000000..c668922
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand.html.ini
@@ -0,0 +1,2 @@
+[background_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand_css_relative_url.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand_css_relative_url.html.ini
new file mode 100644
index 0000000..2784c4f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand_css_relative_url.html.ini
@@ -0,0 +1,2 @@
+[background_shorthand_css_relative_url.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_animation_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_animation_with_timestamp.html.ini
new file mode 100644
index 0000000..bd2c741b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_animation_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[bold_animation_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_properties.html.ini
new file mode 100644
index 0000000..f0cf67cf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_properties.html.ini
@@ -0,0 +1,2 @@
+[bold_background_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_shorthand.html.ini
new file mode 100644
index 0000000..193621c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_shorthand.html.ini
@@ -0,0 +1,2 @@
+[bold_background_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_color.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_color.html.ini
new file mode 100644
index 0000000..c565355b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_color.html.ini
@@ -0,0 +1,2 @@
+[bold_color.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_properties.html.ini
new file mode 100644
index 0000000..24fe59f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_properties.html.ini
@@ -0,0 +1,2 @@
+[bold_font_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_shorthand.html.ini
new file mode 100644
index 0000000..c99fece
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_shorthand.html.ini
@@ -0,0 +1,2 @@
+[bold_font_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_namespace.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_namespace.html.ini
new file mode 100644
index 0000000..b0e4257
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_namespace.html.ini
@@ -0,0 +1,2 @@
+[bold_namespace.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_properties.html.ini
new file mode 100644
index 0000000..0c9e8a5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_properties.html.ini
@@ -0,0 +1,2 @@
+[bold_outline_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_shorthand.html.ini
new file mode 100644
index 0000000..8a37c499
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_shorthand.html.ini
@@ -0,0 +1,2 @@
+[bold_outline_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-decoration_line-through.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-decoration_line-through.html.ini
new file mode 100644
index 0000000..42b3cac4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-decoration_line-through.html.ini
@@ -0,0 +1,2 @@
+[bold_text-decoration_line-through.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-shadow.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-shadow.html.ini
new file mode 100644
index 0000000..3f10f31
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-shadow.html.ini
@@ -0,0 +1,2 @@
+[bold_text-shadow.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_future.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_future.html.ini
new file mode 100644
index 0000000..7cb93e6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_future.html.ini
@@ -0,0 +1,2 @@
+[bold_timestamp_future.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_past.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_past.html.ini
new file mode 100644
index 0000000..502e25e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_past.html.ini
@@ -0,0 +1,2 @@
+[bold_timestamp_past.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_transition_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_transition_with_timestamp.html.ini
new file mode 100644
index 0000000..f910f5b8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_transition_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[bold_transition_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_normal_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_normal_wrapped.html.ini
new file mode 100644
index 0000000..47a1dc9a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_normal_wrapped.html.ini
@@ -0,0 +1,2 @@
+[bold_white-space_normal_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_nowrap.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_nowrap.html.ini
new file mode 100644
index 0000000..ea083aa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_nowrap.html.ini
@@ -0,0 +1,2 @@
+[bold_white-space_nowrap.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-line_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-line_wrapped.html.ini
new file mode 100644
index 0000000..dbda9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-line_wrapped.html.ini
@@ -0,0 +1,2 @@
+[bold_white-space_pre-line_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-wrap_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-wrap_wrapped.html.ini
new file mode 100644
index 0000000..cb82c8c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-wrap_wrapped.html.ini
@@ -0,0 +1,2 @@
+[bold_white-space_pre-wrap_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre_wrapped.html.ini
new file mode 100644
index 0000000..2f98278
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre_wrapped.html.ini
@@ -0,0 +1,2 @@
+[bold_white-space_pre_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class.html.ini
new file mode 100644
index 0000000..893cca7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class.html.ini
@@ -0,0 +1,2 @@
+[bold_with_class.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class_object_specific_selector.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class_object_specific_selector.html.ini
new file mode 100644
index 0000000..9c16c05b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class_object_specific_selector.html.ini
@@ -0,0 +1,2 @@
+[bold_with_class_object_specific_selector.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_animation_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_animation_with_timestamp.html.ini
new file mode 100644
index 0000000..d7b1b10
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_animation_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[class_animation_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_properties.html.ini
new file mode 100644
index 0000000..5cad43a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_properties.html.ini
@@ -0,0 +1,2 @@
+[class_background_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_shorthand.html.ini
new file mode 100644
index 0000000..9b3af13c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_shorthand.html.ini
@@ -0,0 +1,2 @@
+[class_background_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_color.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_color.html.ini
new file mode 100644
index 0000000..dbd9954
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_color.html.ini
@@ -0,0 +1,2 @@
+[class_color.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_properties.html.ini
new file mode 100644
index 0000000..eeb27f02
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_properties.html.ini
@@ -0,0 +1,2 @@
+[class_font_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_shorthand.html.ini
new file mode 100644
index 0000000..29d1132
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_shorthand.html.ini
@@ -0,0 +1,2 @@
+[class_font_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_namespace.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_namespace.html.ini
new file mode 100644
index 0000000..4d6bade
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_namespace.html.ini
@@ -0,0 +1,2 @@
+[class_namespace.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_properties.html.ini
new file mode 100644
index 0000000..3488655
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_properties.html.ini
@@ -0,0 +1,2 @@
+[class_outline_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_shorthand.html.ini
new file mode 100644
index 0000000..1b76845f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_shorthand.html.ini
@@ -0,0 +1,2 @@
+[class_outline_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-decoration_line-through.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-decoration_line-through.html.ini
new file mode 100644
index 0000000..daa4767
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-decoration_line-through.html.ini
@@ -0,0 +1,2 @@
+[class_text-decoration_line-through.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-shadow.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-shadow.html.ini
new file mode 100644
index 0000000..e8cc9f5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-shadow.html.ini
@@ -0,0 +1,2 @@
+[class_text-shadow.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_future.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_future.html.ini
new file mode 100644
index 0000000..b57b6c3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_future.html.ini
@@ -0,0 +1,2 @@
+[class_timestamp_future.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_past.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_past.html.ini
new file mode 100644
index 0000000..23023b1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_past.html.ini
@@ -0,0 +1,2 @@
+[class_timestamp_past.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_transition_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_transition_with_timestamp.html.ini
new file mode 100644
index 0000000..2097db9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_transition_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[class_transition_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_vertical_text-combine-upright.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_vertical_text-combine-upright.html.ini
new file mode 100644
index 0000000..b6d979c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_vertical_text-combine-upright.html.ini
@@ -0,0 +1,2 @@
+[class_vertical_text-combine-upright.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped.html.ini
new file mode 100644
index 0000000..035b3eb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped.html.ini
@@ -0,0 +1,2 @@
+[class_white-space_normal_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_nowrap.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_nowrap.html.ini
new file mode 100644
index 0000000..155396b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_nowrap.html.ini
@@ -0,0 +1,2 @@
+[class_white-space_nowrap.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped.html.ini
new file mode 100644
index 0000000..b852c4a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped.html.ini
@@ -0,0 +1,2 @@
+[class_white-space_pre-line_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-wrap_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-wrap_wrapped.html.ini
new file mode 100644
index 0000000..242a5e3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-wrap_wrapped.html.ini
@@ -0,0 +1,2 @@
+[class_white-space_pre-wrap_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre_wrapped.html.ini
new file mode 100644
index 0000000..19c099a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre_wrapped.html.ini
@@ -0,0 +1,2 @@
+[class_white-space_pre_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class.html.ini
new file mode 100644
index 0000000..44662a0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class.html.ini
@@ -0,0 +1,2 @@
+[class_with_class.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class_object_specific_selector.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class_object_specific_selector.html.ini
new file mode 100644
index 0000000..a50ab7b5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class_object_specific_selector.html.ini
@@ -0,0 +1,2 @@
+[class_with_class_object_specific_selector.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hex.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hex.html.ini
new file mode 100644
index 0000000..dd33dbd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hex.html.ini
@@ -0,0 +1,2 @@
+[color_hex.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hsla.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hsla.html.ini
new file mode 100644
index 0000000..1967248
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hsla.html.ini
@@ -0,0 +1,2 @@
+[color_hsla.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_rgba.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_rgba.html.ini
new file mode 100644
index 0000000..c0bb173c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_rgba.html.ini
@@ -0,0 +1,2 @@
+[color_rgba.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/cue_func_selector_single_colon.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/cue_func_selector_single_colon.html.ini
new file mode 100644
index 0000000..3642895
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/cue_func_selector_single_colon.html.ini
@@ -0,0 +1,2 @@
+[cue_func_selector_single_colon.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_properties.html.ini
new file mode 100644
index 0000000..d1743fc6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_properties.html.ini
@@ -0,0 +1,2 @@
+[font_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_shorthand.html.ini
new file mode 100644
index 0000000..07bef8fa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_shorthand.html.ini
@@ -0,0 +1,2 @@
+[font_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/id_color.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/id_color.html.ini
new file mode 100644
index 0000000..b467256
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/id_color.html.ini
@@ -0,0 +1,2 @@
+[id_color.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/inherit_values_from_media_element.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/inherit_values_from_media_element.html.ini
new file mode 100644
index 0000000..de9ddf4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/inherit_values_from_media_element.html.ini
@@ -0,0 +1,2 @@
+[inherit_values_from_media_element.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_animation_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_animation_with_timestamp.html.ini
new file mode 100644
index 0000000..e065b59
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_animation_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[italic_animation_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_properties.html.ini
new file mode 100644
index 0000000..1406dc0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_properties.html.ini
@@ -0,0 +1,2 @@
+[italic_background_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_shorthand.html.ini
new file mode 100644
index 0000000..391734a4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_shorthand.html.ini
@@ -0,0 +1,2 @@
+[italic_background_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_color.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_color.html.ini
new file mode 100644
index 0000000..04df99e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_color.html.ini
@@ -0,0 +1,2 @@
+[italic_color.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_properties.html.ini
new file mode 100644
index 0000000..3172efb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_properties.html.ini
@@ -0,0 +1,2 @@
+[italic_font_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_shorthand.html.ini
new file mode 100644
index 0000000..95c7453
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_shorthand.html.ini
@@ -0,0 +1,2 @@
+[italic_font_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_namespace.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_namespace.html.ini
new file mode 100644
index 0000000..7a7c66f2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_namespace.html.ini
@@ -0,0 +1,2 @@
+[italic_namespace.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_properties.html.ini
new file mode 100644
index 0000000..b318b05
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_properties.html.ini
@@ -0,0 +1,2 @@
+[italic_outline_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_shorthand.html.ini
new file mode 100644
index 0000000..c358866e8d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_shorthand.html.ini
@@ -0,0 +1,2 @@
+[italic_outline_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-decoration_line-through.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-decoration_line-through.html.ini
new file mode 100644
index 0000000..1cbd9f63
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-decoration_line-through.html.ini
@@ -0,0 +1,2 @@
+[italic_text-decoration_line-through.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-shadow.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-shadow.html.ini
new file mode 100644
index 0000000..d695bc6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-shadow.html.ini
@@ -0,0 +1,2 @@
+[italic_text-shadow.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_future.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_future.html.ini
new file mode 100644
index 0000000..55fb584
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_future.html.ini
@@ -0,0 +1,2 @@
+[italic_timestamp_future.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_past.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_past.html.ini
new file mode 100644
index 0000000..aecb8ad3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_past.html.ini
@@ -0,0 +1,2 @@
+[italic_timestamp_past.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_transition_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_transition_with_timestamp.html.ini
new file mode 100644
index 0000000..49975ce
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_transition_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[italic_transition_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_normal_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_normal_wrapped.html.ini
new file mode 100644
index 0000000..e0a00386
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_normal_wrapped.html.ini
@@ -0,0 +1,2 @@
+[italic_white-space_normal_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_nowrap.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_nowrap.html.ini
new file mode 100644
index 0000000..270f424
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_nowrap.html.ini
@@ -0,0 +1,2 @@
+[italic_white-space_nowrap.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-line_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-line_wrapped.html.ini
new file mode 100644
index 0000000..f10b61f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-line_wrapped.html.ini
@@ -0,0 +1,2 @@
+[italic_white-space_pre-line_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped.html.ini
new file mode 100644
index 0000000..3f462db
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped.html.ini
@@ -0,0 +1,2 @@
+[italic_white-space_pre-wrap_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre_wrapped.html.ini
new file mode 100644
index 0000000..40fb9d2d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre_wrapped.html.ini
@@ -0,0 +1,2 @@
+[italic_white-space_pre_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class.html.ini
new file mode 100644
index 0000000..2d0117ec
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class.html.ini
@@ -0,0 +1,2 @@
+[italic_with_class.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class_object_specific_selector.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class_object_specific_selector.html.ini
new file mode 100644
index 0000000..87187fc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class_object_specific_selector.html.ini
@@ -0,0 +1,2 @@
+[italic_with_class_object_specific_selector.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_allowed_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_allowed_properties.html.ini
new file mode 100644
index 0000000..81225a3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_allowed_properties.html.ini
@@ -0,0 +1,2 @@
+[not_allowed_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_root_selector.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_root_selector.html.ini
new file mode 100644
index 0000000..9559999af
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_root_selector.html.ini
@@ -0,0 +1,2 @@
+[not_root_selector.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_properties.html.ini
new file mode 100644
index 0000000..4d8e07a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_properties.html.ini
@@ -0,0 +1,2 @@
+[outline_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_shorthand.html.ini
new file mode 100644
index 0000000..13b2417
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_shorthand.html.ini
@@ -0,0 +1,2 @@
+[outline_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_namespace.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_namespace.html.ini
new file mode 100644
index 0000000..fea1ee47
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_namespace.html.ini
@@ -0,0 +1,2 @@
+[root_namespace.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_selector.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_selector.html.ini
new file mode 100644
index 0000000..813ad4ab
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_selector.html.ini
@@ -0,0 +1,2 @@
+[root_selector.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_line-through.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_line-through.html.ini
new file mode 100644
index 0000000..a63ffd3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_line-through.html.ini
@@ -0,0 +1,2 @@
+[text-decoration_line-through.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline.html.ini
new file mode 100644
index 0000000..74ff2291
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline.html.ini
@@ -0,0 +1,2 @@
+[text-decoration_overline.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline_underline_line-through.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline_underline_line-through.html.ini
new file mode 100644
index 0000000..9ec52d7f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline_underline_line-through.html.ini
@@ -0,0 +1,2 @@
+[text-decoration_overline_underline_line-through.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_underline.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_underline.html.ini
new file mode 100644
index 0000000..2b298de9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_underline.html.ini
@@ -0,0 +1,2 @@
+[text-decoration_underline.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-shadow.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-shadow.html.ini
new file mode 100644
index 0000000..567ce6d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-shadow.html.ini
@@ -0,0 +1,2 @@
+[text-shadow.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/type_selector_root.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/type_selector_root.html.ini
new file mode 100644
index 0000000..d35fd065
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/type_selector_root.html.ini
@@ -0,0 +1,2 @@
+[type_selector_root.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_animation_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_animation_with_timestamp.html.ini
new file mode 100644
index 0000000..646bf3a4c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_animation_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[underline_animation_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_properties.html.ini
new file mode 100644
index 0000000..333c9a7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_properties.html.ini
@@ -0,0 +1,2 @@
+[underline_background_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_shorthand.html.ini
new file mode 100644
index 0000000..fd55aaef
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_shorthand.html.ini
@@ -0,0 +1,2 @@
+[underline_background_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_color.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_color.html.ini
new file mode 100644
index 0000000..fc8102a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_color.html.ini
@@ -0,0 +1,2 @@
+[underline_color.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_properties.html.ini
new file mode 100644
index 0000000..4f85fc4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_properties.html.ini
@@ -0,0 +1,2 @@
+[underline_font_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_shorthand.html.ini
new file mode 100644
index 0000000..fc989720
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_shorthand.html.ini
@@ -0,0 +1,2 @@
+[underline_font_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_namespace.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_namespace.html.ini
new file mode 100644
index 0000000..1a380d4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_namespace.html.ini
@@ -0,0 +1,2 @@
+[underline_namespace.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_properties.html.ini
new file mode 100644
index 0000000..1caccd0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_properties.html.ini
@@ -0,0 +1,2 @@
+[underline_outline_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_shorthand.html.ini
new file mode 100644
index 0000000..7241f1b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_shorthand.html.ini
@@ -0,0 +1,2 @@
+[underline_outline_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-decoration_line-through.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-decoration_line-through.html.ini
new file mode 100644
index 0000000..327386c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-decoration_line-through.html.ini
@@ -0,0 +1,2 @@
+[underline_text-decoration_line-through.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-shadow.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-shadow.html.ini
new file mode 100644
index 0000000..2e73b0e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-shadow.html.ini
@@ -0,0 +1,2 @@
+[underline_text-shadow.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_future.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_future.html.ini
new file mode 100644
index 0000000..86f8f4542
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_future.html.ini
@@ -0,0 +1,2 @@
+[underline_timestamp_future.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_past.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_past.html.ini
new file mode 100644
index 0000000..971d4c1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_past.html.ini
@@ -0,0 +1,2 @@
+[underline_timestamp_past.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_transition_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_transition_with_timestamp.html.ini
new file mode 100644
index 0000000..7b24f53
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_transition_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[underline_transition_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_normal_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_normal_wrapped.html.ini
new file mode 100644
index 0000000..fe12eda
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_normal_wrapped.html.ini
@@ -0,0 +1,2 @@
+[underline_white-space_normal_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_nowrap.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_nowrap.html.ini
new file mode 100644
index 0000000..4ea86be
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_nowrap.html.ini
@@ -0,0 +1,2 @@
+[underline_white-space_nowrap.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-line_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-line_wrapped.html.ini
new file mode 100644
index 0000000..eeba43d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-line_wrapped.html.ini
@@ -0,0 +1,2 @@
+[underline_white-space_pre-line_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped.html.ini
new file mode 100644
index 0000000..d54ceb4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped.html.ini
@@ -0,0 +1,2 @@
+[underline_white-space_pre-wrap_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre_wrapped.html.ini
new file mode 100644
index 0000000..9d486302
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre_wrapped.html.ini
@@ -0,0 +1,2 @@
+[underline_white-space_pre_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class.html.ini
new file mode 100644
index 0000000..550e80de
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class.html.ini
@@ -0,0 +1,2 @@
+[underline_with_class.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class_object_specific_selector.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class_object_specific_selector.html.ini
new file mode 100644
index 0000000..9a6b9c8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class_object_specific_selector.html.ini
@@ -0,0 +1,2 @@
+[underline_with_class_object_specific_selector.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_animation_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_animation_with_timestamp.html.ini
new file mode 100644
index 0000000..766ff94
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_animation_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[voice_animation_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_properties.html.ini
new file mode 100644
index 0000000..bfa8c08
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_properties.html.ini
@@ -0,0 +1,2 @@
+[voice_background_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_shorthand.html.ini
new file mode 100644
index 0000000..1106076e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_shorthand.html.ini
@@ -0,0 +1,2 @@
+[voice_background_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_color.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_color.html.ini
new file mode 100644
index 0000000..2f4786d3e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_color.html.ini
@@ -0,0 +1,2 @@
+[voice_color.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_properties.html.ini
new file mode 100644
index 0000000..b87293e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_properties.html.ini
@@ -0,0 +1,2 @@
+[voice_font_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_shorthand.html.ini
new file mode 100644
index 0000000..0afa745
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_shorthand.html.ini
@@ -0,0 +1,2 @@
+[voice_font_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_namespace.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_namespace.html.ini
new file mode 100644
index 0000000..512c252a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_namespace.html.ini
@@ -0,0 +1,2 @@
+[voice_namespace.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_properties.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_properties.html.ini
new file mode 100644
index 0000000..1691c33
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_properties.html.ini
@@ -0,0 +1,2 @@
+[voice_outline_properties.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_shorthand.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_shorthand.html.ini
new file mode 100644
index 0000000..a5c2d9e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_shorthand.html.ini
@@ -0,0 +1,2 @@
+[voice_outline_shorthand.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-decoration_line-through.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-decoration_line-through.html.ini
new file mode 100644
index 0000000..e35db12
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-decoration_line-through.html.ini
@@ -0,0 +1,2 @@
+[voice_text-decoration_line-through.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-shadow.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-shadow.html.ini
new file mode 100644
index 0000000..7970c83
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-shadow.html.ini
@@ -0,0 +1,2 @@
+[voice_text-shadow.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_future.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_future.html.ini
new file mode 100644
index 0000000..f622c63
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_future.html.ini
@@ -0,0 +1,2 @@
+[voice_timestamp_future.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_past.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_past.html.ini
new file mode 100644
index 0000000..8ab9600
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_past.html.ini
@@ -0,0 +1,2 @@
+[voice_timestamp_past.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_transition_with_timestamp.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_transition_with_timestamp.html.ini
new file mode 100644
index 0000000..f0dd701
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_transition_with_timestamp.html.ini
@@ -0,0 +1,2 @@
+[voice_transition_with_timestamp.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_voice_attribute.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_voice_attribute.html.ini
new file mode 100644
index 0000000..5bb4aba
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_voice_attribute.html.ini
@@ -0,0 +1,2 @@
+[voice_voice_attribute.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_normal_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_normal_wrapped.html.ini
new file mode 100644
index 0000000..b187a82
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_normal_wrapped.html.ini
@@ -0,0 +1,2 @@
+[voice_white-space_normal_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_nowrap.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_nowrap.html.ini
new file mode 100644
index 0000000..90e2981
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_nowrap.html.ini
@@ -0,0 +1,2 @@
+[voice_white-space_nowrap.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-line_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-line_wrapped.html.ini
new file mode 100644
index 0000000..52e6a8c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-line_wrapped.html.ini
@@ -0,0 +1,2 @@
+[voice_white-space_pre-line_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-wrap_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-wrap_wrapped.html.ini
new file mode 100644
index 0000000..a14602e3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-wrap_wrapped.html.ini
@@ -0,0 +1,2 @@
+[voice_white-space_pre-wrap_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre_wrapped.html.ini
new file mode 100644
index 0000000..77845c9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre_wrapped.html.ini
@@ -0,0 +1,2 @@
+[voice_white-space_pre_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class.html.ini
new file mode 100644
index 0000000..e38985c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class.html.ini
@@ -0,0 +1,2 @@
+[voice_with_class.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class_object_specific_selector.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class_object_specific_selector.html.ini
new file mode 100644
index 0000000..a1b6679
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class_object_specific_selector.html.ini
@@ -0,0 +1,2 @@
+[voice_with_class_object_specific_selector.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_normal_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_normal_wrapped.html.ini
new file mode 100644
index 0000000..8992a83
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_normal_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_normal_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_nowrap_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_nowrap_wrapped.html.ini
new file mode 100644
index 0000000..ae503769
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_nowrap_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_nowrap_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-line_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-line_wrapped.html.ini
new file mode 100644
index 0000000..d7d36df
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-line_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_pre-line_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-wrap_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-wrap_wrapped.html.ini
new file mode 100644
index 0000000..e4ddc89
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-wrap_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_pre-wrap_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre.html.ini
new file mode 100644
index 0000000..d8fd7318
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre.html.ini
@@ -0,0 +1,2 @@
+[white-space_pre.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre_wrapped.html.ini
new file mode 100644
index 0000000..b88a5e26
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre_wrapped.html.ini
@@ -0,0 +1,2 @@
+[white-space_pre_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/bold_object_default_font-style.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/bold_object_default_font-style.html.ini
new file mode 100644
index 0000000..5134a538
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/bold_object_default_font-style.html.ini
@@ -0,0 +1,2 @@
+[bold_object_default_font-style.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/inherit_as_default_value_inherits_values_from_media_element.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/inherit_as_default_value_inherits_values_from_media_element.html.ini
new file mode 100644
index 0000000..e78156c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/inherit_as_default_value_inherits_values_from_media_element.html.ini
@@ -0,0 +1,2 @@
+[inherit_as_default_value_inherits_values_from_media_element.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html.ini
new file mode 100644
index 0000000..a4399895
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html.ini
@@ -0,0 +1,2 @@
+[italic_object_default_font-style.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html.ini
new file mode 100644
index 0000000..7924537
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html.ini
@@ -0,0 +1,2 @@
+[underline_object_default_font-style.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/size_50.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/size_50.html.ini
new file mode 100644
index 0000000..5780c25
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/size_50.html.ini
@@ -0,0 +1,2 @@
+[size_50.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/snap-to-line.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/snap-to-line.html.ini
new file mode 100644
index 0000000..391d7a6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/snap-to-line.html.ini
@@ -0,0 +1,2 @@
+[snap-to-line.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/too_many_cues.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/too_many_cues.html.ini
new file mode 100644
index 0000000..9bb2b2c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/too_many_cues.html.ini
@@ -0,0 +1,2 @@
+[too_many_cues.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/too_many_cues_wrapped.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/too_many_cues_wrapped.html.ini
new file mode 100644
index 0000000..bb05baae
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/too_many_cues_wrapped.html.ini
@@ -0,0 +1,2 @@
+[too_many_cues_wrapped.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt
index 1045aac..fa491095 100644
--- a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt
+++ b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt
@@ -200,6 +200,7 @@
 hyphens: manual
 image-orientation: from-image
 image-rendering: auto
+initial-letter: normal
 inline-size: 769px
 inset-block-end: auto
 inset-block-start: auto
diff --git a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
index be19a1e8..ee430d5 100644
--- a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
+++ b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
@@ -200,6 +200,7 @@
 hyphens: manual
 image-orientation: from-image
 image-rendering: auto
+initial-letter: normal
 inline-size: auto
 inset-block-end: auto
 inset-block-start: auto
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-initial-letter/initial-letter-computed-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-initial-letter/initial-letter-computed-expected.txt
new file mode 100644
index 0000000..7c702a9
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-initial-letter/initial-letter-computed-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL Property initial-letter value 'normal' assert_true: initial-letter doesn't seem to be supported in the computed style expected true got false
+FAIL Property initial-letter value '1.23' assert_true: initial-letter doesn't seem to be supported in the computed style expected true got false
+FAIL Property initial-letter value '1.23 456' assert_true: initial-letter doesn't seem to be supported in the computed style expected true got false
+FAIL Property initial-letter value '1.23 calc(45.6)' assert_true: initial-letter doesn't seem to be supported in the computed style expected true got false
+FAIL Property initial-letter value '1.23 drop' assert_true: initial-letter doesn't seem to be supported in the computed style expected true got false
+FAIL Property initial-letter value '1.23 raise' assert_true: initial-letter doesn't seem to be supported in the computed style expected true got false
+FAIL Property initial-letter value 'drop 1.23' assert_true: initial-letter doesn't seem to be supported in the computed style expected true got false
+FAIL Property initial-letter value 'raise 1.23' assert_true: initial-letter doesn't seem to be supported in the computed style expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-initial-letter/initial-letter-valid-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-initial-letter/initial-letter-valid-expected.txt
new file mode 100644
index 0000000..490e5be
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-initial-letter/initial-letter-valid-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL e.style['initial-letter'] = "normal" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['initial-letter'] = "1.23" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['initial-letter'] = "1.23 456" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['initial-letter'] = "1.23 calc(45.6)" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['initial-letter'] = "1.23 drop" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['initial-letter'] = "1.23 raise" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['initial-letter'] = "drop 1.23" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['initial-letter'] = "raise 1.23" should set the property value assert_not_equals: property should be set got disallowed value ""
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/cssom/getComputedStyle-detached-subtree-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/cssom/getComputedStyle-detached-subtree-expected.txt
new file mode 100644
index 0000000..49adafd
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/cssom/getComputedStyle-detached-subtree-expected.txt
@@ -0,0 +1,9 @@
+This is a testharness.js-based test.
+PASS getComputedStyle returns no style for detached element
+FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) assert_equals: expected 0 but got 365
+FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) from iframe's window assert_equals: expected 0 but got 365
+FAIL getComputedStyle returns no style for element outside the flat tree assert_equals: expected 0 but got 365
+FAIL getComputedStyle returns no style for descendant outside the flat tree assert_equals: expected 0 but got 365
+PASS getComputedStyle returns no style for shadow tree outside of flattened tree
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/cssom/getComputedStyle-pseudo-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/cssom/getComputedStyle-pseudo-expected.txt
new file mode 100644
index 0000000..5ab221b
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/cssom/getComputedStyle-pseudo-expected.txt
@@ -0,0 +1,12 @@
+This is a testharness.js-based test.
+PASS Resolution of width is correct for ::before and ::after pseudo-elements
+PASS Resolution of width is correct for ::before and ::after pseudo-elements of display: contents elements
+PASS Resolution of nonexistent pseudo-element styles
+PASS Resolution of pseudo-element styles in display: none elements
+PASS Item-based blockification of pseudo-elements
+PASS Item-based blockification of nonexistent pseudo-elements
+PASS display: contents on pseudo-elements
+PASS Dynamically change to display: contents on pseudo-elements
+FAIL Unknown pseudo-elements assert_equals: Should return an empty style for unknown pseudo-elements starting with double-colon expected 0 but got 365
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-001-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-001-expected.txt
new file mode 100644
index 0000000..ca973cf
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-001-expected.txt
@@ -0,0 +1,308 @@
+This is a testharness.js-based test.
+Found 304 tests; 302 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Setup
+PASS align-content (type: discrete) has testAccumulation function
+PASS align-content: "flex-end" onto "flex-start"
+PASS align-content: "flex-start" onto "flex-end"
+PASS align-items (type: discrete) has testAccumulation function
+PASS align-items: "flex-end" onto "flex-start"
+PASS align-items: "flex-start" onto "flex-end"
+PASS align-self (type: discrete) has testAccumulation function
+PASS align-self: "flex-end" onto "flex-start"
+PASS align-self: "flex-start" onto "flex-end"
+PASS backface-visibility (type: discrete) has testAccumulation function
+PASS backface-visibility: "hidden" onto "visible"
+PASS backface-visibility: "visible" onto "hidden"
+PASS background-attachment (type: discrete) has testAccumulation function
+PASS background-attachment: "local" onto "fixed"
+PASS background-attachment: "fixed" onto "local"
+PASS background-color (type: color) has testAccumulation function
+PASS background-color supports animating as color of rgb() with overflowed  from and to values
+PASS background-color supports animating as color of #RGB
+PASS background-color supports animating as color of hsl()
+PASS background-color supports animating as color of #RGBa
+PASS background-color supports animating as color of rgba()
+PASS background-color supports animating as color of hsla()
+PASS background-blend-mode (type: discrete) has testAccumulation function
+PASS background-blend-mode: "screen" onto "multiply"
+PASS background-blend-mode: "multiply" onto "screen"
+PASS background-clip (type: discrete) has testAccumulation function
+PASS background-clip: "content-box" onto "padding-box"
+PASS background-clip: "padding-box" onto "content-box"
+PASS background-image (type: discrete) has testAccumulation function
+PASS background-image: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
+PASS background-image: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
+PASS background-origin (type: discrete) has testAccumulation function
+PASS background-origin: "content-box" onto "padding-box"
+PASS background-origin: "padding-box" onto "content-box"
+PASS background-repeat (type: discrete) has testAccumulation function
+PASS background-repeat: "round" onto "space"
+PASS background-repeat: "space" onto "round"
+PASS border-bottom-color (type: color) has testAccumulation function
+PASS border-bottom-color supports animating as color of rgb() with overflowed  from and to values
+PASS border-bottom-color supports animating as color of #RGB
+PASS border-bottom-color supports animating as color of hsl()
+PASS border-bottom-color supports animating as color of #RGBa
+PASS border-bottom-color supports animating as color of rgba()
+PASS border-bottom-color supports animating as color of hsla()
+PASS border-bottom-style (type: discrete) has testAccumulation function
+PASS border-bottom-style: "solid" onto "dotted"
+PASS border-bottom-style: "dotted" onto "solid"
+PASS border-bottom-width (type: length) has testAccumulation function
+PASS border-bottom-width: length
+PASS border-bottom-width: length of rem
+PASS border-collapse (type: discrete) has testAccumulation function
+PASS border-collapse: "separate" onto "collapse"
+PASS border-collapse: "collapse" onto "separate"
+PASS border-image-repeat (type: discrete) has testAccumulation function
+PASS border-image-repeat: "round space" onto "stretch repeat"
+PASS border-image-repeat: "stretch repeat" onto "round space"
+PASS border-image-source (type: discrete) has testAccumulation function
+PASS border-image-source: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
+PASS border-image-source: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
+PASS border-left-color (type: color) has testAccumulation function
+PASS border-left-color supports animating as color of rgb() with overflowed  from and to values
+PASS border-left-color supports animating as color of #RGB
+PASS border-left-color supports animating as color of hsl()
+PASS border-left-color supports animating as color of #RGBa
+PASS border-left-color supports animating as color of rgba()
+PASS border-left-color supports animating as color of hsla()
+PASS border-left-style (type: discrete) has testAccumulation function
+PASS border-left-style: "solid" onto "dotted"
+PASS border-left-style: "dotted" onto "solid"
+PASS border-left-width (type: length) has testAccumulation function
+PASS border-left-width: length
+PASS border-left-width: length of rem
+PASS border-right-color (type: color) has testAccumulation function
+PASS border-right-color supports animating as color of rgb() with overflowed  from and to values
+PASS border-right-color supports animating as color of #RGB
+PASS border-right-color supports animating as color of hsl()
+PASS border-right-color supports animating as color of #RGBa
+PASS border-right-color supports animating as color of rgba()
+PASS border-right-color supports animating as color of hsla()
+PASS border-right-style (type: discrete) has testAccumulation function
+PASS border-right-style: "solid" onto "dotted"
+PASS border-right-style: "dotted" onto "solid"
+PASS border-right-width (type: length) has testAccumulation function
+PASS border-right-width: length
+PASS border-right-width: length of rem
+PASS border-spacing (type: lengthPair) has testAccumulation function
+PASS border-spacing: length pair
+PASS border-spacing: length pair of rem
+PASS border-top-color (type: color) has testAccumulation function
+PASS border-top-color supports animating as color of rgb() with overflowed  from and to values
+PASS border-top-color supports animating as color of #RGB
+PASS border-top-color supports animating as color of hsl()
+PASS border-top-color supports animating as color of #RGBa
+PASS border-top-color supports animating as color of rgba()
+PASS border-top-color supports animating as color of hsla()
+PASS border-top-style (type: discrete) has testAccumulation function
+PASS border-top-style: "solid" onto "dotted"
+PASS border-top-style: "dotted" onto "solid"
+PASS border-top-width (type: length) has testAccumulation function
+PASS border-top-width: length
+PASS border-top-width: length of rem
+PASS box-shadow (type: boxShadowList) has testAccumulation function
+PASS box-shadow: shadow
+PASS box-sizing (type: discrete) has testAccumulation function
+PASS box-sizing: "border-box" onto "content-box"
+PASS box-sizing: "content-box" onto "border-box"
+PASS caption-side (type: discrete) has testAccumulation function
+PASS caption-side: "bottom" onto "top"
+PASS caption-side: "top" onto "bottom"
+PASS caret-color (type: color) has testAccumulation function
+PASS caret-color supports animating as color of rgb() with overflowed  from and to values
+PASS caret-color supports animating as color of #RGB
+PASS caret-color supports animating as color of hsl()
+PASS caret-color supports animating as color of #RGBa
+PASS caret-color supports animating as color of rgba()
+PASS caret-color supports animating as color of hsla()
+PASS clear (type: discrete) has testAccumulation function
+PASS clear: "right" onto "left"
+PASS clear: "left" onto "right"
+PASS clip (type: rect) has testAccumulation function
+PASS clip: rect
+PASS clip (type: discrete) has testAccumulation function
+PASS clip: "auto" onto "rect(10px, 10px, 10px, 10px)"
+PASS clip: "rect(10px, 10px, 10px, 10px)" onto "auto"
+PASS clip: "rect(10px, 10px, 10px, auto)" onto "rect(10px, 10px, 10px, 10px)"
+PASS clip: "rect(10px, 10px, 10px, 10px)" onto "rect(10px, 10px, 10px, auto)"
+PASS clip-rule (type: discrete) has testAccumulation function
+PASS clip-rule: "nonzero" onto "evenodd"
+PASS clip-rule: "evenodd" onto "nonzero"
+PASS color (type: color) has testAccumulation function
+PASS color supports animating as color of rgb() with overflowed  from and to values
+PASS color supports animating as color of #RGB
+PASS color supports animating as color of hsl()
+PASS color supports animating as color of #RGBa
+PASS color supports animating as color of rgba()
+PASS color supports animating as color of hsla()
+PASS color-interpolation (type: discrete) has testAccumulation function
+PASS color-interpolation: "auto" onto "linearrgb"
+PASS color-interpolation: "linearrgb" onto "auto"
+PASS color-interpolation-filters (type: discrete) has testAccumulation function
+PASS color-interpolation-filters: "linearrgb" onto "srgb"
+PASS color-interpolation-filters: "srgb" onto "linearrgb"
+PASS column-count (type: positiveInteger) has testAccumulation function
+PASS column-count: positive integer
+PASS column-count (type: discrete) has testAccumulation function
+PASS column-count: "10" onto "auto"
+PASS column-count: "auto" onto "10"
+PASS column-gap (type: length) has testAccumulation function
+PASS column-gap: length
+PASS column-gap: length of rem
+PASS column-gap (type: discrete) has testAccumulation function
+PASS column-gap: "200px" onto "normal"
+PASS column-gap: "normal" onto "200px"
+PASS column-rule-color (type: color) has testAccumulation function
+PASS column-rule-color supports animating as color of rgb() with overflowed  from and to values
+PASS column-rule-color supports animating as color of #RGB
+PASS column-rule-color supports animating as color of hsl()
+PASS column-rule-color supports animating as color of #RGBa
+PASS column-rule-color supports animating as color of rgba()
+PASS column-rule-color supports animating as color of hsla()
+PASS column-fill (type: discrete) has testAccumulation function
+PASS column-fill: "balance" onto "auto"
+PASS column-fill: "auto" onto "balance"
+PASS column-rule-style (type: discrete) has testAccumulation function
+PASS column-rule-style: "dotted" onto "none"
+PASS column-rule-style: "none" onto "dotted"
+PASS column-rule-width (type: length) has testAccumulation function
+PASS column-rule-width: length
+PASS column-rule-width: length of rem
+PASS column-width (type: length) has testAccumulation function
+PASS column-width: length
+PASS column-width: length of rem
+PASS column-width (type: discrete) has testAccumulation function
+PASS column-width: "1px" onto "auto"
+PASS column-width: "auto" onto "1px"
+PASS counter-increment (type: discrete) has testAccumulation function
+PASS counter-increment: "ident-2 2" onto "ident-1 1"
+PASS counter-increment: "ident-1 1" onto "ident-2 2"
+PASS counter-reset (type: discrete) has testAccumulation function
+PASS counter-reset: "ident-2 2" onto "ident-1 1"
+PASS counter-reset: "ident-1 1" onto "ident-2 2"
+PASS cursor (type: discrete) has testAccumulation function
+PASS cursor: "wait" onto "pointer"
+PASS cursor: "pointer" onto "wait"
+PASS dominant-baseline (type: discrete) has testAccumulation function
+PASS dominant-baseline: "alphabetic" onto "ideographic"
+PASS dominant-baseline: "ideographic" onto "alphabetic"
+PASS empty-cells (type: discrete) has testAccumulation function
+PASS empty-cells: "hide" onto "show"
+PASS empty-cells: "show" onto "hide"
+PASS fill-opacity (type: opacity) has testAccumulation function
+PASS fill-opacity: [0, 1] number
+PASS fill-opacity: [0, 1] number (clamped)
+PASS fill-rule (type: discrete) has testAccumulation function
+PASS fill-rule: "nonzero" onto "evenodd"
+PASS fill-rule: "evenodd" onto "nonzero"
+PASS filter (type: filterList) has testAccumulation function
+PASS filter: same ordered filter functions
+PASS filter: mismatched ordered filter functions
+PASS flex-basis (type: lengthPercentageOrCalc) has testAccumulation function
+PASS flex-basis: length
+PASS flex-basis: length of rem
+PASS flex-basis: percentage
+PASS flex-basis: units "%" onto "px"
+PASS flex-basis: units "px" onto "%"
+PASS flex-basis: units "rem" onto "%"
+PASS flex-basis: units "%" onto "rem"
+PASS flex-basis: units "rem" onto "em"
+PASS flex-basis: units "em" onto "rem"
+PASS flex-basis: units "calc" onto "px"
+PASS flex-basis: calc
+PASS flex-basis (type: discrete) has testAccumulation function
+PASS flex-basis: "10px" onto "auto"
+PASS flex-basis: "auto" onto "10px"
+PASS flex-direction (type: discrete) has testAccumulation function
+PASS flex-direction: "row-reverse" onto "row"
+PASS flex-direction: "row" onto "row-reverse"
+PASS flex-grow (type: positiveNumber) has testAccumulation function
+PASS flex-grow: positive number
+PASS flex-shrink (type: positiveNumber) has testAccumulation function
+PASS flex-shrink: positive number
+PASS flex-wrap (type: discrete) has testAccumulation function
+PASS flex-wrap: "wrap" onto "nowrap"
+PASS flex-wrap: "nowrap" onto "wrap"
+PASS flood-color (type: color) has testAccumulation function
+PASS flood-color supports animating as color of rgb() with overflowed  from and to values
+PASS flood-color supports animating as color of #RGB
+PASS flood-color supports animating as color of hsl()
+PASS flood-color supports animating as color of #RGBa
+PASS flood-color supports animating as color of rgba()
+PASS flood-color supports animating as color of hsla()
+PASS flood-opacity (type: opacity) has testAccumulation function
+PASS flood-opacity: [0, 1] number
+PASS flood-opacity: [0, 1] number (clamped)
+PASS font-stretch (type: percentage) has testAccumulation function
+PASS font-stretch: percentage
+PASS font-style (type: discrete) has testAccumulation function
+FAIL font-style: "oblique" onto "italic" assert_equals: The value should be oblique at 0ms expected "oblique" but got "italic"
+PASS font-style: "italic" onto "oblique"
+PASS float (type: discrete) has testAccumulation function
+PASS float: "right" onto "left"
+PASS float: "left" onto "right"
+PASS font-family (type: discrete) has testAccumulation function
+PASS font-family: "verdana" onto "helvetica"
+PASS font-family: "helvetica" onto "verdana"
+PASS font-feature-settings (type: discrete) has testAccumulation function
+PASS font-feature-settings: "normal" onto ""liga" 5"
+PASS font-feature-settings: ""liga" 5" onto "normal"
+PASS font-kerning (type: discrete) has testAccumulation function
+PASS font-kerning: "normal" onto "auto"
+PASS font-kerning: "auto" onto "normal"
+PASS font-synthesis (type: discrete) has testAccumulation function
+PASS font-synthesis: "weight style" onto "none"
+PASS font-synthesis: "none" onto "weight style"
+PASS font-variant-caps (type: discrete) has testAccumulation function
+PASS font-variant-caps: "unicase" onto "small-caps"
+PASS font-variant-caps: "small-caps" onto "unicase"
+PASS font-variant-east-asian (type: discrete) has testAccumulation function
+PASS font-variant-east-asian: "proportional-width" onto "full-width"
+PASS font-variant-east-asian: "full-width" onto "proportional-width"
+PASS font-variant-ligatures (type: discrete) has testAccumulation function
+PASS font-variant-ligatures: "no-common-ligatures" onto "common-ligatures"
+PASS font-variant-ligatures: "common-ligatures" onto "no-common-ligatures"
+PASS font-variant-numeric (type: discrete) has testAccumulation function
+PASS font-variant-numeric: "oldstyle-nums" onto "lining-nums"
+PASS font-variant-numeric: "lining-nums" onto "oldstyle-nums"
+PASS font-variation-settings (type: fontVariationSettings) has testAccumulation function
+PASS font-variation-settings with composite type accumulate
+PASS font-variation-settings (type: discrete) has testAccumulation function
+PASS font-variation-settings: ""wdth" 5" onto ""wdth" 1, "wght" 1.1"
+PASS font-variation-settings: ""wdth" 1, "wght" 1.1" onto ""wdth" 5"
+PASS font-variation-settings: "normal" onto ""wdth" 5"
+PASS font-variation-settings: ""wdth" 5" onto "normal"
+PASS grid-auto-columns (type: discrete) has testAccumulation function
+PASS grid-auto-columns: "5px" onto "1px"
+PASS grid-auto-columns: "1px" onto "5px"
+PASS grid-auto-flow (type: discrete) has testAccumulation function
+PASS grid-auto-flow: "column" onto "row"
+PASS grid-auto-flow: "row" onto "column"
+PASS grid-auto-rows (type: discrete) has testAccumulation function
+PASS grid-auto-rows: "5px" onto "1px"
+PASS grid-auto-rows: "1px" onto "5px"
+PASS grid-column-end (type: discrete) has testAccumulation function
+PASS grid-column-end: "5" onto "1"
+PASS grid-column-end: "1" onto "5"
+PASS grid-column-start (type: discrete) has testAccumulation function
+PASS grid-column-start: "5" onto "1"
+PASS grid-column-start: "1" onto "5"
+PASS grid-row-end (type: discrete) has testAccumulation function
+PASS grid-row-end: "5" onto "1"
+PASS grid-row-end: "1" onto "5"
+PASS grid-row-start (type: discrete) has testAccumulation function
+PASS grid-row-start: "5" onto "1"
+PASS grid-row-start: "1" onto "5"
+PASS grid-template-areas (type: discrete) has testAccumulation function
+PASS grid-template-areas: "none" onto "". . a b" ". .a b""
+FAIL grid-template-areas: "". . a b" ". .a b"" onto "none" assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
+PASS hyphens (type: discrete) has testAccumulation function
+PASS hyphens: "none" onto "manual"
+PASS hyphens: "manual" onto "none"
+PASS image-orientation (type: discrete) has testAccumulation function
+PASS image-orientation: "from-image" onto "none"
+PASS image-orientation: "none" onto "from-image"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/web-animations/animation-model/animation-types/addition-per-property-001-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/web-animations/animation-model/animation-types/addition-per-property-001-expected.txt
new file mode 100644
index 0000000..a711accf
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/web-animations/animation-model/animation-types/addition-per-property-001-expected.txt
@@ -0,0 +1,308 @@
+This is a testharness.js-based test.
+Found 304 tests; 302 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Setup
+PASS align-content (type: discrete) has testAddition function
+PASS align-content: "flex-end" onto "flex-start"
+PASS align-content: "flex-start" onto "flex-end"
+PASS align-items (type: discrete) has testAddition function
+PASS align-items: "flex-end" onto "flex-start"
+PASS align-items: "flex-start" onto "flex-end"
+PASS align-self (type: discrete) has testAddition function
+PASS align-self: "flex-end" onto "flex-start"
+PASS align-self: "flex-start" onto "flex-end"
+PASS backface-visibility (type: discrete) has testAddition function
+PASS backface-visibility: "hidden" onto "visible"
+PASS backface-visibility: "visible" onto "hidden"
+PASS background-attachment (type: discrete) has testAddition function
+PASS background-attachment: "local" onto "fixed"
+PASS background-attachment: "fixed" onto "local"
+PASS background-color (type: color) has testAddition function
+PASS background-color supports animating as color of rgb() with overflowed  from and to values
+PASS background-color supports animating as color of #RGB
+PASS background-color supports animating as color of hsl()
+PASS background-color supports animating as color of #RGBa
+PASS background-color supports animating as color of rgba()
+PASS background-color supports animating as color of hsla()
+PASS background-blend-mode (type: discrete) has testAddition function
+PASS background-blend-mode: "screen" onto "multiply"
+PASS background-blend-mode: "multiply" onto "screen"
+PASS background-clip (type: discrete) has testAddition function
+PASS background-clip: "content-box" onto "padding-box"
+PASS background-clip: "padding-box" onto "content-box"
+PASS background-image (type: discrete) has testAddition function
+PASS background-image: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
+PASS background-image: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
+PASS background-origin (type: discrete) has testAddition function
+PASS background-origin: "content-box" onto "padding-box"
+PASS background-origin: "padding-box" onto "content-box"
+PASS background-repeat (type: discrete) has testAddition function
+PASS background-repeat: "round" onto "space"
+PASS background-repeat: "space" onto "round"
+PASS border-bottom-color (type: color) has testAddition function
+PASS border-bottom-color supports animating as color of rgb() with overflowed  from and to values
+PASS border-bottom-color supports animating as color of #RGB
+PASS border-bottom-color supports animating as color of hsl()
+PASS border-bottom-color supports animating as color of #RGBa
+PASS border-bottom-color supports animating as color of rgba()
+PASS border-bottom-color supports animating as color of hsla()
+PASS border-bottom-style (type: discrete) has testAddition function
+PASS border-bottom-style: "solid" onto "dotted"
+PASS border-bottom-style: "dotted" onto "solid"
+PASS border-bottom-width (type: length) has testAddition function
+PASS border-bottom-width: length
+PASS border-bottom-width: length of rem
+PASS border-collapse (type: discrete) has testAddition function
+PASS border-collapse: "separate" onto "collapse"
+PASS border-collapse: "collapse" onto "separate"
+PASS border-image-repeat (type: discrete) has testAddition function
+PASS border-image-repeat: "round space" onto "stretch repeat"
+PASS border-image-repeat: "stretch repeat" onto "round space"
+PASS border-image-source (type: discrete) has testAddition function
+PASS border-image-source: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
+PASS border-image-source: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
+PASS border-left-color (type: color) has testAddition function
+PASS border-left-color supports animating as color of rgb() with overflowed  from and to values
+PASS border-left-color supports animating as color of #RGB
+PASS border-left-color supports animating as color of hsl()
+PASS border-left-color supports animating as color of #RGBa
+PASS border-left-color supports animating as color of rgba()
+PASS border-left-color supports animating as color of hsla()
+PASS border-left-style (type: discrete) has testAddition function
+PASS border-left-style: "solid" onto "dotted"
+PASS border-left-style: "dotted" onto "solid"
+PASS border-left-width (type: length) has testAddition function
+PASS border-left-width: length
+PASS border-left-width: length of rem
+PASS border-right-color (type: color) has testAddition function
+PASS border-right-color supports animating as color of rgb() with overflowed  from and to values
+PASS border-right-color supports animating as color of #RGB
+PASS border-right-color supports animating as color of hsl()
+PASS border-right-color supports animating as color of #RGBa
+PASS border-right-color supports animating as color of rgba()
+PASS border-right-color supports animating as color of hsla()
+PASS border-right-style (type: discrete) has testAddition function
+PASS border-right-style: "solid" onto "dotted"
+PASS border-right-style: "dotted" onto "solid"
+PASS border-right-width (type: length) has testAddition function
+PASS border-right-width: length
+PASS border-right-width: length of rem
+PASS border-spacing (type: lengthPair) has testAddition function
+PASS border-spacing: length pair
+PASS border-spacing: length pair of rem
+PASS border-top-color (type: color) has testAddition function
+PASS border-top-color supports animating as color of rgb() with overflowed  from and to values
+PASS border-top-color supports animating as color of #RGB
+PASS border-top-color supports animating as color of hsl()
+PASS border-top-color supports animating as color of #RGBa
+PASS border-top-color supports animating as color of rgba()
+PASS border-top-color supports animating as color of hsla()
+PASS border-top-style (type: discrete) has testAddition function
+PASS border-top-style: "solid" onto "dotted"
+PASS border-top-style: "dotted" onto "solid"
+PASS border-top-width (type: length) has testAddition function
+PASS border-top-width: length
+PASS border-top-width: length of rem
+PASS box-shadow (type: boxShadowList) has testAddition function
+PASS box-shadow: shadow
+PASS box-sizing (type: discrete) has testAddition function
+PASS box-sizing: "border-box" onto "content-box"
+PASS box-sizing: "content-box" onto "border-box"
+PASS caption-side (type: discrete) has testAddition function
+PASS caption-side: "bottom" onto "top"
+PASS caption-side: "top" onto "bottom"
+PASS caret-color (type: color) has testAddition function
+PASS caret-color supports animating as color of rgb() with overflowed  from and to values
+PASS caret-color supports animating as color of #RGB
+PASS caret-color supports animating as color of hsl()
+PASS caret-color supports animating as color of #RGBa
+PASS caret-color supports animating as color of rgba()
+PASS caret-color supports animating as color of hsla()
+PASS clear (type: discrete) has testAddition function
+PASS clear: "right" onto "left"
+PASS clear: "left" onto "right"
+PASS clip (type: rect) has testAddition function
+PASS clip: rect
+PASS clip (type: discrete) has testAddition function
+PASS clip: "auto" onto "rect(10px, 10px, 10px, 10px)"
+PASS clip: "rect(10px, 10px, 10px, 10px)" onto "auto"
+PASS clip: "rect(10px, 10px, 10px, auto)" onto "rect(10px, 10px, 10px, 10px)"
+PASS clip: "rect(10px, 10px, 10px, 10px)" onto "rect(10px, 10px, 10px, auto)"
+PASS clip-rule (type: discrete) has testAddition function
+PASS clip-rule: "nonzero" onto "evenodd"
+PASS clip-rule: "evenodd" onto "nonzero"
+PASS color (type: color) has testAddition function
+PASS color supports animating as color of rgb() with overflowed  from and to values
+PASS color supports animating as color of #RGB
+PASS color supports animating as color of hsl()
+PASS color supports animating as color of #RGBa
+PASS color supports animating as color of rgba()
+PASS color supports animating as color of hsla()
+PASS color-interpolation (type: discrete) has testAddition function
+PASS color-interpolation: "auto" onto "linearrgb"
+PASS color-interpolation: "linearrgb" onto "auto"
+PASS color-interpolation-filters (type: discrete) has testAddition function
+PASS color-interpolation-filters: "linearrgb" onto "srgb"
+PASS color-interpolation-filters: "srgb" onto "linearrgb"
+PASS column-count (type: positiveInteger) has testAddition function
+PASS column-count: positive integer
+PASS column-count (type: discrete) has testAddition function
+PASS column-count: "10" onto "auto"
+PASS column-count: "auto" onto "10"
+PASS column-gap (type: length) has testAddition function
+PASS column-gap: length
+PASS column-gap: length of rem
+PASS column-gap (type: discrete) has testAddition function
+PASS column-gap: "200px" onto "normal"
+PASS column-gap: "normal" onto "200px"
+PASS column-rule-color (type: color) has testAddition function
+PASS column-rule-color supports animating as color of rgb() with overflowed  from and to values
+PASS column-rule-color supports animating as color of #RGB
+PASS column-rule-color supports animating as color of hsl()
+PASS column-rule-color supports animating as color of #RGBa
+PASS column-rule-color supports animating as color of rgba()
+PASS column-rule-color supports animating as color of hsla()
+PASS column-fill (type: discrete) has testAddition function
+PASS column-fill: "balance" onto "auto"
+PASS column-fill: "auto" onto "balance"
+PASS column-rule-style (type: discrete) has testAddition function
+PASS column-rule-style: "dotted" onto "none"
+PASS column-rule-style: "none" onto "dotted"
+PASS column-rule-width (type: length) has testAddition function
+PASS column-rule-width: length
+PASS column-rule-width: length of rem
+PASS column-width (type: length) has testAddition function
+PASS column-width: length
+PASS column-width: length of rem
+PASS column-width (type: discrete) has testAddition function
+PASS column-width: "1px" onto "auto"
+PASS column-width: "auto" onto "1px"
+PASS counter-increment (type: discrete) has testAddition function
+PASS counter-increment: "ident-2 2" onto "ident-1 1"
+PASS counter-increment: "ident-1 1" onto "ident-2 2"
+PASS counter-reset (type: discrete) has testAddition function
+PASS counter-reset: "ident-2 2" onto "ident-1 1"
+PASS counter-reset: "ident-1 1" onto "ident-2 2"
+PASS cursor (type: discrete) has testAddition function
+PASS cursor: "wait" onto "pointer"
+PASS cursor: "pointer" onto "wait"
+PASS dominant-baseline (type: discrete) has testAddition function
+PASS dominant-baseline: "alphabetic" onto "ideographic"
+PASS dominant-baseline: "ideographic" onto "alphabetic"
+PASS empty-cells (type: discrete) has testAddition function
+PASS empty-cells: "hide" onto "show"
+PASS empty-cells: "show" onto "hide"
+PASS fill-opacity (type: opacity) has testAddition function
+PASS fill-opacity: [0, 1] number
+PASS fill-opacity: [0, 1] number (clamped)
+PASS fill-rule (type: discrete) has testAddition function
+PASS fill-rule: "nonzero" onto "evenodd"
+PASS fill-rule: "evenodd" onto "nonzero"
+PASS filter (type: filterList) has testAddition function
+PASS filter: blur on blur
+PASS filter: different filter functions
+PASS flex-basis (type: lengthPercentageOrCalc) has testAddition function
+PASS flex-basis: length
+PASS flex-basis: length of rem
+PASS flex-basis: percentage
+PASS flex-basis: units "%" onto "px"
+PASS flex-basis: units "px" onto "%"
+PASS flex-basis: units "rem" onto "%"
+PASS flex-basis: units "%" onto "rem"
+PASS flex-basis: units "rem" onto "em"
+PASS flex-basis: units "em" onto "rem"
+PASS flex-basis: units "calc" onto "px"
+PASS flex-basis: calc
+PASS flex-basis (type: discrete) has testAddition function
+PASS flex-basis: "10px" onto "auto"
+PASS flex-basis: "auto" onto "10px"
+PASS flex-direction (type: discrete) has testAddition function
+PASS flex-direction: "row-reverse" onto "row"
+PASS flex-direction: "row" onto "row-reverse"
+PASS flex-grow (type: positiveNumber) has testAddition function
+PASS flex-grow: positive number
+PASS flex-shrink (type: positiveNumber) has testAddition function
+PASS flex-shrink: positive number
+PASS flex-wrap (type: discrete) has testAddition function
+PASS flex-wrap: "wrap" onto "nowrap"
+PASS flex-wrap: "nowrap" onto "wrap"
+PASS flood-color (type: color) has testAddition function
+PASS flood-color supports animating as color of rgb() with overflowed  from and to values
+PASS flood-color supports animating as color of #RGB
+PASS flood-color supports animating as color of hsl()
+PASS flood-color supports animating as color of #RGBa
+PASS flood-color supports animating as color of rgba()
+PASS flood-color supports animating as color of hsla()
+PASS flood-opacity (type: opacity) has testAddition function
+PASS flood-opacity: [0, 1] number
+PASS flood-opacity: [0, 1] number (clamped)
+PASS font-stretch (type: percentage) has testAddition function
+PASS font-stretch: percentage
+PASS font-style (type: discrete) has testAddition function
+FAIL font-style: "oblique" onto "italic" assert_equals: The value should be oblique at 0ms expected "oblique" but got "italic"
+PASS font-style: "italic" onto "oblique"
+PASS float (type: discrete) has testAddition function
+PASS float: "right" onto "left"
+PASS float: "left" onto "right"
+PASS font-family (type: discrete) has testAddition function
+PASS font-family: "verdana" onto "helvetica"
+PASS font-family: "helvetica" onto "verdana"
+PASS font-feature-settings (type: discrete) has testAddition function
+PASS font-feature-settings: "normal" onto ""liga" 5"
+PASS font-feature-settings: ""liga" 5" onto "normal"
+PASS font-kerning (type: discrete) has testAddition function
+PASS font-kerning: "normal" onto "auto"
+PASS font-kerning: "auto" onto "normal"
+PASS font-synthesis (type: discrete) has testAddition function
+PASS font-synthesis: "weight style" onto "none"
+PASS font-synthesis: "none" onto "weight style"
+PASS font-variant-caps (type: discrete) has testAddition function
+PASS font-variant-caps: "unicase" onto "small-caps"
+PASS font-variant-caps: "small-caps" onto "unicase"
+PASS font-variant-east-asian (type: discrete) has testAddition function
+PASS font-variant-east-asian: "proportional-width" onto "full-width"
+PASS font-variant-east-asian: "full-width" onto "proportional-width"
+PASS font-variant-ligatures (type: discrete) has testAddition function
+PASS font-variant-ligatures: "no-common-ligatures" onto "common-ligatures"
+PASS font-variant-ligatures: "common-ligatures" onto "no-common-ligatures"
+PASS font-variant-numeric (type: discrete) has testAddition function
+PASS font-variant-numeric: "oldstyle-nums" onto "lining-nums"
+PASS font-variant-numeric: "lining-nums" onto "oldstyle-nums"
+PASS font-variation-settings (type: fontVariationSettings) has testAddition function
+PASS font-variation-settings with composite type add
+PASS font-variation-settings (type: discrete) has testAddition function
+PASS font-variation-settings: ""wdth" 5" onto ""wdth" 1, "wght" 1.1"
+PASS font-variation-settings: ""wdth" 1, "wght" 1.1" onto ""wdth" 5"
+PASS font-variation-settings: "normal" onto ""wdth" 5"
+PASS font-variation-settings: ""wdth" 5" onto "normal"
+PASS grid-auto-columns (type: discrete) has testAddition function
+PASS grid-auto-columns: "5px" onto "1px"
+PASS grid-auto-columns: "1px" onto "5px"
+PASS grid-auto-flow (type: discrete) has testAddition function
+PASS grid-auto-flow: "column" onto "row"
+PASS grid-auto-flow: "row" onto "column"
+PASS grid-auto-rows (type: discrete) has testAddition function
+PASS grid-auto-rows: "5px" onto "1px"
+PASS grid-auto-rows: "1px" onto "5px"
+PASS grid-column-end (type: discrete) has testAddition function
+PASS grid-column-end: "5" onto "1"
+PASS grid-column-end: "1" onto "5"
+PASS grid-column-start (type: discrete) has testAddition function
+PASS grid-column-start: "5" onto "1"
+PASS grid-column-start: "1" onto "5"
+PASS grid-row-end (type: discrete) has testAddition function
+PASS grid-row-end: "5" onto "1"
+PASS grid-row-end: "1" onto "5"
+PASS grid-row-start (type: discrete) has testAddition function
+PASS grid-row-start: "5" onto "1"
+PASS grid-row-start: "1" onto "5"
+PASS grid-template-areas (type: discrete) has testAddition function
+PASS grid-template-areas: "none" onto "". . a b" ". .a b""
+FAIL grid-template-areas: "". . a b" ". .a b"" onto "none" assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
+PASS hyphens (type: discrete) has testAddition function
+PASS hyphens: "none" onto "manual"
+PASS hyphens: "manual" onto "none"
+PASS image-orientation (type: discrete) has testAddition function
+PASS image-orientation: "from-image" onto "none"
+PASS image-orientation: "none" onto "from-image"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-001-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-001-expected.txt
new file mode 100644
index 0000000..b9f21595f
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-001-expected.txt
@@ -0,0 +1,381 @@
+This is a testharness.js-based test.
+Found 377 tests; 365 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Setup
+PASS align-content (type: discrete) has testInterpolation function
+PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
+PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with effect easing
+PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with keyframe easing
+PASS align-items (type: discrete) has testInterpolation function
+PASS align-items uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
+PASS align-items uses discrete animation when animating between "flex-start" and "flex-end" with effect easing
+PASS align-items uses discrete animation when animating between "flex-start" and "flex-end" with keyframe easing
+PASS align-self (type: discrete) has testInterpolation function
+PASS align-self uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
+PASS align-self uses discrete animation when animating between "flex-start" and "flex-end" with effect easing
+PASS align-self uses discrete animation when animating between "flex-start" and "flex-end" with keyframe easing
+PASS backface-visibility (type: discrete) has testInterpolation function
+PASS backface-visibility uses discrete animation when animating between "visible" and "hidden" with linear easing
+PASS backface-visibility uses discrete animation when animating between "visible" and "hidden" with effect easing
+PASS backface-visibility uses discrete animation when animating between "visible" and "hidden" with keyframe easing
+PASS background-attachment (type: discrete) has testInterpolation function
+PASS background-attachment uses discrete animation when animating between "fixed" and "local" with linear easing
+PASS background-attachment uses discrete animation when animating between "fixed" and "local" with effect easing
+PASS background-attachment uses discrete animation when animating between "fixed" and "local" with keyframe easing
+PASS background-color (type: color) has testInterpolation function
+PASS background-color supports animating as color of rgb()
+PASS background-color supports animating as color of #RGB
+PASS background-color supports animating as color of hsl()
+PASS background-color supports animating as color of #RGBa
+PASS background-color supports animating as color of rgba()
+PASS background-color supports animating as color of hsla()
+PASS background-blend-mode (type: discrete) has testInterpolation function
+PASS background-blend-mode uses discrete animation when animating between "multiply" and "screen" with linear easing
+PASS background-blend-mode uses discrete animation when animating between "multiply" and "screen" with effect easing
+PASS background-blend-mode uses discrete animation when animating between "multiply" and "screen" with keyframe easing
+PASS background-clip (type: discrete) has testInterpolation function
+PASS background-clip uses discrete animation when animating between "padding-box" and "content-box" with linear easing
+PASS background-clip uses discrete animation when animating between "padding-box" and "content-box" with effect easing
+PASS background-clip uses discrete animation when animating between "padding-box" and "content-box" with keyframe easing
+PASS background-image (type: discrete) has testInterpolation function
+FAIL background-image uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing assert_equals: The value should be url("http://localhost/test-1") at 499ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.499)"
+FAIL background-image uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.428259)"
+FAIL background-image uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.428259)"
+PASS background-origin (type: discrete) has testInterpolation function
+PASS background-origin uses discrete animation when animating between "padding-box" and "content-box" with linear easing
+PASS background-origin uses discrete animation when animating between "padding-box" and "content-box" with effect easing
+PASS background-origin uses discrete animation when animating between "padding-box" and "content-box" with keyframe easing
+PASS background-repeat (type: discrete) has testInterpolation function
+PASS background-repeat uses discrete animation when animating between "space" and "round" with linear easing
+PASS background-repeat uses discrete animation when animating between "space" and "round" with effect easing
+PASS background-repeat uses discrete animation when animating between "space" and "round" with keyframe easing
+PASS border-bottom-color (type: color) has testInterpolation function
+PASS border-bottom-color supports animating as color of rgb()
+PASS border-bottom-color supports animating as color of #RGB
+PASS border-bottom-color supports animating as color of hsl()
+PASS border-bottom-color supports animating as color of #RGBa
+PASS border-bottom-color supports animating as color of rgba()
+PASS border-bottom-color supports animating as color of hsla()
+PASS border-bottom-style (type: discrete) has testInterpolation function
+PASS border-bottom-style uses discrete animation when animating between "dotted" and "solid" with linear easing
+PASS border-bottom-style uses discrete animation when animating between "dotted" and "solid" with effect easing
+PASS border-bottom-style uses discrete animation when animating between "dotted" and "solid" with keyframe easing
+PASS border-bottom-width (type: length) has testInterpolation function
+PASS border-bottom-width supports animating as a length
+PASS border-bottom-width supports animating as a length of rem
+PASS border-collapse (type: discrete) has testInterpolation function
+PASS border-collapse uses discrete animation when animating between "collapse" and "separate" with linear easing
+PASS border-collapse uses discrete animation when animating between "collapse" and "separate" with effect easing
+PASS border-collapse uses discrete animation when animating between "collapse" and "separate" with keyframe easing
+PASS border-image-repeat (type: discrete) has testInterpolation function
+PASS border-image-repeat uses discrete animation when animating between "stretch repeat" and "round space" with linear easing
+PASS border-image-repeat uses discrete animation when animating between "stretch repeat" and "round space" with effect easing
+PASS border-image-repeat uses discrete animation when animating between "stretch repeat" and "round space" with keyframe easing
+PASS border-image-source (type: discrete) has testInterpolation function
+FAIL border-image-source uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing assert_equals: The value should be url("http://localhost/test-1") at 499ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.499)"
+FAIL border-image-source uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.428259)"
+FAIL border-image-source uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.428259)"
+PASS border-left-color (type: color) has testInterpolation function
+PASS border-left-color supports animating as color of rgb()
+PASS border-left-color supports animating as color of #RGB
+PASS border-left-color supports animating as color of hsl()
+PASS border-left-color supports animating as color of #RGBa
+PASS border-left-color supports animating as color of rgba()
+PASS border-left-color supports animating as color of hsla()
+PASS border-left-style (type: discrete) has testInterpolation function
+PASS border-left-style uses discrete animation when animating between "dotted" and "solid" with linear easing
+PASS border-left-style uses discrete animation when animating between "dotted" and "solid" with effect easing
+PASS border-left-style uses discrete animation when animating between "dotted" and "solid" with keyframe easing
+PASS border-left-width (type: length) has testInterpolation function
+PASS border-left-width supports animating as a length
+PASS border-left-width supports animating as a length of rem
+PASS border-right-color (type: color) has testInterpolation function
+PASS border-right-color supports animating as color of rgb()
+PASS border-right-color supports animating as color of #RGB
+PASS border-right-color supports animating as color of hsl()
+PASS border-right-color supports animating as color of #RGBa
+PASS border-right-color supports animating as color of rgba()
+PASS border-right-color supports animating as color of hsla()
+PASS border-right-style (type: discrete) has testInterpolation function
+PASS border-right-style uses discrete animation when animating between "dotted" and "solid" with linear easing
+PASS border-right-style uses discrete animation when animating between "dotted" and "solid" with effect easing
+PASS border-right-style uses discrete animation when animating between "dotted" and "solid" with keyframe easing
+PASS border-right-width (type: length) has testInterpolation function
+PASS border-right-width supports animating as a length
+PASS border-right-width supports animating as a length of rem
+PASS border-spacing (type: lengthPair) has testInterpolation function
+PASS border-spacing supports animating as a length pair
+PASS border-spacing supports animating as a length pair of rem
+PASS border-top-color (type: color) has testInterpolation function
+PASS border-top-color supports animating as color of rgb()
+PASS border-top-color supports animating as color of #RGB
+PASS border-top-color supports animating as color of hsl()
+PASS border-top-color supports animating as color of #RGBa
+PASS border-top-color supports animating as color of rgba()
+PASS border-top-color supports animating as color of hsla()
+PASS border-top-style (type: discrete) has testInterpolation function
+PASS border-top-style uses discrete animation when animating between "dotted" and "solid" with linear easing
+PASS border-top-style uses discrete animation when animating between "dotted" and "solid" with effect easing
+PASS border-top-style uses discrete animation when animating between "dotted" and "solid" with keyframe easing
+PASS border-top-width (type: length) has testInterpolation function
+PASS border-top-width supports animating as a length
+PASS border-top-width supports animating as a length of rem
+PASS box-shadow (type: boxShadowList) has testInterpolation function
+PASS box-shadow: from none to other
+PASS box-shadow: from other to none
+PASS box-shadow: single shadow
+PASS box-shadow: shadow list
+PASS box-shadow: mismatched list length (from shorter to longer)
+PASS box-shadow: mismatched list length (from longer to shorter)
+PASS box-shadow: with currentcolor
+PASS box-sizing (type: discrete) has testInterpolation function
+PASS box-sizing uses discrete animation when animating between "content-box" and "border-box" with linear easing
+PASS box-sizing uses discrete animation when animating between "content-box" and "border-box" with effect easing
+PASS box-sizing uses discrete animation when animating between "content-box" and "border-box" with keyframe easing
+PASS caption-side (type: discrete) has testInterpolation function
+PASS caption-side uses discrete animation when animating between "top" and "bottom" with linear easing
+PASS caption-side uses discrete animation when animating between "top" and "bottom" with effect easing
+PASS caption-side uses discrete animation when animating between "top" and "bottom" with keyframe easing
+PASS caret-color (type: color) has testInterpolation function
+PASS caret-color supports animating as color of rgb()
+PASS caret-color supports animating as color of #RGB
+PASS caret-color supports animating as color of hsl()
+PASS caret-color supports animating as color of #RGBa
+PASS caret-color supports animating as color of rgba()
+PASS caret-color supports animating as color of hsla()
+PASS clear (type: discrete) has testInterpolation function
+PASS clear uses discrete animation when animating between "left" and "right" with linear easing
+PASS clear uses discrete animation when animating between "left" and "right" with effect easing
+PASS clear uses discrete animation when animating between "left" and "right" with keyframe easing
+PASS clip (type: rect) has testInterpolation function
+PASS clip supports animating as a rect
+PASS clip (type: discrete) has testInterpolation function
+PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "auto" with linear easing
+PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "auto" with effect easing
+PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "auto" with keyframe easing
+PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "rect(10px, 10px, 10px, auto)" with linear easing
+PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "rect(10px, 10px, 10px, auto)" with effect easing
+PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "rect(10px, 10px, 10px, auto)" with keyframe easing
+PASS clip-rule (type: discrete) has testInterpolation function
+PASS clip-rule uses discrete animation when animating between "evenodd" and "nonzero" with linear easing
+PASS clip-rule uses discrete animation when animating between "evenodd" and "nonzero" with effect easing
+PASS clip-rule uses discrete animation when animating between "evenodd" and "nonzero" with keyframe easing
+PASS color (type: color) has testInterpolation function
+PASS color supports animating as color of rgb()
+PASS color supports animating as color of #RGB
+PASS color supports animating as color of hsl()
+PASS color supports animating as color of #RGBa
+PASS color supports animating as color of rgba()
+PASS color supports animating as color of hsla()
+PASS color-interpolation (type: discrete) has testInterpolation function
+PASS color-interpolation uses discrete animation when animating between "linearrgb" and "auto" with linear easing
+PASS color-interpolation uses discrete animation when animating between "linearrgb" and "auto" with effect easing
+PASS color-interpolation uses discrete animation when animating between "linearrgb" and "auto" with keyframe easing
+PASS color-interpolation-filters (type: discrete) has testInterpolation function
+PASS color-interpolation-filters uses discrete animation when animating between "srgb" and "linearrgb" with linear easing
+PASS color-interpolation-filters uses discrete animation when animating between "srgb" and "linearrgb" with effect easing
+PASS color-interpolation-filters uses discrete animation when animating between "srgb" and "linearrgb" with keyframe easing
+PASS column-count (type: positiveInteger) has testInterpolation function
+PASS column-count supports animating as a positive integer
+PASS column-count (type: discrete) has testInterpolation function
+PASS column-count uses discrete animation when animating between "auto" and "10" with linear easing
+PASS column-count uses discrete animation when animating between "auto" and "10" with effect easing
+PASS column-count uses discrete animation when animating between "auto" and "10" with keyframe easing
+PASS column-gap (type: length) has testInterpolation function
+PASS column-gap supports animating as a length
+PASS column-gap supports animating as a length of rem
+PASS column-gap (type: discrete) has testInterpolation function
+PASS column-gap uses discrete animation when animating between "normal" and "200px" with linear easing
+PASS column-gap uses discrete animation when animating between "normal" and "200px" with effect easing
+PASS column-gap uses discrete animation when animating between "normal" and "200px" with keyframe easing
+PASS column-rule-color (type: color) has testInterpolation function
+PASS column-rule-color supports animating as color of rgb()
+PASS column-rule-color supports animating as color of #RGB
+PASS column-rule-color supports animating as color of hsl()
+PASS column-rule-color supports animating as color of #RGBa
+PASS column-rule-color supports animating as color of rgba()
+PASS column-rule-color supports animating as color of hsla()
+PASS column-fill (type: discrete) has testInterpolation function
+PASS column-fill uses discrete animation when animating between "auto" and "balance" with linear easing
+PASS column-fill uses discrete animation when animating between "auto" and "balance" with effect easing
+PASS column-fill uses discrete animation when animating between "auto" and "balance" with keyframe easing
+PASS column-rule-style (type: discrete) has testInterpolation function
+PASS column-rule-style uses discrete animation when animating between "none" and "dotted" with linear easing
+PASS column-rule-style uses discrete animation when animating between "none" and "dotted" with effect easing
+PASS column-rule-style uses discrete animation when animating between "none" and "dotted" with keyframe easing
+PASS column-rule-width (type: length) has testInterpolation function
+PASS column-rule-width supports animating as a length
+PASS column-rule-width supports animating as a length of rem
+PASS column-width (type: length) has testInterpolation function
+PASS column-width supports animating as a length
+PASS column-width supports animating as a length of rem
+PASS column-width (type: discrete) has testInterpolation function
+PASS column-width uses discrete animation when animating between "auto" and "1px" with linear easing
+PASS column-width uses discrete animation when animating between "auto" and "1px" with effect easing
+PASS column-width uses discrete animation when animating between "auto" and "1px" with keyframe easing
+PASS counter-increment (type: discrete) has testInterpolation function
+PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with linear easing
+PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with effect easing
+PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with keyframe easing
+PASS counter-reset (type: discrete) has testInterpolation function
+PASS counter-reset uses discrete animation when animating between "ident-1 1" and "ident-2 2" with linear easing
+PASS counter-reset uses discrete animation when animating between "ident-1 1" and "ident-2 2" with effect easing
+PASS counter-reset uses discrete animation when animating between "ident-1 1" and "ident-2 2" with keyframe easing
+PASS cursor (type: discrete) has testInterpolation function
+PASS cursor uses discrete animation when animating between "pointer" and "wait" with linear easing
+PASS cursor uses discrete animation when animating between "pointer" and "wait" with effect easing
+PASS cursor uses discrete animation when animating between "pointer" and "wait" with keyframe easing
+PASS dominant-baseline (type: discrete) has testInterpolation function
+PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with linear easing
+PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with effect easing
+PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with keyframe easing
+PASS empty-cells (type: discrete) has testInterpolation function
+PASS empty-cells uses discrete animation when animating between "show" and "hide" with linear easing
+PASS empty-cells uses discrete animation when animating between "show" and "hide" with effect easing
+PASS empty-cells uses discrete animation when animating between "show" and "hide" with keyframe easing
+PASS fill-opacity (type: opacity) has testInterpolation function
+PASS fill-opacity supports animating as a [0, 1] number
+PASS fill-rule (type: discrete) has testInterpolation function
+PASS fill-rule uses discrete animation when animating between "evenodd" and "nonzero" with linear easing
+PASS fill-rule uses discrete animation when animating between "evenodd" and "nonzero" with effect easing
+PASS fill-rule uses discrete animation when animating between "evenodd" and "nonzero" with keyframe easing
+PASS filter (type: filterList) has testInterpolation function
+PASS filter: blur function
+PASS filter: hue-rotate function with same unit(deg)
+PASS filter: hue-rotate function with different unit(deg -> rad)
+PASS filter: drop-shadow function
+PASS filter: percentage or numeric-specifiable functions (number value)
+PASS filter: percentage or numeric-specifiable functions (percentage value)
+PASS filter: interpolate different length of filter-function-list with function which lacuna value is 1
+PASS filter: interpolate different length of filter-function-list with function which lacuna value is 0
+PASS filter: interpolate different length of filter-function-list with drop-shadow function
+PASS filter: interpolate from none
+PASS filter: url function (interpoalte as discrete)
+PASS flex-basis (type: lengthPercentageOrCalc) has testInterpolation function
+PASS flex-basis supports animating as a length
+PASS flex-basis supports animating as a length of rem
+PASS flex-basis supports animating as a percentage
+PASS flex-basis supports animating as combination units "px" and "%"
+PASS flex-basis supports animating as combination units "%" and "em"
+PASS flex-basis supports animating as combination units "em" and "rem"
+PASS flex-basis supports animating as combination units "px" and "calc"
+PASS flex-basis supports animating as a calc
+PASS flex-basis (type: discrete) has testInterpolation function
+PASS flex-basis uses discrete animation when animating between "auto" and "10px" with linear easing
+PASS flex-basis uses discrete animation when animating between "auto" and "10px" with effect easing
+PASS flex-basis uses discrete animation when animating between "auto" and "10px" with keyframe easing
+PASS flex-direction (type: discrete) has testInterpolation function
+PASS flex-direction uses discrete animation when animating between "row" and "row-reverse" with linear easing
+PASS flex-direction uses discrete animation when animating between "row" and "row-reverse" with effect easing
+PASS flex-direction uses discrete animation when animating between "row" and "row-reverse" with keyframe easing
+PASS flex-grow (type: positiveNumber) has testInterpolation function
+PASS flex-grow supports animating as a positive number
+PASS flex-shrink (type: positiveNumber) has testInterpolation function
+PASS flex-shrink supports animating as a positive number
+PASS flex-wrap (type: discrete) has testInterpolation function
+PASS flex-wrap uses discrete animation when animating between "nowrap" and "wrap" with linear easing
+PASS flex-wrap uses discrete animation when animating between "nowrap" and "wrap" with effect easing
+PASS flex-wrap uses discrete animation when animating between "nowrap" and "wrap" with keyframe easing
+PASS flood-color (type: color) has testInterpolation function
+PASS flood-color supports animating as color of rgb()
+PASS flood-color supports animating as color of #RGB
+PASS flood-color supports animating as color of hsl()
+PASS flood-color supports animating as color of #RGBa
+PASS flood-color supports animating as color of rgba()
+PASS flood-color supports animating as color of hsla()
+PASS flood-opacity (type: opacity) has testInterpolation function
+PASS flood-opacity supports animating as a [0, 1] number
+PASS font-stretch (type: percentage) has testInterpolation function
+PASS font-stretch supports animating as a percentage
+PASS font-style (type: discrete) has testInterpolation function
+FAIL font-style uses discrete animation when animating between "italic" and "oblique" with linear easing assert_equals: The value should be oblique at 500ms expected "oblique" but got "italic"
+FAIL font-style uses discrete animation when animating between "italic" and "oblique" with effect easing assert_equals: The value should be oblique at 960ms expected "oblique" but got "italic"
+FAIL font-style uses discrete animation when animating between "italic" and "oblique" with keyframe easing assert_equals: The value should be oblique at 960ms expected "oblique" but got "italic"
+PASS float (type: discrete) has testInterpolation function
+PASS float uses discrete animation when animating between "left" and "right" with linear easing
+PASS float uses discrete animation when animating between "left" and "right" with effect easing
+PASS float uses discrete animation when animating between "left" and "right" with keyframe easing
+PASS font-family (type: discrete) has testInterpolation function
+PASS font-family uses discrete animation when animating between "helvetica" and "verdana" with linear easing
+PASS font-family uses discrete animation when animating between "helvetica" and "verdana" with effect easing
+PASS font-family uses discrete animation when animating between "helvetica" and "verdana" with keyframe easing
+PASS font-feature-settings (type: discrete) has testInterpolation function
+PASS font-feature-settings uses discrete animation when animating between ""liga" 5" and "normal" with linear easing
+PASS font-feature-settings uses discrete animation when animating between ""liga" 5" and "normal" with effect easing
+PASS font-feature-settings uses discrete animation when animating between ""liga" 5" and "normal" with keyframe easing
+PASS font-kerning (type: discrete) has testInterpolation function
+PASS font-kerning uses discrete animation when animating between "auto" and "normal" with linear easing
+PASS font-kerning uses discrete animation when animating between "auto" and "normal" with effect easing
+PASS font-kerning uses discrete animation when animating between "auto" and "normal" with keyframe easing
+PASS font-synthesis (type: discrete) has testInterpolation function
+PASS font-synthesis uses discrete animation when animating between "none" and "weight style" with linear easing
+PASS font-synthesis uses discrete animation when animating between "none" and "weight style" with effect easing
+PASS font-synthesis uses discrete animation when animating between "none" and "weight style" with keyframe easing
+PASS font-variant-caps (type: discrete) has testInterpolation function
+PASS font-variant-caps uses discrete animation when animating between "small-caps" and "unicase" with linear easing
+PASS font-variant-caps uses discrete animation when animating between "small-caps" and "unicase" with effect easing
+PASS font-variant-caps uses discrete animation when animating between "small-caps" and "unicase" with keyframe easing
+PASS font-variant-east-asian (type: discrete) has testInterpolation function
+PASS font-variant-east-asian uses discrete animation when animating between "full-width" and "proportional-width" with linear easing
+PASS font-variant-east-asian uses discrete animation when animating between "full-width" and "proportional-width" with effect easing
+PASS font-variant-east-asian uses discrete animation when animating between "full-width" and "proportional-width" with keyframe easing
+PASS font-variant-ligatures (type: discrete) has testInterpolation function
+PASS font-variant-ligatures uses discrete animation when animating between "common-ligatures" and "no-common-ligatures" with linear easing
+PASS font-variant-ligatures uses discrete animation when animating between "common-ligatures" and "no-common-ligatures" with effect easing
+PASS font-variant-ligatures uses discrete animation when animating between "common-ligatures" and "no-common-ligatures" with keyframe easing
+PASS font-variant-numeric (type: discrete) has testInterpolation function
+PASS font-variant-numeric uses discrete animation when animating between "lining-nums" and "oldstyle-nums" with linear easing
+PASS font-variant-numeric uses discrete animation when animating between "lining-nums" and "oldstyle-nums" with effect easing
+PASS font-variant-numeric uses discrete animation when animating between "lining-nums" and "oldstyle-nums" with keyframe easing
+PASS font-variation-settings (type: fontVariationSettings) has testInterpolation function
+PASS font-variation-settings supports animation as float
+PASS font-variation-settings supports animation as float with multiple tags
+PASS font-variation-settings supports animation as float with multiple duplicate tags
+PASS font-variation-settings (type: discrete) has testInterpolation function
+PASS font-variation-settings uses discrete animation when animating between ""wdth" 1, "wght" 1.1" and ""wdth" 5" with linear easing
+PASS font-variation-settings uses discrete animation when animating between ""wdth" 1, "wght" 1.1" and ""wdth" 5" with effect easing
+PASS font-variation-settings uses discrete animation when animating between ""wdth" 1, "wght" 1.1" and ""wdth" 5" with keyframe easing
+PASS font-variation-settings uses discrete animation when animating between ""wdth" 5" and "normal" with linear easing
+PASS font-variation-settings uses discrete animation when animating between ""wdth" 5" and "normal" with effect easing
+PASS font-variation-settings uses discrete animation when animating between ""wdth" 5" and "normal" with keyframe easing
+PASS grid-auto-columns (type: discrete) has testInterpolation function
+PASS grid-auto-columns uses discrete animation when animating between "1px" and "5px" with linear easing
+PASS grid-auto-columns uses discrete animation when animating between "1px" and "5px" with effect easing
+PASS grid-auto-columns uses discrete animation when animating between "1px" and "5px" with keyframe easing
+PASS grid-auto-flow (type: discrete) has testInterpolation function
+PASS grid-auto-flow uses discrete animation when animating between "row" and "column" with linear easing
+PASS grid-auto-flow uses discrete animation when animating between "row" and "column" with effect easing
+PASS grid-auto-flow uses discrete animation when animating between "row" and "column" with keyframe easing
+PASS grid-auto-rows (type: discrete) has testInterpolation function
+PASS grid-auto-rows uses discrete animation when animating between "1px" and "5px" with linear easing
+PASS grid-auto-rows uses discrete animation when animating between "1px" and "5px" with effect easing
+PASS grid-auto-rows uses discrete animation when animating between "1px" and "5px" with keyframe easing
+PASS grid-column-end (type: discrete) has testInterpolation function
+PASS grid-column-end uses discrete animation when animating between "1" and "5" with linear easing
+PASS grid-column-end uses discrete animation when animating between "1" and "5" with effect easing
+PASS grid-column-end uses discrete animation when animating between "1" and "5" with keyframe easing
+PASS grid-column-start (type: discrete) has testInterpolation function
+PASS grid-column-start uses discrete animation when animating between "1" and "5" with linear easing
+PASS grid-column-start uses discrete animation when animating between "1" and "5" with effect easing
+PASS grid-column-start uses discrete animation when animating between "1" and "5" with keyframe easing
+PASS grid-row-end (type: discrete) has testInterpolation function
+PASS grid-row-end uses discrete animation when animating between "1" and "5" with linear easing
+PASS grid-row-end uses discrete animation when animating between "1" and "5" with effect easing
+PASS grid-row-end uses discrete animation when animating between "1" and "5" with keyframe easing
+PASS grid-row-start (type: discrete) has testInterpolation function
+PASS grid-row-start uses discrete animation when animating between "1" and "5" with linear easing
+PASS grid-row-start uses discrete animation when animating between "1" and "5" with effect easing
+PASS grid-row-start uses discrete animation when animating between "1" and "5" with keyframe easing
+PASS grid-template-areas (type: discrete) has testInterpolation function
+FAIL grid-template-areas uses discrete animation when animating between "". . a b" ". .a b"" and "none" with linear easing assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
+FAIL grid-template-areas uses discrete animation when animating between "". . a b" ". .a b"" and "none" with effect easing assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
+FAIL grid-template-areas uses discrete animation when animating between "". . a b" ". .a b"" and "none" with keyframe easing assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
+PASS hyphens (type: discrete) has testInterpolation function
+PASS hyphens uses discrete animation when animating between "manual" and "none" with linear easing
+PASS hyphens uses discrete animation when animating between "manual" and "none" with effect easing
+PASS hyphens uses discrete animation when animating between "manual" and "none" with keyframe easing
+PASS image-orientation (type: discrete) has testInterpolation function
+PASS image-orientation uses discrete animation when animating between "none" and "from-image" with linear easing
+PASS image-orientation uses discrete animation when animating between "none" and "from-image" with effect easing
+PASS image-orientation uses discrete animation when animating between "none" and "from-image" with keyframe easing
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/getComputedStyle/computed-style-listing-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/getComputedStyle/computed-style-listing-expected.txt
new file mode 100644
index 0000000..1045aac
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/getComputedStyle/computed-style-listing-expected.txt
@@ -0,0 +1,377 @@
+This test documents all computed styles on a div element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+-webkit-border-horizontal-spacing: 0px
+-webkit-border-image: none
+-webkit-border-vertical-spacing: 0px
+-webkit-box-align: stretch
+-webkit-box-decoration-break: slice
+-webkit-box-direction: normal
+-webkit-box-flex: 0
+-webkit-box-ordinal-group: 1
+-webkit-box-orient: horizontal
+-webkit-box-pack: start
+-webkit-box-reflect: none
+-webkit-font-smoothing: auto
+-webkit-highlight: none
+-webkit-line-break: auto
+-webkit-line-clamp: none
+-webkit-locale: auto
+-webkit-mask-box-image: none
+-webkit-mask-box-image-outset: 0
+-webkit-mask-box-image-repeat: stretch
+-webkit-mask-box-image-slice: 0 fill
+-webkit-mask-box-image-source: none
+-webkit-mask-box-image-width: auto
+-webkit-mask-clip: border-box
+-webkit-mask-composite: source-over
+-webkit-mask-image: none
+-webkit-mask-origin: border-box
+-webkit-mask-position: 0% 0%
+-webkit-mask-position-x: 0%
+-webkit-mask-position-y: 0%
+-webkit-mask-repeat: repeat
+-webkit-mask-size: auto
+-webkit-print-color-adjust: economy
+-webkit-rtl-ordering: logical
+-webkit-text-combine: none
+-webkit-text-decorations-in-effect: none
+-webkit-text-fill-color: rgb(0, 0, 0)
+-webkit-text-orientation: vertical-right
+-webkit-text-security: none
+-webkit-text-stroke-color: rgb(0, 0, 0)
+-webkit-text-stroke-width: 0px
+-webkit-user-drag: auto
+-webkit-user-modify: read-only
+-webkit-writing-mode: horizontal-tb
+accent-color: auto
+align-content: normal
+align-items: normal
+align-self: auto
+alignment-baseline: auto
+anchor-name: none
+anchor-scroll: none
+animation-delay: 0s
+animation-direction: normal
+animation-duration: 0s
+animation-fill-mode: none
+animation-iteration-count: 1
+animation-name: none
+animation-play-state: running
+animation-timeline: auto
+animation-timing-function: ease
+app-region: none
+appearance: none
+backdrop-filter: none
+backface-visibility: visible
+background-attachment: scroll
+background-blend-mode: normal
+background-clip: border-box
+background-color: rgba(0, 0, 0, 0)
+background-image: none
+background-origin: padding-box
+background-position: 0% 0%
+background-position-x: 0%
+background-position-y: 0%
+background-repeat: repeat
+background-size: auto
+baseline-shift: 0px
+block-size: 0px
+border-block-end-color: rgb(0, 0, 0)
+border-block-end-style: none
+border-block-end-width: 0px
+border-block-start-color: rgb(0, 0, 0)
+border-block-start-style: none
+border-block-start-width: 0px
+border-bottom-color: rgb(0, 0, 0)
+border-bottom-left-radius: 0px
+border-bottom-right-radius: 0px
+border-bottom-style: none
+border-bottom-width: 0px
+border-collapse: separate
+border-end-end-radius: 0px
+border-end-start-radius: 0px
+border-image-outset: 0
+border-image-repeat: stretch
+border-image-slice: 100%
+border-image-source: none
+border-image-width: 1
+border-inline-end-color: rgb(0, 0, 0)
+border-inline-end-style: none
+border-inline-end-width: 0px
+border-inline-start-color: rgb(0, 0, 0)
+border-inline-start-style: none
+border-inline-start-width: 0px
+border-left-color: rgb(0, 0, 0)
+border-left-style: none
+border-left-width: 0px
+border-right-color: rgb(0, 0, 0)
+border-right-style: none
+border-right-width: 0px
+border-spacing: 0px 0px
+border-start-end-radius: 0px
+border-start-start-radius: 0px
+border-top-color: rgb(0, 0, 0)
+border-top-left-radius: 0px
+border-top-right-radius: 0px
+border-top-style: none
+border-top-width: 0px
+bottom: auto
+box-shadow: none
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+buffered-rendering: auto
+caption-side: top
+caret-color: rgb(0, 0, 0)
+clear: none
+clip: auto
+clip-path: none
+clip-rule: nonzero
+color: rgb(0, 0, 0)
+color-interpolation: srgb
+color-interpolation-filters: linearrgb
+color-rendering: auto
+column-count: auto
+column-gap: normal
+column-rule-color: rgb(0, 0, 0)
+column-rule-style: none
+column-rule-width: 0px
+column-span: none
+column-width: auto
+contain-intrinsic-block-size: none
+contain-intrinsic-height: none
+contain-intrinsic-inline-size: none
+contain-intrinsic-size: none
+contain-intrinsic-width: none
+container-name: none
+container-type: normal
+content: normal
+cursor: auto
+cx: 0px
+cy: 0px
+d: none
+direction: ltr
+display: block
+dominant-baseline: auto
+empty-cells: show
+fill: rgb(0, 0, 0)
+fill-opacity: 1
+fill-rule: nonzero
+filter: none
+flex-basis: auto
+flex-direction: row
+flex-grow: 0
+flex-shrink: 1
+flex-wrap: nowrap
+float: none
+flood-color: rgb(0, 0, 0)
+flood-opacity: 1
+font-kerning: auto
+font-optical-sizing: auto
+font-palette: normal
+font-size: 16px
+font-size-adjust: none
+font-stretch: 100%
+font-style: normal
+font-synthesis-small-caps: auto
+font-synthesis-style: auto
+font-synthesis-weight: auto
+font-variant: normal
+font-variant-caps: normal
+font-variant-east-asian: normal
+font-variant-ligatures: normal
+font-variant-numeric: normal
+font-weight: 400
+grid-auto-columns: auto
+grid-auto-flow: row
+grid-auto-rows: auto
+grid-column-end: auto
+grid-column-start: auto
+grid-row-end: auto
+grid-row-start: auto
+grid-template-areas: none
+grid-template-columns: none
+grid-template-rows: none
+height: 0px
+hyphenate-character: auto
+hyphens: manual
+image-orientation: from-image
+image-rendering: auto
+inline-size: 769px
+inset-block-end: auto
+inset-block-start: auto
+inset-inline-end: auto
+inset-inline-start: auto
+isolation: auto
+justify-content: normal
+justify-items: normal
+justify-self: auto
+left: auto
+letter-spacing: normal
+lighting-color: rgb(255, 255, 255)
+line-break: auto
+line-height: normal
+line-height-step: 0px
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-block-end: 0px
+margin-block-start: 0px
+margin-bottom: 0px
+margin-inline-end: 0px
+margin-inline-start: 0px
+margin-left: 0px
+margin-right: 0px
+margin-top: 0px
+marker-end: none
+marker-mid: none
+marker-start: none
+mask-type: luminance
+math-depth: 0
+math-shift: normal
+math-style: normal
+max-block-size: none
+max-height: none
+max-inline-size: none
+max-width: none
+min-block-size: 0px
+min-height: 0px
+min-inline-size: 0px
+min-width: 0px
+mix-blend-mode: normal
+object-fit: fill
+object-position: 50% 50%
+object-view-box: none
+offset-anchor: auto
+offset-distance: 0px
+offset-path: none
+offset-position: auto
+offset-rotate: auto 0deg
+opacity: 1
+order: 0
+orphans: 2
+outline-color: rgb(0, 0, 0)
+outline-offset: 0px
+outline-style: none
+outline-width: 0px
+overflow: visible
+overflow-anchor: auto
+overflow-block: visible
+overflow-clip-margin: 0px
+overflow-inline: visible
+overflow-wrap: normal
+overflow-x: visible
+overflow-y: visible
+overscroll-behavior-block: auto
+overscroll-behavior-inline: auto
+padding-block-end: 0px
+padding-block-start: 0px
+padding-bottom: 0px
+padding-inline-end: 0px
+padding-inline-start: 0px
+padding-left: 0px
+padding-right: 0px
+padding-top: 0px
+paint-order: normal
+perspective: none
+perspective-origin: 384.5px 0px
+pointer-events: auto
+position: static
+position-fallback: none
+r: 0px
+resize: none
+right: auto
+rotate: none
+row-gap: normal
+ruby-position: over
+rx: auto
+ry: auto
+scale: none
+scroll-behavior: auto
+scroll-margin-block-end: 0px
+scroll-margin-block-start: 0px
+scroll-margin-inline-end: 0px
+scroll-margin-inline-start: 0px
+scroll-padding-block-end: auto
+scroll-padding-block-start: auto
+scroll-padding-inline-end: auto
+scroll-padding-inline-start: auto
+scroll-timeline-axis: block
+scroll-timeline-name: none
+scrollbar-gutter: auto
+scrollbar-width: auto
+shape-image-threshold: 0
+shape-margin: 0px
+shape-outside: none
+shape-rendering: auto
+speak: normal
+stop-color: rgb(0, 0, 0)
+stop-opacity: 1
+stroke: none
+stroke-dasharray: none
+stroke-dashoffset: 0px
+stroke-linecap: butt
+stroke-linejoin: miter
+stroke-miterlimit: 4
+stroke-opacity: 1
+stroke-width: 1px
+tab-size: 8
+table-layout: auto
+text-align: start
+text-align-last: auto
+text-anchor: start
+text-decoration: none solid rgb(0, 0, 0)
+text-decoration-color: rgb(0, 0, 0)
+text-decoration-line: none
+text-decoration-skip-ink: auto
+text-decoration-style: solid
+text-emphasis-color: rgb(0, 0, 0)
+text-emphasis-position: over
+text-emphasis-style: none
+text-indent: 0px
+text-overflow: clip
+text-rendering: auto
+text-shadow: none
+text-size-adjust: auto
+text-transform: none
+text-underline-position: auto
+toggle-group: none
+toggle-root: none
+toggle-trigger: none
+toggle-visibility: normal
+top: auto
+touch-action: auto
+transform: none
+transform-origin: 384.5px 0px
+transform-style: flat
+transition-delay: 0s
+transition-duration: 0s
+transition-property: all
+transition-timing-function: ease
+translate: none
+unicode-bidi: normal
+user-select: auto
+vector-effect: none
+vertical-align: baseline
+view-timeline-axis: block
+view-timeline-inset: 0px
+view-timeline-name: none
+visibility: visible
+white-space: normal
+widows: 2
+width: 769px
+will-change: auto
+word-break: normal
+word-spacing: 0px
+writing-mode: horizontal-tb
+x: 0px
+y: 0px
+z-index: auto
+zoom: 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
new file mode 100644
index 0000000..be19a1e8
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
@@ -0,0 +1,377 @@
+This test documents all computed styles on a display: none element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+-webkit-border-horizontal-spacing: 0px
+-webkit-border-image: none
+-webkit-border-vertical-spacing: 0px
+-webkit-box-align: stretch
+-webkit-box-decoration-break: slice
+-webkit-box-direction: normal
+-webkit-box-flex: 0
+-webkit-box-ordinal-group: 1
+-webkit-box-orient: horizontal
+-webkit-box-pack: start
+-webkit-box-reflect: none
+-webkit-font-smoothing: auto
+-webkit-highlight: none
+-webkit-line-break: auto
+-webkit-line-clamp: none
+-webkit-locale: auto
+-webkit-mask-box-image: none
+-webkit-mask-box-image-outset: 0
+-webkit-mask-box-image-repeat: stretch
+-webkit-mask-box-image-slice: 0 fill
+-webkit-mask-box-image-source: none
+-webkit-mask-box-image-width: auto
+-webkit-mask-clip: border-box
+-webkit-mask-composite: source-over
+-webkit-mask-image: none
+-webkit-mask-origin: border-box
+-webkit-mask-position: 0% 0%
+-webkit-mask-position-x: 0%
+-webkit-mask-position-y: 0%
+-webkit-mask-repeat: repeat
+-webkit-mask-size: auto
+-webkit-print-color-adjust: economy
+-webkit-rtl-ordering: logical
+-webkit-text-combine: none
+-webkit-text-decorations-in-effect: none
+-webkit-text-fill-color: rgb(0, 0, 0)
+-webkit-text-orientation: vertical-right
+-webkit-text-security: none
+-webkit-text-stroke-color: rgb(0, 0, 0)
+-webkit-text-stroke-width: 0px
+-webkit-user-drag: auto
+-webkit-user-modify: read-only
+-webkit-writing-mode: horizontal-tb
+accent-color: auto
+align-content: normal
+align-items: normal
+align-self: auto
+alignment-baseline: auto
+anchor-name: none
+anchor-scroll: none
+animation-delay: 0s
+animation-direction: normal
+animation-duration: 0s
+animation-fill-mode: none
+animation-iteration-count: 1
+animation-name: none
+animation-play-state: running
+animation-timeline: auto
+animation-timing-function: ease
+app-region: none
+appearance: none
+backdrop-filter: none
+backface-visibility: visible
+background-attachment: scroll
+background-blend-mode: normal
+background-clip: border-box
+background-color: rgba(0, 0, 0, 0)
+background-image: none
+background-origin: padding-box
+background-position: 0% 0%
+background-position-x: 0%
+background-position-y: 0%
+background-repeat: repeat
+background-size: auto
+baseline-shift: 0px
+block-size: auto
+border-block-end-color: rgb(0, 0, 0)
+border-block-end-style: none
+border-block-end-width: 0px
+border-block-start-color: rgb(0, 0, 0)
+border-block-start-style: none
+border-block-start-width: 0px
+border-bottom-color: rgb(0, 0, 0)
+border-bottom-left-radius: 0px
+border-bottom-right-radius: 0px
+border-bottom-style: none
+border-bottom-width: 0px
+border-collapse: separate
+border-end-end-radius: 0px
+border-end-start-radius: 0px
+border-image-outset: 0
+border-image-repeat: stretch
+border-image-slice: 100%
+border-image-source: none
+border-image-width: 1
+border-inline-end-color: rgb(0, 0, 0)
+border-inline-end-style: none
+border-inline-end-width: 0px
+border-inline-start-color: rgb(0, 0, 0)
+border-inline-start-style: none
+border-inline-start-width: 0px
+border-left-color: rgb(0, 0, 0)
+border-left-style: none
+border-left-width: 0px
+border-right-color: rgb(0, 0, 0)
+border-right-style: none
+border-right-width: 0px
+border-spacing: 0px 0px
+border-start-end-radius: 0px
+border-start-start-radius: 0px
+border-top-color: rgb(0, 0, 0)
+border-top-left-radius: 0px
+border-top-right-radius: 0px
+border-top-style: none
+border-top-width: 0px
+bottom: auto
+box-shadow: none
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+buffered-rendering: auto
+caption-side: top
+caret-color: rgb(0, 0, 0)
+clear: none
+clip: auto
+clip-path: none
+clip-rule: nonzero
+color: rgb(0, 0, 0)
+color-interpolation: srgb
+color-interpolation-filters: linearrgb
+color-rendering: auto
+column-count: auto
+column-gap: normal
+column-rule-color: rgb(0, 0, 0)
+column-rule-style: none
+column-rule-width: 0px
+column-span: none
+column-width: auto
+contain-intrinsic-block-size: none
+contain-intrinsic-height: none
+contain-intrinsic-inline-size: none
+contain-intrinsic-size: none
+contain-intrinsic-width: none
+container-name: none
+container-type: normal
+content: normal
+cursor: auto
+cx: 0px
+cy: 0px
+d: none
+direction: ltr
+display: none
+dominant-baseline: auto
+empty-cells: show
+fill: rgb(0, 0, 0)
+fill-opacity: 1
+fill-rule: nonzero
+filter: none
+flex-basis: auto
+flex-direction: row
+flex-grow: 0
+flex-shrink: 1
+flex-wrap: nowrap
+float: none
+flood-color: rgb(0, 0, 0)
+flood-opacity: 1
+font-kerning: auto
+font-optical-sizing: auto
+font-palette: normal
+font-size: 16px
+font-size-adjust: none
+font-stretch: 100%
+font-style: normal
+font-synthesis-small-caps: auto
+font-synthesis-style: auto
+font-synthesis-weight: auto
+font-variant: normal
+font-variant-caps: normal
+font-variant-east-asian: normal
+font-variant-ligatures: normal
+font-variant-numeric: normal
+font-weight: 400
+grid-auto-columns: auto
+grid-auto-flow: row
+grid-auto-rows: auto
+grid-column-end: auto
+grid-column-start: auto
+grid-row-end: auto
+grid-row-start: auto
+grid-template-areas: none
+grid-template-columns: none
+grid-template-rows: none
+height: auto
+hyphenate-character: auto
+hyphens: manual
+image-orientation: from-image
+image-rendering: auto
+inline-size: auto
+inset-block-end: auto
+inset-block-start: auto
+inset-inline-end: auto
+inset-inline-start: auto
+isolation: auto
+justify-content: normal
+justify-items: normal
+justify-self: auto
+left: auto
+letter-spacing: normal
+lighting-color: rgb(255, 255, 255)
+line-break: auto
+line-height: normal
+line-height-step: 0px
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-block-end: 0px
+margin-block-start: 0px
+margin-bottom: 0px
+margin-inline-end: 0px
+margin-inline-start: 0px
+margin-left: 0px
+margin-right: 0px
+margin-top: 0px
+marker-end: none
+marker-mid: none
+marker-start: none
+mask-type: luminance
+math-depth: 0
+math-shift: normal
+math-style: normal
+max-block-size: none
+max-height: none
+max-inline-size: none
+max-width: none
+min-block-size: 0px
+min-height: 0px
+min-inline-size: 0px
+min-width: 0px
+mix-blend-mode: normal
+object-fit: fill
+object-position: 50% 50%
+object-view-box: none
+offset-anchor: auto
+offset-distance: 0px
+offset-path: none
+offset-position: auto
+offset-rotate: auto 0deg
+opacity: 1
+order: 0
+orphans: 2
+outline-color: rgb(0, 0, 0)
+outline-offset: 0px
+outline-style: none
+outline-width: 0px
+overflow: visible
+overflow-anchor: auto
+overflow-block: visible
+overflow-clip-margin: 0px
+overflow-inline: visible
+overflow-wrap: normal
+overflow-x: visible
+overflow-y: visible
+overscroll-behavior-block: auto
+overscroll-behavior-inline: auto
+padding-block-end: 0px
+padding-block-start: 0px
+padding-bottom: 0px
+padding-inline-end: 0px
+padding-inline-start: 0px
+padding-left: 0px
+padding-right: 0px
+padding-top: 0px
+paint-order: normal
+perspective: none
+perspective-origin: 50% 50%
+pointer-events: auto
+position: static
+position-fallback: none
+r: 0px
+resize: none
+right: auto
+rotate: none
+row-gap: normal
+ruby-position: over
+rx: auto
+ry: auto
+scale: none
+scroll-behavior: auto
+scroll-margin-block-end: 0px
+scroll-margin-block-start: 0px
+scroll-margin-inline-end: 0px
+scroll-margin-inline-start: 0px
+scroll-padding-block-end: auto
+scroll-padding-block-start: auto
+scroll-padding-inline-end: auto
+scroll-padding-inline-start: auto
+scroll-timeline-axis: block
+scroll-timeline-name: none
+scrollbar-gutter: auto
+scrollbar-width: auto
+shape-image-threshold: 0
+shape-margin: 0px
+shape-outside: none
+shape-rendering: auto
+speak: normal
+stop-color: rgb(0, 0, 0)
+stop-opacity: 1
+stroke: none
+stroke-dasharray: none
+stroke-dashoffset: 0px
+stroke-linecap: butt
+stroke-linejoin: miter
+stroke-miterlimit: 4
+stroke-opacity: 1
+stroke-width: 1px
+tab-size: 8
+table-layout: auto
+text-align: start
+text-align-last: auto
+text-anchor: start
+text-decoration: none solid rgb(0, 0, 0)
+text-decoration-color: rgb(0, 0, 0)
+text-decoration-line: none
+text-decoration-skip-ink: auto
+text-decoration-style: solid
+text-emphasis-color: rgb(0, 0, 0)
+text-emphasis-position: over
+text-emphasis-style: none
+text-indent: 0px
+text-overflow: clip
+text-rendering: auto
+text-shadow: none
+text-size-adjust: auto
+text-transform: none
+text-underline-position: auto
+toggle-group: none
+toggle-root: none
+toggle-trigger: none
+toggle-visibility: normal
+top: auto
+touch-action: auto
+transform: none
+transform-origin: 50% 50%
+transform-style: flat
+transition-delay: 0s
+transition-duration: 0s
+transition-property: all
+transition-timing-function: ease
+translate: none
+unicode-bidi: normal
+user-select: auto
+vector-effect: none
+vertical-align: baseline
+view-timeline-axis: block
+view-timeline-inset: 0px
+view-timeline-name: none
+visibility: visible
+white-space: normal
+widows: 2
+width: auto
+will-change: auto
+word-break: normal
+word-spacing: 0px
+writing-mode: horizontal-tb
+x: 0px
+y: 0px
+z-index: auto
+zoom: 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/svg/css/getComputedStyle-listing-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/svg/css/getComputedStyle-listing-expected.txt
new file mode 100644
index 0000000..46f8e1a9
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/svg/css/getComputedStyle-listing-expected.txt
@@ -0,0 +1,377 @@
+This test documents all computed styles on an SVG rect element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+-webkit-border-horizontal-spacing: 0px
+-webkit-border-image: none
+-webkit-border-vertical-spacing: 0px
+-webkit-box-align: stretch
+-webkit-box-decoration-break: slice
+-webkit-box-direction: normal
+-webkit-box-flex: 0
+-webkit-box-ordinal-group: 1
+-webkit-box-orient: horizontal
+-webkit-box-pack: start
+-webkit-box-reflect: none
+-webkit-font-smoothing: auto
+-webkit-highlight: none
+-webkit-line-break: auto
+-webkit-line-clamp: none
+-webkit-locale: auto
+-webkit-mask-box-image: none
+-webkit-mask-box-image-outset: 0
+-webkit-mask-box-image-repeat: stretch
+-webkit-mask-box-image-slice: 0 fill
+-webkit-mask-box-image-source: none
+-webkit-mask-box-image-width: auto
+-webkit-mask-clip: border-box
+-webkit-mask-composite: source-over
+-webkit-mask-image: none
+-webkit-mask-origin: border-box
+-webkit-mask-position: 0% 0%
+-webkit-mask-position-x: 0%
+-webkit-mask-position-y: 0%
+-webkit-mask-repeat: repeat
+-webkit-mask-size: auto
+-webkit-print-color-adjust: economy
+-webkit-rtl-ordering: logical
+-webkit-text-combine: none
+-webkit-text-decorations-in-effect: none
+-webkit-text-fill-color: rgb(0, 0, 0)
+-webkit-text-orientation: vertical-right
+-webkit-text-security: none
+-webkit-text-stroke-color: rgb(0, 0, 0)
+-webkit-text-stroke-width: 0px
+-webkit-user-drag: auto
+-webkit-user-modify: read-only
+-webkit-writing-mode: horizontal-tb
+accent-color: auto
+align-content: normal
+align-items: normal
+align-self: auto
+alignment-baseline: auto
+anchor-name: none
+anchor-scroll: none
+animation-delay: 0s
+animation-direction: normal
+animation-duration: 0s
+animation-fill-mode: none
+animation-iteration-count: 1
+animation-name: none
+animation-play-state: running
+animation-timeline: auto
+animation-timing-function: ease
+app-region: none
+appearance: none
+backdrop-filter: none
+backface-visibility: visible
+background-attachment: scroll
+background-blend-mode: normal
+background-clip: border-box
+background-color: rgba(0, 0, 0, 0)
+background-image: none
+background-origin: padding-box
+background-position: 0% 0%
+background-position-x: 0%
+background-position-y: 0%
+background-repeat: repeat
+background-size: auto
+baseline-shift: 0px
+block-size: 100px
+border-block-end-color: rgb(0, 0, 0)
+border-block-end-style: none
+border-block-end-width: 0px
+border-block-start-color: rgb(0, 0, 0)
+border-block-start-style: none
+border-block-start-width: 0px
+border-bottom-color: rgb(0, 0, 0)
+border-bottom-left-radius: 0px
+border-bottom-right-radius: 0px
+border-bottom-style: none
+border-bottom-width: 0px
+border-collapse: separate
+border-end-end-radius: 0px
+border-end-start-radius: 0px
+border-image-outset: 0
+border-image-repeat: stretch
+border-image-slice: 100%
+border-image-source: none
+border-image-width: 1
+border-inline-end-color: rgb(0, 0, 0)
+border-inline-end-style: none
+border-inline-end-width: 0px
+border-inline-start-color: rgb(0, 0, 0)
+border-inline-start-style: none
+border-inline-start-width: 0px
+border-left-color: rgb(0, 0, 0)
+border-left-style: none
+border-left-width: 0px
+border-right-color: rgb(0, 0, 0)
+border-right-style: none
+border-right-width: 0px
+border-spacing: 0px 0px
+border-start-end-radius: 0px
+border-start-start-radius: 0px
+border-top-color: rgb(0, 0, 0)
+border-top-left-radius: 0px
+border-top-right-radius: 0px
+border-top-style: none
+border-top-width: 0px
+bottom: auto
+box-shadow: none
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+buffered-rendering: auto
+caption-side: top
+caret-color: rgb(0, 0, 0)
+clear: none
+clip: auto
+clip-path: none
+clip-rule: nonzero
+color: rgb(0, 0, 0)
+color-interpolation: srgb
+color-interpolation-filters: linearrgb
+color-rendering: auto
+column-count: auto
+column-gap: normal
+column-rule-color: rgb(0, 0, 0)
+column-rule-style: none
+column-rule-width: 0px
+column-span: none
+column-width: auto
+contain-intrinsic-block-size: none
+contain-intrinsic-height: none
+contain-intrinsic-inline-size: none
+contain-intrinsic-size: none
+contain-intrinsic-width: none
+container-name: none
+container-type: normal
+content: normal
+cursor: auto
+cx: 0px
+cy: 0px
+d: none
+direction: ltr
+display: inline
+dominant-baseline: auto
+empty-cells: show
+fill: rgb(0, 128, 0)
+fill-opacity: 1
+fill-rule: nonzero
+filter: none
+flex-basis: auto
+flex-direction: row
+flex-grow: 0
+flex-shrink: 1
+flex-wrap: nowrap
+float: none
+flood-color: rgb(0, 0, 0)
+flood-opacity: 1
+font-kerning: auto
+font-optical-sizing: auto
+font-palette: normal
+font-size: 16px
+font-size-adjust: none
+font-stretch: 100%
+font-style: normal
+font-synthesis-small-caps: auto
+font-synthesis-style: auto
+font-synthesis-weight: auto
+font-variant: normal
+font-variant-caps: normal
+font-variant-east-asian: normal
+font-variant-ligatures: normal
+font-variant-numeric: normal
+font-weight: 400
+grid-auto-columns: auto
+grid-auto-flow: row
+grid-auto-rows: auto
+grid-column-end: auto
+grid-column-start: auto
+grid-row-end: auto
+grid-row-start: auto
+grid-template-areas: none
+grid-template-columns: none
+grid-template-rows: none
+height: 100px
+hyphenate-character: auto
+hyphens: manual
+image-orientation: from-image
+image-rendering: auto
+inline-size: 100px
+inset-block-end: auto
+inset-block-start: auto
+inset-inline-end: auto
+inset-inline-start: auto
+isolation: auto
+justify-content: normal
+justify-items: normal
+justify-self: auto
+left: auto
+letter-spacing: normal
+lighting-color: rgb(255, 255, 255)
+line-break: auto
+line-height: normal
+line-height-step: 0px
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-block-end: 0px
+margin-block-start: 0px
+margin-bottom: 0px
+margin-inline-end: 0px
+margin-inline-start: 0px
+margin-left: 0px
+margin-right: 0px
+margin-top: 0px
+marker-end: none
+marker-mid: none
+marker-start: none
+mask-type: luminance
+math-depth: 0
+math-shift: normal
+math-style: normal
+max-block-size: none
+max-height: none
+max-inline-size: none
+max-width: none
+min-block-size: 0px
+min-height: 0px
+min-inline-size: 0px
+min-width: 0px
+mix-blend-mode: normal
+object-fit: fill
+object-position: 50% 50%
+object-view-box: none
+offset-anchor: auto
+offset-distance: 0px
+offset-path: none
+offset-position: auto
+offset-rotate: auto 0deg
+opacity: 1
+order: 0
+orphans: 2
+outline-color: rgb(0, 0, 0)
+outline-offset: 0px
+outline-style: none
+outline-width: 0px
+overflow: visible
+overflow-anchor: auto
+overflow-block: visible
+overflow-clip-margin: 0px
+overflow-inline: visible
+overflow-wrap: normal
+overflow-x: visible
+overflow-y: visible
+overscroll-behavior-block: auto
+overscroll-behavior-inline: auto
+padding-block-end: 0px
+padding-block-start: 0px
+padding-bottom: 0px
+padding-inline-end: 0px
+padding-inline-start: 0px
+padding-left: 0px
+padding-right: 0px
+padding-top: 0px
+paint-order: normal
+perspective: none
+perspective-origin: 0px 0px
+pointer-events: auto
+position: static
+position-fallback: none
+r: 0px
+resize: none
+right: auto
+rotate: none
+row-gap: normal
+ruby-position: over
+rx: auto
+ry: auto
+scale: none
+scroll-behavior: auto
+scroll-margin-block-end: 0px
+scroll-margin-block-start: 0px
+scroll-margin-inline-end: 0px
+scroll-margin-inline-start: 0px
+scroll-padding-block-end: auto
+scroll-padding-block-start: auto
+scroll-padding-inline-end: auto
+scroll-padding-inline-start: auto
+scroll-timeline-axis: block
+scroll-timeline-name: none
+scrollbar-gutter: auto
+scrollbar-width: auto
+shape-image-threshold: 0
+shape-margin: 0px
+shape-outside: none
+shape-rendering: auto
+speak: normal
+stop-color: rgb(0, 0, 0)
+stop-opacity: 1
+stroke: none
+stroke-dasharray: none
+stroke-dashoffset: 0px
+stroke-linecap: butt
+stroke-linejoin: miter
+stroke-miterlimit: 4
+stroke-opacity: 1
+stroke-width: 1px
+tab-size: 8
+table-layout: auto
+text-align: start
+text-align-last: auto
+text-anchor: start
+text-decoration: none solid rgb(0, 0, 0)
+text-decoration-color: rgb(0, 0, 0)
+text-decoration-line: none
+text-decoration-skip-ink: auto
+text-decoration-style: solid
+text-emphasis-color: rgb(0, 0, 0)
+text-emphasis-position: over
+text-emphasis-style: none
+text-indent: 0px
+text-overflow: clip
+text-rendering: auto
+text-shadow: none
+text-size-adjust: auto
+text-transform: none
+text-underline-position: auto
+toggle-group: none
+toggle-root: none
+toggle-trigger: none
+toggle-visibility: normal
+top: auto
+touch-action: auto
+transform: none
+transform-origin: 0px 0px
+transform-style: flat
+transition-delay: 0s
+transition-duration: 0s
+transition-property: all
+transition-timing-function: ease
+translate: none
+unicode-bidi: normal
+user-select: auto
+vector-effect: none
+vertical-align: baseline
+view-timeline-axis: block
+view-timeline-inset: 0px
+view-timeline-name: none
+visibility: visible
+white-space: normal
+widows: 2
+width: 100px
+will-change: auto
+word-break: normal
+word-spacing: 0px
+writing-mode: horizontal-tb
+x: 0px
+y: 0px
+z-index: auto
+zoom: 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/webexposed/css-properties-as-js-properties-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/webexposed/css-properties-as-js-properties-expected.txt
new file mode 100644
index 0000000..1fc2cf8
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/webexposed/css-properties-as-js-properties-expected.txt
@@ -0,0 +1,631 @@
+This test (crudely) documents Blink's web-exposed CSS properties.  All changes to this list should go through Blink's feature review process: http://www.chromium.org/blink#new-features
+
+
+accentColor
+additiveSymbols
+alignContent
+alignItems
+alignSelf
+alignmentBaseline
+all
+anchorName
+anchorScroll
+animation
+animationDelay
+animationDirection
+animationDuration
+animationFillMode
+animationIterationCount
+animationName
+animationPlayState
+animationTimeline
+animationTimingFunction
+appRegion
+appearance
+ascentOverride
+aspectRatio
+backdropFilter
+backfaceVisibility
+background
+backgroundAttachment
+backgroundBlendMode
+backgroundClip
+backgroundColor
+backgroundImage
+backgroundOrigin
+backgroundPosition
+backgroundPositionX
+backgroundPositionY
+backgroundRepeat
+backgroundRepeatX
+backgroundRepeatY
+backgroundSize
+basePalette
+baselineShift
+blockSize
+border
+borderBlock
+borderBlockColor
+borderBlockEnd
+borderBlockEndColor
+borderBlockEndStyle
+borderBlockEndWidth
+borderBlockStart
+borderBlockStartColor
+borderBlockStartStyle
+borderBlockStartWidth
+borderBlockStyle
+borderBlockWidth
+borderBottom
+borderBottomColor
+borderBottomLeftRadius
+borderBottomRightRadius
+borderBottomStyle
+borderBottomWidth
+borderCollapse
+borderColor
+borderEndEndRadius
+borderEndStartRadius
+borderImage
+borderImageOutset
+borderImageRepeat
+borderImageSlice
+borderImageSource
+borderImageWidth
+borderInline
+borderInlineColor
+borderInlineEnd
+borderInlineEndColor
+borderInlineEndStyle
+borderInlineEndWidth
+borderInlineStart
+borderInlineStartColor
+borderInlineStartStyle
+borderInlineStartWidth
+borderInlineStyle
+borderInlineWidth
+borderLeft
+borderLeftColor
+borderLeftStyle
+borderLeftWidth
+borderRadius
+borderRight
+borderRightColor
+borderRightStyle
+borderRightWidth
+borderSpacing
+borderStartEndRadius
+borderStartStartRadius
+borderStyle
+borderTop
+borderTopColor
+borderTopLeftRadius
+borderTopRightRadius
+borderTopStyle
+borderTopWidth
+borderWidth
+bottom
+boxShadow
+boxSizing
+breakAfter
+breakBefore
+breakInside
+bufferedRendering
+captionSide
+caretColor
+clear
+clip
+clipPath
+clipRule
+color
+colorInterpolation
+colorInterpolationFilters
+colorRendering
+colorScheme
+columnCount
+columnFill
+columnGap
+columnRule
+columnRuleColor
+columnRuleStyle
+columnRuleWidth
+columnSpan
+columnWidth
+columns
+contain
+containIntrinsicBlockSize
+containIntrinsicHeight
+containIntrinsicInlineSize
+containIntrinsicSize
+containIntrinsicWidth
+container
+containerName
+containerType
+content
+contentVisibility
+counterIncrement
+counterReset
+counterSet
+cssFloat
+cssText
+cursor
+cx
+cy
+d
+descentOverride
+direction
+display
+dominantBaseline
+emptyCells
+end
+fallback
+fill
+fillOpacity
+fillRule
+filter
+flex
+flexBasis
+flexDirection
+flexFlow
+flexGrow
+flexShrink
+flexWrap
+float
+floodColor
+floodOpacity
+font
+fontDisplay
+fontFamily
+fontFeatureSettings
+fontKerning
+fontOpticalSizing
+fontPalette
+fontSize
+fontSizeAdjust
+fontStretch
+fontStyle
+fontSynthesis
+fontSynthesisSmallCaps
+fontSynthesisStyle
+fontSynthesisWeight
+fontVariant
+fontVariantCaps
+fontVariantEastAsian
+fontVariantLigatures
+fontVariantNumeric
+fontVariationSettings
+fontWeight
+forcedColorAdjust
+gap
+getPropertyPriority
+getPropertyValue
+grid
+gridArea
+gridAutoColumns
+gridAutoFlow
+gridAutoRows
+gridColumn
+gridColumnEnd
+gridColumnGap
+gridColumnStart
+gridGap
+gridRow
+gridRowEnd
+gridRowGap
+gridRowStart
+gridTemplate
+gridTemplateAreas
+gridTemplateColumns
+gridTemplateRows
+height
+hyphenateCharacter
+hyphens
+imageOrientation
+imageRendering
+inherits
+initialValue
+inlineSize
+inset
+insetBlock
+insetBlockEnd
+insetBlockStart
+insetInline
+insetInlineEnd
+insetInlineStart
+isolation
+item
+justifyContent
+justifyItems
+justifySelf
+left
+length
+letterSpacing
+lightingColor
+lineBreak
+lineGapOverride
+lineHeight
+lineHeightStep
+listStyle
+listStyleImage
+listStylePosition
+listStyleType
+margin
+marginBlock
+marginBlockEnd
+marginBlockStart
+marginBottom
+marginInline
+marginInlineEnd
+marginInlineStart
+marginLeft
+marginRight
+marginTop
+marker
+markerEnd
+markerMid
+markerStart
+mask
+maskType
+mathDepth
+mathShift
+mathStyle
+maxBlockSize
+maxHeight
+maxInlineSize
+maxWidth
+minBlockSize
+minHeight
+minInlineSize
+minWidth
+mixBlendMode
+negative
+objectFit
+objectPosition
+objectViewBox
+offset
+offsetAnchor
+offsetDistance
+offsetPath
+offsetPosition
+offsetRotate
+opacity
+order
+orphans
+outline
+outlineColor
+outlineOffset
+outlineStyle
+outlineWidth
+overflow
+overflowAnchor
+overflowBlock
+overflowClipMargin
+overflowInline
+overflowWrap
+overflowX
+overflowY
+overrideColors
+overscrollBehavior
+overscrollBehaviorBlock
+overscrollBehaviorInline
+overscrollBehaviorX
+overscrollBehaviorY
+pad
+padding
+paddingBlock
+paddingBlockEnd
+paddingBlockStart
+paddingBottom
+paddingInline
+paddingInlineEnd
+paddingInlineStart
+paddingLeft
+paddingRight
+paddingTop
+page
+pageBreakAfter
+pageBreakBefore
+pageBreakInside
+pageOrientation
+paintOrder
+parentRule
+perspective
+perspectiveOrigin
+placeContent
+placeItems
+placeSelf
+pointerEvents
+position
+positionFallback
+prefix
+quotes
+r
+range
+removeProperty
+resize
+right
+rotate
+rowGap
+rubyPosition
+rx
+ry
+scale
+scrollBehavior
+scrollMargin
+scrollMarginBlock
+scrollMarginBlockEnd
+scrollMarginBlockStart
+scrollMarginBottom
+scrollMarginInline
+scrollMarginInlineEnd
+scrollMarginInlineStart
+scrollMarginLeft
+scrollMarginRight
+scrollMarginTop
+scrollPadding
+scrollPaddingBlock
+scrollPaddingBlockEnd
+scrollPaddingBlockStart
+scrollPaddingBottom
+scrollPaddingInline
+scrollPaddingInlineEnd
+scrollPaddingInlineStart
+scrollPaddingLeft
+scrollPaddingRight
+scrollPaddingTop
+scrollSnapAlign
+scrollSnapStop
+scrollSnapType
+scrollTimeline
+scrollTimelineAxis
+scrollTimelineName
+scrollbarGutter
+scrollbarWidth
+setProperty
+shapeImageThreshold
+shapeMargin
+shapeOutside
+shapeRendering
+size
+sizeAdjust
+source
+speak
+speakAs
+src
+start
+stopColor
+stopOpacity
+stroke
+strokeDasharray
+strokeDashoffset
+strokeLinecap
+strokeLinejoin
+strokeMiterlimit
+strokeOpacity
+strokeWidth
+suffix
+symbols
+syntax
+system
+tabSize
+tableLayout
+textAlign
+textAlignLast
+textAnchor
+textCombineUpright
+textDecoration
+textDecorationColor
+textDecorationLine
+textDecorationSkipInk
+textDecorationStyle
+textDecorationThickness
+textEmphasis
+textEmphasisColor
+textEmphasisPosition
+textEmphasisStyle
+textIndent
+textOrientation
+textOverflow
+textRendering
+textShadow
+textSizeAdjust
+textTransform
+textUnderlineOffset
+textUnderlinePosition
+toggle
+toggleGroup
+toggleRoot
+toggleTrigger
+toggleVisibility
+top
+touchAction
+transform
+transformBox
+transformOrigin
+transformStyle
+transition
+transitionDelay
+transitionDuration
+transitionProperty
+transitionTimingFunction
+translate
+unicodeBidi
+unicodeRange
+userSelect
+vectorEffect
+verticalAlign
+viewTimeline
+viewTimelineAxis
+viewTimelineInset
+viewTimelineName
+visibility
+webkitAlignContent
+webkitAlignItems
+webkitAlignSelf
+webkitAnimation
+webkitAnimationDelay
+webkitAnimationDirection
+webkitAnimationDuration
+webkitAnimationFillMode
+webkitAnimationIterationCount
+webkitAnimationName
+webkitAnimationPlayState
+webkitAnimationTimingFunction
+webkitAppRegion
+webkitAppearance
+webkitBackfaceVisibility
+webkitBackgroundClip
+webkitBackgroundOrigin
+webkitBackgroundSize
+webkitBorderAfter
+webkitBorderAfterColor
+webkitBorderAfterStyle
+webkitBorderAfterWidth
+webkitBorderBefore
+webkitBorderBeforeColor
+webkitBorderBeforeStyle
+webkitBorderBeforeWidth
+webkitBorderBottomLeftRadius
+webkitBorderBottomRightRadius
+webkitBorderEnd
+webkitBorderEndColor
+webkitBorderEndStyle
+webkitBorderEndWidth
+webkitBorderHorizontalSpacing
+webkitBorderImage
+webkitBorderRadius
+webkitBorderStart
+webkitBorderStartColor
+webkitBorderStartStyle
+webkitBorderStartWidth
+webkitBorderTopLeftRadius
+webkitBorderTopRightRadius
+webkitBorderVerticalSpacing
+webkitBoxAlign
+webkitBoxDecorationBreak
+webkitBoxDirection
+webkitBoxFlex
+webkitBoxOrdinalGroup
+webkitBoxOrient
+webkitBoxPack
+webkitBoxReflect
+webkitBoxShadow
+webkitBoxSizing
+webkitClipPath
+webkitColumnBreakAfter
+webkitColumnBreakBefore
+webkitColumnBreakInside
+webkitColumnCount
+webkitColumnGap
+webkitColumnRule
+webkitColumnRuleColor
+webkitColumnRuleStyle
+webkitColumnRuleWidth
+webkitColumnSpan
+webkitColumnWidth
+webkitColumns
+webkitFilter
+webkitFlex
+webkitFlexBasis
+webkitFlexDirection
+webkitFlexFlow
+webkitFlexGrow
+webkitFlexShrink
+webkitFlexWrap
+webkitFontFeatureSettings
+webkitFontSmoothing
+webkitHighlight
+webkitHyphenateCharacter
+webkitJustifyContent
+webkitLineBreak
+webkitLineClamp
+webkitLocale
+webkitLogicalHeight
+webkitLogicalWidth
+webkitMarginAfter
+webkitMarginBefore
+webkitMarginEnd
+webkitMarginStart
+webkitMask
+webkitMaskBoxImage
+webkitMaskBoxImageOutset
+webkitMaskBoxImageRepeat
+webkitMaskBoxImageSlice
+webkitMaskBoxImageSource
+webkitMaskBoxImageWidth
+webkitMaskClip
+webkitMaskComposite
+webkitMaskImage
+webkitMaskOrigin
+webkitMaskPosition
+webkitMaskPositionX
+webkitMaskPositionY
+webkitMaskRepeat
+webkitMaskRepeatX
+webkitMaskRepeatY
+webkitMaskSize
+webkitMaxLogicalHeight
+webkitMaxLogicalWidth
+webkitMinLogicalHeight
+webkitMinLogicalWidth
+webkitOpacity
+webkitOrder
+webkitPaddingAfter
+webkitPaddingBefore
+webkitPaddingEnd
+webkitPaddingStart
+webkitPerspective
+webkitPerspectiveOrigin
+webkitPerspectiveOriginX
+webkitPerspectiveOriginY
+webkitPrintColorAdjust
+webkitRtlOrdering
+webkitRubyPosition
+webkitShapeImageThreshold
+webkitShapeMargin
+webkitShapeOutside
+webkitTapHighlightColor
+webkitTextCombine
+webkitTextDecorationsInEffect
+webkitTextEmphasis
+webkitTextEmphasisColor
+webkitTextEmphasisPosition
+webkitTextEmphasisStyle
+webkitTextFillColor
+webkitTextOrientation
+webkitTextSecurity
+webkitTextSizeAdjust
+webkitTextStroke
+webkitTextStrokeColor
+webkitTextStrokeWidth
+webkitTransform
+webkitTransformOrigin
+webkitTransformOriginX
+webkitTransformOriginY
+webkitTransformOriginZ
+webkitTransformStyle
+webkitTransition
+webkitTransitionDelay
+webkitTransitionDuration
+webkitTransitionProperty
+webkitTransitionTimingFunction
+webkitUserDrag
+webkitUserModify
+webkitUserSelect
+webkitWritingMode
+whiteSpace
+widows
+width
+willChange
+wordBreak
+wordSpacing
+wordWrap
+writingMode
+x
+y
+zIndex
+zoom
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/webexposed/css-property-listing-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/webexposed/css-property-listing-expected.txt
new file mode 100644
index 0000000..08614c3
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/webexposed/css-property-listing-expected.txt
@@ -0,0 +1,985 @@
+This test documents Blink's web-exposed CSS properties.
+All changes to this list should go through Blink's feature review process: http://www.chromium.org/blink#new-features
+
+[LONGHANDS]
+    -webkit-border-horizontal-spacing
+    -webkit-border-image
+    -webkit-border-vertical-spacing
+    -webkit-box-align
+    -webkit-box-decoration-break
+    -webkit-box-direction
+    -webkit-box-flex
+    -webkit-box-ordinal-group
+    -webkit-box-orient
+    -webkit-box-pack
+    -webkit-box-reflect
+    -webkit-font-smoothing
+    -webkit-highlight
+    -webkit-line-break
+    -webkit-line-clamp
+    -webkit-locale
+    -webkit-mask-box-image-outset
+    -webkit-mask-box-image-repeat
+    -webkit-mask-box-image-slice
+    -webkit-mask-box-image-source
+    -webkit-mask-box-image-width
+    -webkit-mask-clip
+    -webkit-mask-composite
+    -webkit-mask-image
+    -webkit-mask-origin
+    -webkit-mask-position-x
+    -webkit-mask-position-y
+    -webkit-mask-repeat-x
+    -webkit-mask-repeat-y
+    -webkit-mask-size
+    -webkit-perspective-origin-x
+    -webkit-perspective-origin-y
+    -webkit-print-color-adjust
+    -webkit-rtl-ordering
+    -webkit-ruby-position
+    -webkit-tap-highlight-color
+    -webkit-text-combine
+    -webkit-text-decorations-in-effect
+    -webkit-text-fill-color
+    -webkit-text-orientation
+    -webkit-text-security
+    -webkit-text-stroke-color
+    -webkit-text-stroke-width
+    -webkit-transform-origin-x
+    -webkit-transform-origin-y
+    -webkit-transform-origin-z
+    -webkit-user-drag
+    -webkit-user-modify
+    -webkit-writing-mode
+    accent-color
+    align-content
+    align-items
+    align-self
+    alignment-baseline
+    all
+    anchor-name
+    anchor-scroll
+    animation-delay
+    animation-direction
+    animation-duration
+    animation-fill-mode
+    animation-iteration-count
+    animation-name
+    animation-play-state
+    animation-timeline
+    animation-timing-function
+    app-region
+    appearance
+    aspect-ratio
+    backdrop-filter
+    backface-visibility
+    background-attachment
+    background-blend-mode
+    background-clip
+    background-color
+    background-image
+    background-origin
+    background-position-x
+    background-position-y
+    background-repeat-x
+    background-repeat-y
+    background-size
+    baseline-shift
+    block-size
+    border-block-end-color
+    border-block-end-style
+    border-block-end-width
+    border-block-start-color
+    border-block-start-style
+    border-block-start-width
+    border-bottom-color
+    border-bottom-left-radius
+    border-bottom-right-radius
+    border-bottom-style
+    border-bottom-width
+    border-collapse
+    border-end-end-radius
+    border-end-start-radius
+    border-image-outset
+    border-image-repeat
+    border-image-slice
+    border-image-source
+    border-image-width
+    border-inline-end-color
+    border-inline-end-style
+    border-inline-end-width
+    border-inline-start-color
+    border-inline-start-style
+    border-inline-start-width
+    border-left-color
+    border-left-style
+    border-left-width
+    border-right-color
+    border-right-style
+    border-right-width
+    border-start-end-radius
+    border-start-start-radius
+    border-top-color
+    border-top-left-radius
+    border-top-right-radius
+    border-top-style
+    border-top-width
+    bottom
+    box-shadow
+    box-sizing
+    break-after
+    break-before
+    break-inside
+    buffered-rendering
+    caption-side
+    caret-color
+    clear
+    clip
+    clip-path
+    clip-rule
+    color
+    color-interpolation
+    color-interpolation-filters
+    color-rendering
+    color-scheme
+    column-count
+    column-fill
+    column-gap
+    column-rule-color
+    column-rule-style
+    column-rule-width
+    column-span
+    column-width
+    contain
+    contain-intrinsic-block-size
+    contain-intrinsic-height
+    contain-intrinsic-inline-size
+    contain-intrinsic-width
+    container-name
+    container-type
+    content
+    content-visibility
+    counter-increment
+    counter-reset
+    counter-set
+    cursor
+    cx
+    cy
+    d
+    direction
+    display
+    dominant-baseline
+    empty-cells
+    fill
+    fill-opacity
+    fill-rule
+    filter
+    flex-basis
+    flex-direction
+    flex-grow
+    flex-shrink
+    flex-wrap
+    float
+    flood-color
+    flood-opacity
+    font-family
+    font-feature-settings
+    font-kerning
+    font-optical-sizing
+    font-palette
+    font-size
+    font-size-adjust
+    font-stretch
+    font-style
+    font-synthesis-small-caps
+    font-synthesis-style
+    font-synthesis-weight
+    font-variant-caps
+    font-variant-east-asian
+    font-variant-ligatures
+    font-variant-numeric
+    font-variation-settings
+    font-weight
+    forced-color-adjust
+    grid-auto-columns
+    grid-auto-flow
+    grid-auto-rows
+    grid-column-end
+    grid-column-start
+    grid-row-end
+    grid-row-start
+    grid-template-areas
+    grid-template-columns
+    grid-template-rows
+    height
+    hyphenate-character
+    hyphens
+    image-orientation
+    image-rendering
+    inline-size
+    inset-block-end
+    inset-block-start
+    inset-inline-end
+    inset-inline-start
+    isolation
+    justify-content
+    justify-items
+    justify-self
+    left
+    letter-spacing
+    lighting-color
+    line-break
+    line-height
+    line-height-step
+    list-style-image
+    list-style-position
+    list-style-type
+    margin-block-end
+    margin-block-start
+    margin-bottom
+    margin-inline-end
+    margin-inline-start
+    margin-left
+    margin-right
+    margin-top
+    marker-end
+    marker-mid
+    marker-start
+    mask
+    mask-type
+    math-depth
+    math-shift
+    math-style
+    max-block-size
+    max-height
+    max-inline-size
+    max-width
+    min-block-size
+    min-height
+    min-inline-size
+    min-width
+    mix-blend-mode
+    object-fit
+    object-position
+    object-view-box
+    offset-anchor
+    offset-distance
+    offset-path
+    offset-position
+    offset-rotate
+    opacity
+    order
+    orphans
+    outline-color
+    outline-offset
+    outline-style
+    outline-width
+    overflow-anchor
+    overflow-block
+    overflow-clip-margin
+    overflow-inline
+    overflow-wrap
+    overflow-x
+    overflow-y
+    overscroll-behavior-block
+    overscroll-behavior-inline
+    overscroll-behavior-x
+    overscroll-behavior-y
+    padding-block-end
+    padding-block-start
+    padding-bottom
+    padding-inline-end
+    padding-inline-start
+    padding-left
+    padding-right
+    padding-top
+    page
+    page-orientation
+    paint-order
+    perspective
+    perspective-origin
+    pointer-events
+    position
+    position-fallback
+    quotes
+    r
+    resize
+    right
+    rotate
+    row-gap
+    ruby-position
+    rx
+    ry
+    scale
+    scroll-behavior
+    scroll-margin-block-end
+    scroll-margin-block-start
+    scroll-margin-bottom
+    scroll-margin-inline-end
+    scroll-margin-inline-start
+    scroll-margin-left
+    scroll-margin-right
+    scroll-margin-top
+    scroll-padding-block-end
+    scroll-padding-block-start
+    scroll-padding-bottom
+    scroll-padding-inline-end
+    scroll-padding-inline-start
+    scroll-padding-left
+    scroll-padding-right
+    scroll-padding-top
+    scroll-snap-align
+    scroll-snap-stop
+    scroll-snap-type
+    scroll-timeline-axis
+    scroll-timeline-name
+    scrollbar-gutter
+    scrollbar-width
+    shape-image-threshold
+    shape-margin
+    shape-outside
+    shape-rendering
+    size
+    speak
+    stop-color
+    stop-opacity
+    stroke
+    stroke-dasharray
+    stroke-dashoffset
+    stroke-linecap
+    stroke-linejoin
+    stroke-miterlimit
+    stroke-opacity
+    stroke-width
+    tab-size
+    table-layout
+    text-align
+    text-align-last
+    text-anchor
+    text-combine-upright
+    text-decoration-color
+    text-decoration-line
+    text-decoration-skip-ink
+    text-decoration-style
+    text-decoration-thickness
+    text-emphasis-color
+    text-emphasis-position
+    text-emphasis-style
+    text-indent
+    text-orientation
+    text-overflow
+    text-rendering
+    text-shadow
+    text-size-adjust
+    text-transform
+    text-underline-offset
+    text-underline-position
+    toggle-group
+    toggle-root
+    toggle-trigger
+    toggle-visibility
+    top
+    touch-action
+    transform
+    transform-box
+    transform-origin
+    transform-style
+    transition-delay
+    transition-duration
+    transition-property
+    transition-timing-function
+    translate
+    unicode-bidi
+    user-select
+    vector-effect
+    vertical-align
+    view-timeline-axis
+    view-timeline-inset
+    view-timeline-name
+    visibility
+    white-space
+    widows
+    width
+    will-change
+    word-break
+    word-spacing
+    writing-mode
+    x
+    y
+    z-index
+    zoom
+
+[SHORTHANDS]
+    -webkit-column-break-after
+        break-after
+    -webkit-column-break-before
+        break-before
+    -webkit-column-break-inside
+        break-inside
+    -webkit-mask
+        -webkit-mask-clip
+        -webkit-mask-image
+        -webkit-mask-origin
+        -webkit-mask-position-x
+        -webkit-mask-position-y
+        -webkit-mask-repeat-x
+        -webkit-mask-repeat-y
+        -webkit-mask-size
+    -webkit-mask-box-image
+        -webkit-mask-box-image-outset
+        -webkit-mask-box-image-repeat
+        -webkit-mask-box-image-slice
+        -webkit-mask-box-image-source
+        -webkit-mask-box-image-width
+    -webkit-mask-position
+        -webkit-mask-position-x
+        -webkit-mask-position-y
+    -webkit-mask-repeat
+        -webkit-mask-repeat-x
+        -webkit-mask-repeat-y
+    -webkit-text-stroke
+        -webkit-text-stroke-color
+        -webkit-text-stroke-width
+    animation
+        animation-delay
+        animation-direction
+        animation-duration
+        animation-fill-mode
+        animation-iteration-count
+        animation-name
+        animation-play-state
+        animation-timeline
+        animation-timing-function
+    background
+        background-attachment
+        background-clip
+        background-color
+        background-image
+        background-origin
+        background-position-x
+        background-position-y
+        background-repeat-x
+        background-repeat-y
+        background-size
+    background-position
+        background-position-x
+        background-position-y
+    background-repeat
+        background-repeat-x
+        background-repeat-y
+    border
+        border-bottom-color
+        border-bottom-style
+        border-bottom-width
+        border-image-outset
+        border-image-repeat
+        border-image-slice
+        border-image-source
+        border-image-width
+        border-left-color
+        border-left-style
+        border-left-width
+        border-right-color
+        border-right-style
+        border-right-width
+        border-top-color
+        border-top-style
+        border-top-width
+    border-block
+        border-block-end-color
+        border-block-end-style
+        border-block-end-width
+        border-block-start-color
+        border-block-start-style
+        border-block-start-width
+    border-block-color
+        border-block-end-color
+        border-block-start-color
+    border-block-end
+        border-block-end-color
+        border-block-end-style
+        border-block-end-width
+    border-block-start
+        border-block-start-color
+        border-block-start-style
+        border-block-start-width
+    border-block-style
+        border-block-end-style
+        border-block-start-style
+    border-block-width
+        border-block-end-width
+        border-block-start-width
+    border-bottom
+        border-bottom-color
+        border-bottom-style
+        border-bottom-width
+    border-color
+        border-bottom-color
+        border-left-color
+        border-right-color
+        border-top-color
+    border-image
+        border-image-outset
+        border-image-repeat
+        border-image-slice
+        border-image-source
+        border-image-width
+    border-inline
+        border-inline-end-color
+        border-inline-end-style
+        border-inline-end-width
+        border-inline-start-color
+        border-inline-start-style
+        border-inline-start-width
+    border-inline-color
+        border-inline-end-color
+        border-inline-start-color
+    border-inline-end
+        border-inline-end-color
+        border-inline-end-style
+        border-inline-end-width
+    border-inline-start
+        border-inline-start-color
+        border-inline-start-style
+        border-inline-start-width
+    border-inline-style
+        border-inline-end-style
+        border-inline-start-style
+    border-inline-width
+        border-inline-end-width
+        border-inline-start-width
+    border-left
+        border-left-color
+        border-left-style
+        border-left-width
+    border-radius
+        border-bottom-left-radius
+        border-bottom-right-radius
+        border-top-left-radius
+        border-top-right-radius
+    border-right
+        border-right-color
+        border-right-style
+        border-right-width
+    border-spacing
+        -webkit-border-horizontal-spacing
+        -webkit-border-vertical-spacing
+    border-style
+        border-bottom-style
+        border-left-style
+        border-right-style
+        border-top-style
+    border-top
+        border-top-color
+        border-top-style
+        border-top-width
+    border-width
+        border-bottom-width
+        border-left-width
+        border-right-width
+        border-top-width
+    column-rule
+        column-rule-color
+        column-rule-style
+        column-rule-width
+    columns
+        column-count
+        column-width
+    contain-intrinsic-size
+        contain-intrinsic-height
+        contain-intrinsic-width
+    container
+        container-name
+        container-type
+    flex
+        flex-basis
+        flex-grow
+        flex-shrink
+    flex-flow
+        flex-direction
+        flex-wrap
+    font
+        font-family
+        font-size
+        font-stretch
+        font-style
+        font-variant-caps
+        font-variant-east-asian
+        font-variant-ligatures
+        font-variant-numeric
+        font-weight
+        line-height
+    font-synthesis
+        font-synthesis-small-caps
+        font-synthesis-style
+        font-synthesis-weight
+    font-variant
+        font-variant-caps
+        font-variant-east-asian
+        font-variant-ligatures
+        font-variant-numeric
+    gap
+        column-gap
+        row-gap
+    grid
+        grid-auto-columns
+        grid-auto-flow
+        grid-auto-rows
+        grid-template-areas
+        grid-template-columns
+        grid-template-rows
+    grid-area
+        grid-column-end
+        grid-column-start
+        grid-row-end
+        grid-row-start
+    grid-column
+        grid-column-end
+        grid-column-start
+    grid-column-gap
+        column-gap
+    grid-gap
+        column-gap
+        row-gap
+    grid-row
+        grid-row-end
+        grid-row-start
+    grid-row-gap
+        row-gap
+    grid-template
+        grid-template-areas
+        grid-template-columns
+        grid-template-rows
+    inset
+        bottom
+        left
+        right
+        top
+    inset-block
+        inset-block-end
+        inset-block-start
+    inset-inline
+        inset-inline-end
+        inset-inline-start
+    list-style
+        list-style-image
+        list-style-position
+        list-style-type
+    margin
+        margin-bottom
+        margin-left
+        margin-right
+        margin-top
+    margin-block
+        margin-block-end
+        margin-block-start
+    margin-inline
+        margin-inline-end
+        margin-inline-start
+    marker
+        marker-end
+        marker-mid
+        marker-start
+    offset
+        offset-anchor
+        offset-distance
+        offset-path
+        offset-position
+        offset-rotate
+    outline
+        outline-color
+        outline-style
+        outline-width
+    overflow
+        overflow-x
+        overflow-y
+    overscroll-behavior
+        overscroll-behavior-x
+        overscroll-behavior-y
+    padding
+        padding-bottom
+        padding-left
+        padding-right
+        padding-top
+    padding-block
+        padding-block-end
+        padding-block-start
+    padding-inline
+        padding-inline-end
+        padding-inline-start
+    page-break-after
+        break-after
+    page-break-before
+        break-before
+    page-break-inside
+        break-inside
+    place-content
+        align-content
+        justify-content
+    place-items
+        align-items
+        justify-items
+    place-self
+        align-self
+        justify-self
+    scroll-margin
+        scroll-margin-bottom
+        scroll-margin-left
+        scroll-margin-right
+        scroll-margin-top
+    scroll-margin-block
+        scroll-margin-block-end
+        scroll-margin-block-start
+    scroll-margin-inline
+        scroll-margin-inline-end
+        scroll-margin-inline-start
+    scroll-padding
+        scroll-padding-bottom
+        scroll-padding-left
+        scroll-padding-right
+        scroll-padding-top
+    scroll-padding-block
+        scroll-padding-block-end
+        scroll-padding-block-start
+    scroll-padding-inline
+        scroll-padding-inline-end
+        scroll-padding-inline-start
+    scroll-timeline
+        scroll-timeline-axis
+        scroll-timeline-name
+    text-decoration
+        text-decoration-color
+        text-decoration-line
+        text-decoration-style
+        text-decoration-thickness
+    text-emphasis
+        text-emphasis-color
+        text-emphasis-style
+    toggle
+        toggle-root
+        toggle-trigger
+    transition
+        transition-delay
+        transition-duration
+        transition-property
+        transition-timing-function
+    view-timeline
+        view-timeline-axis
+        view-timeline-name
+
+[ALIASES]
+    -epub-caption-side
+        caption-side
+    -epub-text-combine
+        -webkit-text-combine
+    -epub-text-emphasis
+        text-emphasis
+    -epub-text-emphasis-color
+        text-emphasis-color
+    -epub-text-emphasis-style
+        text-emphasis-style
+    -epub-text-orientation
+        -webkit-text-orientation
+    -epub-text-transform
+        text-transform
+    -epub-word-break
+        word-break
+    -epub-writing-mode
+        -webkit-writing-mode
+    -webkit-align-content
+        align-content
+    -webkit-align-items
+        align-items
+    -webkit-align-self
+        align-self
+    -webkit-animation
+        animation
+    -webkit-animation-delay
+        animation-delay
+    -webkit-animation-direction
+        animation-direction
+    -webkit-animation-duration
+        animation-duration
+    -webkit-animation-fill-mode
+        animation-fill-mode
+    -webkit-animation-iteration-count
+        animation-iteration-count
+    -webkit-animation-name
+        animation-name
+    -webkit-animation-play-state
+        animation-play-state
+    -webkit-animation-timing-function
+        animation-timing-function
+    -webkit-app-region
+        app-region
+    -webkit-appearance
+        appearance
+    -webkit-backface-visibility
+        backface-visibility
+    -webkit-background-clip
+        background-clip
+    -webkit-background-origin
+        background-origin
+    -webkit-background-size
+        background-size
+    -webkit-border-after
+        border-block-end
+    -webkit-border-after-color
+        border-block-end-color
+    -webkit-border-after-style
+        border-block-end-style
+    -webkit-border-after-width
+        border-block-end-width
+    -webkit-border-before
+        border-block-start
+    -webkit-border-before-color
+        border-block-start-color
+    -webkit-border-before-style
+        border-block-start-style
+    -webkit-border-before-width
+        border-block-start-width
+    -webkit-border-bottom-left-radius
+        border-bottom-left-radius
+    -webkit-border-bottom-right-radius
+        border-bottom-right-radius
+    -webkit-border-end
+        border-inline-end
+    -webkit-border-end-color
+        border-inline-end-color
+    -webkit-border-end-style
+        border-inline-end-style
+    -webkit-border-end-width
+        border-inline-end-width
+    -webkit-border-radius
+        border-radius
+    -webkit-border-start
+        border-inline-start
+    -webkit-border-start-color
+        border-inline-start-color
+    -webkit-border-start-style
+        border-inline-start-style
+    -webkit-border-start-width
+        border-inline-start-width
+    -webkit-border-top-left-radius
+        border-top-left-radius
+    -webkit-border-top-right-radius
+        border-top-right-radius
+    -webkit-box-shadow
+        box-shadow
+    -webkit-box-sizing
+        box-sizing
+    -webkit-clip-path
+        clip-path
+    -webkit-column-count
+        column-count
+    -webkit-column-gap
+        column-gap
+    -webkit-column-rule
+        column-rule
+    -webkit-column-rule-color
+        column-rule-color
+    -webkit-column-rule-style
+        column-rule-style
+    -webkit-column-rule-width
+        column-rule-width
+    -webkit-column-span
+        column-span
+    -webkit-column-width
+        column-width
+    -webkit-columns
+        columns
+    -webkit-filter
+        filter
+    -webkit-flex
+        flex
+    -webkit-flex-basis
+        flex-basis
+    -webkit-flex-direction
+        flex-direction
+    -webkit-flex-flow
+        flex-flow
+    -webkit-flex-grow
+        flex-grow
+    -webkit-flex-shrink
+        flex-shrink
+    -webkit-flex-wrap
+        flex-wrap
+    -webkit-font-feature-settings
+        font-feature-settings
+    -webkit-hyphenate-character
+        hyphenate-character
+    -webkit-justify-content
+        justify-content
+    -webkit-logical-height
+        block-size
+    -webkit-logical-width
+        inline-size
+    -webkit-margin-after
+        margin-block-end
+    -webkit-margin-before
+        margin-block-start
+    -webkit-margin-end
+        margin-inline-end
+    -webkit-margin-start
+        margin-inline-start
+    -webkit-max-logical-height
+        max-block-size
+    -webkit-max-logical-width
+        max-inline-size
+    -webkit-min-logical-height
+        min-block-size
+    -webkit-min-logical-width
+        min-inline-size
+    -webkit-opacity
+        opacity
+    -webkit-order
+        order
+    -webkit-padding-after
+        padding-block-end
+    -webkit-padding-before
+        padding-block-start
+    -webkit-padding-end
+        padding-inline-end
+    -webkit-padding-start
+        padding-inline-start
+    -webkit-perspective
+        perspective
+    -webkit-perspective-origin
+        perspective-origin
+    -webkit-shape-image-threshold
+        shape-image-threshold
+    -webkit-shape-margin
+        shape-margin
+    -webkit-shape-outside
+        shape-outside
+    -webkit-text-emphasis
+        text-emphasis
+    -webkit-text-emphasis-color
+        text-emphasis-color
+    -webkit-text-emphasis-position
+        text-emphasis-position
+    -webkit-text-emphasis-style
+        text-emphasis-style
+    -webkit-text-size-adjust
+        text-size-adjust
+    -webkit-transform
+        transform
+    -webkit-transform-origin
+        transform-origin
+    -webkit-transform-style
+        transform-style
+    -webkit-transition
+        transition
+    -webkit-transition-delay
+        transition-delay
+    -webkit-transition-duration
+        transition-duration
+    -webkit-transition-property
+        transition-property
+    -webkit-transition-timing-function
+        transition-timing-function
+    -webkit-user-select
+        user-select
+    word-wrap
+        overflow-wrap
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
deleted file mode 100644
index dac5646..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
-PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#OK"
-FAIL permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute. assert_equals: expected "#OK" but got "#Error"
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#OK"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt
deleted file mode 100644
index 0e83229..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Default "display-capture" permissions policy ["self"] allows the top-level document. promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio only requests are not supported"
-FAIL Default "display-capture" permissions policy ["self"] allows same-origin iframes. assert_equals: expected "#OK" but got "#TypeError"
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#TypeError"
-FAIL permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute. assert_equals: expected "#OK" but got "#TypeError"
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#TypeError"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt
deleted file mode 100644
index 36bc1d2..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
-PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#Error"
-FAIL permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute. assert_equals: expected "#OK" but got "#Error"
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#OK"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt
deleted file mode 100644
index c18144b..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/screen-capture/permissions-policy-audio.https.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Default "display-capture" permissions policy ["self"] allows the top-level document. promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio only requests are not supported"
-FAIL Default "display-capture" permissions policy ["self"] allows same-origin iframes. assert_equals: expected "#OK" but got "#TypeError"
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#Error"
-FAIL permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute. assert_equals: expected "#OK" but got "#TypeError"
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#TypeError"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt
deleted file mode 100644
index 669a9527..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
-PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#OK"
-PASS permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute.
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#OK"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
deleted file mode 100644
index 669a9527..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
-PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#OK"
-PASS permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute.
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#OK"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt
deleted file mode 100644
index 36bc1d2..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/screen-capture/permissions-policy-video.https.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
-PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#Error"
-FAIL permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute. assert_equals: expected "#OK" but got "#Error"
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#OK"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
deleted file mode 100644
index 96e5c607..0000000
--- a/third_party/blink/web_tests/platform/mac/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
-PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#Error"
-PASS permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute.
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#OK"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
deleted file mode 100644
index 669a9527..0000000
--- a/third_party/blink/web_tests/platform/win/external/wpt/screen-capture/permissions-policy-audio+video.https.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Default "display-capture" permissions policy ["self"] allows the top-level document.
-PASS Default "display-capture" permissions policy ["self"] allows same-origin iframes.
-FAIL Default "display-capture" permissions policy ["self"] disallows cross-origin iframes. assert_equals: expected "#NotAllowedError" but got "#OK"
-PASS permissions policy "display-capture" can be enabled in cross-origin iframes using "allow" attribute.
-FAIL permissions policy "display-capture" can be disabled in same-origin iframes using "allow" attribute. assert_equals: expected "#NotAllowedError" but got "#OK"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt b/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt
index 46f8e1a9..a6bea8a 100644
--- a/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt
+++ b/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt
@@ -200,6 +200,7 @@
 hyphens: manual
 image-orientation: from-image
 image-rendering: auto
+initial-letter: normal
 inline-size: 100px
 inset-block-end: auto
 inset-block-start: auto
diff --git a/third_party/blink/web_tests/virtual/not-restored-reasons/README.md b/third_party/blink/web_tests/virtual/not-restored-reasons/README.md
deleted file mode 100644
index 2437ad1..0000000
--- a/third_party/blink/web_tests/virtual/not-restored-reasons/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Virtual Tests for BackForwardCache NotRestoredReasons
-
-This folder contains virtual test suites to cover NotRestoredReasons feature.
-
-The suite runs `external/wpt/performance-timeline/not-restored-reasons/` with `--enable-features=BackForwardCacheSendNotRestoredReasons`.
-
-To manually run the suites, use the following command:
-
-```bash
-third_party/blink/tools/run_web_tests.py -t Default virtual/not-restored-reasons/external/wpt/performance-timeline/not-restored-reasons/
-```
\ No newline at end of file
diff --git a/third_party/blink/web_tests/virtual/not-restored-reasons/external/wpt/performance-timeline/not-restored-reasons/README.txt b/third_party/blink/web_tests/virtual/not-restored-reasons/external/wpt/performance-timeline/not-restored-reasons/README.txt
deleted file mode 100644
index 2437ad1..0000000
--- a/third_party/blink/web_tests/virtual/not-restored-reasons/external/wpt/performance-timeline/not-restored-reasons/README.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-# Virtual Tests for BackForwardCache NotRestoredReasons
-
-This folder contains virtual test suites to cover NotRestoredReasons feature.
-
-The suite runs `external/wpt/performance-timeline/not-restored-reasons/` with `--enable-features=BackForwardCacheSendNotRestoredReasons`.
-
-To manually run the suites, use the following command:
-
-```bash
-third_party/blink/tools/run_web_tests.py -t Default virtual/not-restored-reasons/external/wpt/performance-timeline/not-restored-reasons/
-```
\ No newline at end of file
diff --git a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt b/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
index 1fc2cf8..2bbefe07 100644
--- a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
+++ b/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
@@ -223,6 +223,7 @@
 imageOrientation
 imageRendering
 inherits
+initialLetter
 initialValue
 inlineSize
 inset
diff --git a/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt b/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
index 08614c3..cfbf1cc 100644
--- a/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
@@ -216,6 +216,7 @@
     hyphens
     image-orientation
     image-rendering
+    initial-letter
     inline-size
     inset-block-end
     inset-block-start
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index 1c357fd..e88fb3e 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -5157,10 +5157,14 @@
 interface MLContext
     attribute @@toStringTag
     method constructor
+interface MLGraph
+    attribute @@toStringTag
+    method constructor
 interface MLGraphBuilder
     attribute @@toStringTag
     method add
     method averagePool2d
+    method buildAsync
     method clamp
     method constant
     method constructor
diff --git a/third_party/wayland-protocols/BUILD.gn b/third_party/wayland-protocols/BUILD.gn
index a4d6b98..d513d6b 100644
--- a/third_party/wayland-protocols/BUILD.gn
+++ b/third_party/wayland-protocols/BUILD.gn
@@ -9,7 +9,7 @@
 # is special: that is the wayland-protocols package which defines a set of
 # standardised protocols.  When using the system libwayland for the client, we
 # should use the manifest files provided in the sysroot.
-if (use_system_libwayland_client && use_sysroot) {
+if (use_system_libwayland && use_sysroot) {
   standard_protocol_prefix = "${sysroot}/usr/share/wayland-protocols"
 } else {
   standard_protocol_prefix = "src"
diff --git a/third_party/wayland/BUILD.gn b/third_party/wayland/BUILD.gn
index ec0b9a1e..d60491d 100644
--- a/third_party/wayland/BUILD.gn
+++ b/third_party/wayland/BUILD.gn
@@ -7,10 +7,10 @@
 import("//third_party/wayland/wayland_protocol.gni")
 import("//tools/generate_stubs/rules.gni")
 
-# This should be open to both system and non - system libwayland as wayland_stubs
-# also uses this.
+# This should be open to both system and non - system libwayland as
+# wayland_stubs also uses this.
 wayland_protocol("wayland_protocol_c") {
-  if (use_system_libwayland_client && use_sysroot) {
+  if (use_system_libwayland && use_sysroot) {
     sources = [ "${sysroot}/usr/share/wayland/wayland.xml" ]
   } else {
     sources = [ "src/protocol/wayland.xml" ]
@@ -18,7 +18,7 @@
   generator_type = "protocol-marshalling"
 }
 
-if (!use_system_libwayland_client || !use_system_libwayland_server) {
+if (!use_system_libwayland) {
   config("wayland_config") {
     include_dirs = [
       "include",
@@ -57,11 +57,7 @@
     configs -= [ "//build/config/compiler:chromium_code" ]
     configs += [ "//build/config/compiler:no_chromium_code" ]
 
-    if (use_system_libwayland_client) {
-      configs += [ ":wayland_config" ]
-    } else {
-      public_configs = [ ":wayland_config" ]
-    }
+    public_configs = [ ":wayland_config" ]
   }
 
   static_library("wayland_private") {
@@ -79,20 +75,9 @@
       "//build/config/linux/libffi",
     ]
 
-    if (use_system_libwayland_client) {
-      configs += [ ":wayland_config" ]
-    } else {
-      public_configs = [ ":wayland_config" ]
-    }
+    public_configs = [ ":wayland_config" ]
   }
-} else {
-  # use_system_libwayland_client && use_system_libwayland_server
-  group("wayland_util") {
-    public_configs = [ ":wayland_client_config" ]
-  }
-}
 
-if (!use_system_libwayland_server) {
   static_library("wayland_server") {
     sources = [
       "src/src/event-loop.c",
@@ -116,23 +101,9 @@
       "//build/config/linux/libffi",
     ]
 
-    if (use_system_libwayland_client) {
-      configs += [ ":wayland_config" ]
-    } else {
-      public_configs = [ ":wayland_config" ]
-    }
-  }
-} else {
-  pkg_config("wayland_server_config") {
-    packages = [ "wayland-server" ]
+    public_configs = [ ":wayland_config" ]
   }
 
-  group("wayland_server") {
-    public_configs = [ ":wayland_server_config" ]
-  }
-}
-
-if (!use_system_libwayland_client) {
   static_library("wayland_client") {
     sources = [ "src/src/wayland-client.c" ]
 
@@ -190,35 +161,20 @@
       ":wayland_config",
     ]
   }
-}
-
-if (!use_system_wayland_scanner) {
-  config("wayland_scanner_config") {
-    cflags = [
-      "-Wno-int-conversion",
-      "-Wno-implicit-function-declaration",
-    ]
-
-    include_dirs = [ "include/" ]
+} else {
+  # use_system_libwayland
+  pkg_config("wayland_server_config") {
+    packages = [ "wayland-server" ]
   }
 
-  executable("wayland_scanner") {
-    sources = [ "src/src/scanner.c" ]
-
-    deps = [
-      ":wayland_util",
-      "//third_party/expat:expat",
-    ]
-
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [
-      "//build/config/compiler:no_chromium_code",
-      ":wayland_scanner_config",
-    ]
+  group("wayland_server") {
+    public_configs = [ ":wayland_server_config" ]
   }
-}
 
-if (use_system_libwayland_client) {
+  group("wayland_util") {
+    public_configs = [ ":wayland_client_config" ]
+  }
+
   pkg_config("wayland_client_config") {
     packages = [ "wayland-client" ]
   }
@@ -274,3 +230,29 @@
     deps = [ ":wayland_protocol_c" ]
   }
 }
+
+if (!use_system_wayland_scanner) {
+  config("wayland_scanner_config") {
+    cflags = [
+      "-Wno-int-conversion",
+      "-Wno-implicit-function-declaration",
+    ]
+
+    include_dirs = [ "include/" ]
+  }
+
+  executable("wayland_scanner") {
+    sources = [ "src/src/scanner.c" ]
+
+    deps = [
+      ":wayland_util",
+      "//third_party/expat:expat",
+    ]
+
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [
+      "//build/config/compiler:no_chromium_code",
+      ":wayland_scanner_config",
+    ]
+  }
+}
diff --git a/third_party/wayland/features.gni b/third_party/wayland/features.gni
index 1d3f1e3..88246f3 100644
--- a/third_party/wayland/features.gni
+++ b/third_party/wayland/features.gni
@@ -8,25 +8,15 @@
 import("//build/config/sysroot.gni")
 
 declare_args() {
-  # This variable is deprecated.  use_system_libwayland_client should be used
-  # instead.
+  # Controls whether the build should use the version of Wayland
+  # library shipped with the system or Chromium third_party.
   use_system_libwayland = false
-
-  # Controls whether the build should use the version of Wayland
-  # library shipped with the system or Chromium third_party (server library).
-  use_system_libwayland_server = false
-}
-
-declare_args() {
-  # Controls whether the build should use the version of Wayland
-  # library shipped with the system or Chromium third_party (client library).
-  use_system_libwayland_client = use_system_libwayland
 }
 
 declare_args() {
   # This may be set by Chromium packagers who do not wish to use the bundled
   # wayland scanner.
-  use_system_wayland_scanner = use_system_libwayland_client
+  use_system_wayland_scanner = use_system_libwayland
 }
 
 declare_args() {
@@ -41,7 +31,7 @@
   }
 }
 
-if (use_system_libwayland_client) {
+if (use_system_libwayland) {
   # ChromeOS should always be built with the bundled libwayland.
   assert(!is_chromeos)
 }
diff --git a/tools/clang/scripts/expand_thin_archives.py b/tools/clang/scripts/expand_thin_archives.py
index a6b988f..4da74ee 100755
--- a/tools/clang/scripts/expand_thin_archives.py
+++ b/tools/clang/scripts/expand_thin_archives.py
@@ -14,8 +14,8 @@
 import argparse
 import sys
 
-from goma_link import GomaLinkWindows
-from goma_ld import GomaLinkUnix
+from remote_link import RemoteLinkWindows
+from remote_ld import RemoteLinkUnix
 
 
 def main(argv):
@@ -43,9 +43,9 @@
   linker_prefix = args.linker_prefix
 
   if linker_prefix == '-Wl,':
-    linker = GomaLinkUnix()
+    linker = RemoteLinkUnix()
   else:
-    linker = GomaLinkWindows()
+    linker = RemoteLinkWindows()
 
   rsp_expanded = list(linker.expand_args_rsps(cmdline))
   expanded_args = list(linker.expand_thin_archives(rsp_expanded))
diff --git a/tools/clang/scripts/goma_ld.py b/tools/clang/scripts/remote_ld.py
similarity index 86%
rename from tools/clang/scripts/goma_ld.py
rename to tools/clang/scripts/remote_ld.py
index 08d0bb6..3ed2111 100755
--- a/tools/clang/scripts/goma_ld.py
+++ b/tools/clang/scripts/remote_ld.py
@@ -3,7 +3,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Linker wrapper that performs distributed ThinLTO on Goma.
+# Linker wrapper that performs distributed ThinLTO on Goma or Reclient.
 #
 # Usage: Pass the original link command as parameters to this script.
 # E.g. original: clang++ -o foo foo.o
@@ -13,10 +13,10 @@
 import re
 import sys
 
-import goma_link
+import remote_link
 
 
-class GomaLinkUnix(goma_link.GomaLinkBase):
+class RemoteLinkUnix(remote_link.RemoteLinkBase):
   # Target-platform-specific constants.
   WL = '-Wl,'
   TLTO = '-plugin-opt=thinlto'
@@ -46,7 +46,7 @@
       return None
     if not (args.allowlist or os.path.basename(args.output) in self.ALLOWLIST):
       return None
-    return super(GomaLinkUnix, self).analyze_args(args, *posargs, **kwargs)
+    return super(RemoteLinkUnix, self).analyze_args(args, *posargs, **kwargs)
 
   def process_output_param(self, args, i):
     """
@@ -60,4 +60,4 @@
 
 
 if __name__ == '__main__':
-  sys.exit(GomaLinkUnix().main(sys.argv))
+  sys.exit(RemoteLinkUnix().main(sys.argv))
diff --git a/tools/clang/scripts/goma_link.py b/tools/clang/scripts/remote_link.py
similarity index 95%
rename from tools/clang/scripts/goma_link.py
rename to tools/clang/scripts/remote_link.py
index 12b301d7..783c354 100755
--- a/tools/clang/scripts/goma_link.py
+++ b/tools/clang/scripts/remote_link.py
@@ -3,11 +3,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Linker wrapper that performs distributed ThinLTO on Goma.
+# Linker wrapper that performs distributed ThinLTO on Goma or Reclient.
 #
 # Usage: Pass the original link command as parameters to this script.
 # E.g. original: lld-link -out:foo foo.obj
-# Becomes: goma_link.py lld-link -out:foo foo.obj
+# Becomes: remote_link.py lld-link -out:foo foo.obj
 
 import argparse
 import errno
@@ -33,9 +33,8 @@
   Returns the name of the autoninja executable to invoke.
   """
   name = os.path.normpath(
-      os.path.join(
-          os.path.dirname(__file__), '..', '..', '..', 'third_party',
-          'depot_tools', 'autoninja'))
+      os.path.join(os.path.dirname(__file__), '..', '..', '..', 'third_party',
+                   'depot_tools', 'autoninja'))
   if os.name == 'nt':
     return name + '.bat'
   else:
@@ -171,9 +170,11 @@
   ap.add_argument('--generate',
                   action='store_true',
                   help='generate ninja file, but do not invoke it.')
-  ap.add_argument('--gomacc', help='path to gomacc.')
+  ap.add_argument('--wrapper', help='path to remote exec wrapper.')
   ap.add_argument('--jobs', '-j', help='maximum number of concurrent jobs.')
-  ap.add_argument('--no-gomacc', action='store_true', help='do not use gomacc.')
+  ap.add_argument('--no-wrapper',
+                  action='store_true',
+                  help='do not use remote exec wrapper.')
   ap.add_argument('--allowlist',
                   action='store_true',
                   help='act as if the target is on the allow list.')
@@ -202,12 +203,12 @@
   return subprocess.check_call(cmd, *args, **kwargs)
 
 
-class GomaLinkBase(object):
+class RemoteLinkBase(object):
   """
-  Base class used by GomaLinkUnix and GomaLinkWindows.
+  Base class used by RemoteLinkUnix and RemoteLinkWindows.
   """
   # Defaults.
-  gomacc = 'gomacc'
+  wrapper = 'gomacc'
   jobs = None
 
   # These constants should work across platforms.
@@ -535,15 +536,15 @@
     params and with objs being a list of bitcode files for which to generate
     native code.
     """
-    if self.gomacc:
-      gomacc_prefix = ninjaenc(self.gomacc) + ' '
+    if self.wrapper:
+      wrapper_prefix = ninjaenc(self.wrapper) + ' '
     else:
-      gomacc_prefix = ''
+      wrapper_prefix = ''
     base = gen_dir + '/' + os.path.basename(params.output)
     ensure_dir(gen_dir)
     ensure_dir(os.path.dirname(ninjaname))
     codegen_cmd = ('%s%s -c %s -fthinlto-index=$index %s$bitcode -o $native' %
-                   (gomacc_prefix, ninjaenc(params.compiler),
+                   (wrapper_prefix, ninjaenc(params.compiler),
                     ninjajoin(params.codegen_params), self.XIR))
     if params.index_inputs:
       used_obj_file = base + '.objs'
@@ -615,10 +616,10 @@
     args.output = self.output_path(argv[1:])
     if args.output is None:
       return self._no_codegen(args)
-    if args.gomacc:
-      self.gomacc = args.gomacc
-    if args.no_gomacc:
-      self.gomacc = None
+    if args.wrapper:
+      self.wrapper = args.wrapper
+    if args.no_wrapper:
+      self.wrapper = None
     if args.jobs:
       self.jobs = int(args.jobs)
 
@@ -661,7 +662,7 @@
       return e.returncode
 
 
-class GomaLinkWindows(GomaLinkBase):
+class RemoteLinkWindows(RemoteLinkBase):
   # Target-platform-specific constants.
   WL = ''
   TLTO = '-thinlto'
@@ -707,4 +708,4 @@
 
 
 if __name__ == '__main__':
-  sys.exit(GomaLinkWindows().main(sys.argv))
+  sys.exit(RemoteLinkWindows().main(sys.argv))
diff --git a/tools/clang/scripts/goma_link_integration_tests.py b/tools/clang/scripts/remote_link_integration_tests.py
similarity index 89%
rename from tools/clang/scripts/goma_link_integration_tests.py
rename to tools/clang/scripts/remote_link_integration_tests.py
index b4d2457..12255cc 100755
--- a/tools/clang/scripts/goma_link_integration_tests.py
+++ b/tools/clang/scripts/remote_link_integration_tests.py
@@ -3,20 +3,21 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Integration tests for goma_link.
+# Integration tests for remote_link.
 #
 # Usage:
 #
-# Ensure that gomacc, llvm-objdump, and llvm-dwarfdump are in your PATH.
+# Ensure that gomacc or rewrapper, llvm-objdump, and llvm-dwarfdump are in your
+# PATH.
 # Then run:
 #
-#   tools/clang/scripts/goma_link_integration_tests.py
+#   tools/clang/scripts/remote_link_integration_tests.py
 #
-# See also goma_link_unit_tests.py, which contains unit tests and
+# See also remote_link_unit_tests.py, which contains unit tests and
 # instructions for generating coverage information.
 
-import goma_ld
-import goma_link
+import remote_ld
+import remote_link
 
 from io import StringIO
 import os
@@ -26,7 +27,7 @@
 import unittest
 from unittest import mock
 
-from goma_link_test_utils import named_directory, working_directory
+from remote_link_test_utils import named_directory, working_directory
 
 # Path constants.
 CHROMIUM_DIR = os.path.abspath(
@@ -48,32 +49,32 @@
     f.write('int bar() {\n  return 9;\n}\n')
 
 
-class GomaLinkUnixAllowMain(goma_ld.GomaLinkUnix):
+class RemoteLinkUnixAllowMain(remote_ld.RemoteLinkUnix):
   """
-  Same as goma_ld.GomaLinkUnix, but has "main" on the allow list.
+  Same as remote_ld.RemoteLinkUnix, but has "main" on the allow list.
   """
 
   def __init__(self, *args, **kwargs):
-    super(GomaLinkUnixAllowMain, self).__init__(*args, **kwargs)
+    super(RemoteLinkUnixAllowMain, self).__init__(*args, **kwargs)
     self.ALLOWLIST = {'main'}
 
 
-class GomaLinkWindowsAllowMain(goma_link.GomaLinkWindows):
+class RemoteLinkWindowsAllowMain(remote_link.RemoteLinkWindows):
   """
-  Same as goma_ld.GomaLinkWindows, but has "main" on the allow list.
+  Same as remote_ld.RemoteLinkWindows, but has "main" on the allow list.
   """
 
   def __init__(self, *args, **kwargs):
-    super(GomaLinkWindowsAllowMain, self).__init__(*args, **kwargs)
+    super(RemoteLinkWindowsAllowMain, self).__init__(*args, **kwargs)
     self.ALLOWLIST = {'main.exe'}
 
 
-class GomaLinkIntegrationTest(unittest.TestCase):
+class RemoteLinkIntegrationTest(unittest.TestCase):
   def clangcl(self):
-    return os.path.join(LLVM_BIN_DIR, 'clang-cl' + goma_link.exe_suffix())
+    return os.path.join(LLVM_BIN_DIR, 'clang-cl' + remote_link.exe_suffix())
 
   def lld_link(self):
-    return os.path.join(LLVM_BIN_DIR, 'lld-link' + goma_link.exe_suffix())
+    return os.path.join(LLVM_BIN_DIR, 'lld-link' + remote_link.exe_suffix())
 
   def test_distributed_lto_common_objs(self):
     with named_directory() as d, working_directory(d):
@@ -96,8 +97,8 @@
       with open('my_goma.sh', 'w') as f:
         f.write('#! /bin/sh\n\ngomacc "$@"\n')
       os.chmod('my_goma.sh', 0o755)
-      rc = goma_link.GomaLinkWindows().main([
-          'goma_link.py', '--gomacc', './my_goma.sh', '--',
+      rc = remote_link.RemoteLinkWindows().main([
+          'remote_link.py', '--wrapper', './my_goma.sh', '--',
           self.lld_link(), '-nodefaultlib', '-entry:main', '-out:main.exe',
           '@main.rsp'
       ])
@@ -148,8 +149,8 @@
           ['llvm-ar', 'crsT', 'obj/foobar.lib', 'obj/bar.obj', 'obj/foo.obj'])
       with open('main.rsp', 'w') as f:
         f.write('obj/main.obj\n' 'obj/foobar.lib\n')
-      rc = GomaLinkWindowsAllowMain().main([
-          'goma_link.py', '--gomacc', 'gomacc', '--',
+      rc = RemoteLinkWindowsAllowMain().main([
+          'remote_link.py', '--wrapper', 'gomacc', '--',
           self.lld_link(), '-nodefaultlib', '-entry:main', '-machine:X86',
           '-opt:lldlto=2', '-mllvm:-import-instr-limit=10', '-out:main.exe',
           '@main.rsp'
@@ -194,8 +195,8 @@
       subprocess.check_call([
           self.clangcl(), '-c', '-O2', '-flto=thin', 'foo.cpp', '-Foobj/foo.obj'
       ])
-      rc = goma_link.GomaLinkWindows().main([
-          'goma_link.py', '--generate', '--allowlist', '--',
+      rc = remote_link.RemoteLinkWindows().main([
+          'remote_link.py', '--generate', '--allowlist', '--',
           self.lld_link(), '-nodefaultlib', '-entry:main', '-opt:lldlto=2',
           '-out:main.exe', 'obj/main.obj', 'obj/foo.obj'
       ])
@@ -219,9 +220,9 @@
         self.assertIsNotNone(link_match)
 
 
-class GomaLdIntegrationTest(unittest.TestCase):
+class RemoteLdIntegrationTest(unittest.TestCase):
   def clangxx(self):
-    return os.path.join(LLVM_BIN_DIR, 'clang++' + goma_link.exe_suffix())
+    return os.path.join(LLVM_BIN_DIR, 'clang++' + remote_link.exe_suffix())
 
   def test_nonlto(self):
     with named_directory() as d, working_directory(d):
@@ -230,8 +231,8 @@
           [self.clangxx(), '-c', '-Os', 'main.cpp', '-o', 'main.o'])
       subprocess.check_call(
           [self.clangxx(), '-c', '-Os', 'foo.cpp', '-o', 'foo.o'])
-      rc = GomaLinkUnixAllowMain().main([
-          'goma_ld.py', '--gomacc', 'gomacc', '--',
+      rc = RemoteLinkUnixAllowMain().main([
+          'remote_ld.py', '--wrapper', 'gomacc', '--',
           self.clangxx(), '-fuse-ld=lld', 'main.o', 'foo.o', '-o', 'main'
       ])
       # Should succeed.
@@ -253,8 +254,8 @@
       ])
       subprocess.check_call(
           [self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o'])
-      rc = goma_ld.GomaLinkUnix().main([
-          'goma_ld.py', '--gomacc', 'gomacc', '--',
+      rc = remote_ld.RemoteLinkUnix().main([
+          'remote_ld.py', '--wrapper', 'gomacc', '--',
           self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o',
           'main'
       ])
@@ -277,8 +278,8 @@
       ])
       subprocess.check_call(
           [self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o'])
-      rc = GomaLinkUnixAllowMain().main([
-          'goma_ld.py', '-j', '16', '--',
+      rc = RemoteLinkUnixAllowMain().main([
+          'remote_ld.py', '-j', '16', '--',
           self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o',
           'main'
       ])
@@ -309,8 +310,8 @@
           [self.clangxx(), '-c', '-Os', '-flto=thin', 'bar.cpp', '-o', 'bar.o'])
       subprocess.check_call(
           ['llvm-ar', 'crsT', 'libfoobar.a', 'bar.o', 'foo.o'])
-      rc = GomaLinkUnixAllowMain().main([
-          'goma_ld.py',
+      rc = RemoteLinkUnixAllowMain().main([
+          'remote_ld.py',
           self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'libfoobar.a',
           '-o', 'main'
       ])
@@ -347,8 +348,8 @@
       ])
       subprocess.check_call(
           ['llvm-ar', 'crsT', 'obj/libfoobar.a', 'obj/bar.o', 'obj/foo.o'])
-      rc = GomaLinkUnixAllowMain().main([
-          'goma_ld.py',
+      rc = RemoteLinkUnixAllowMain().main([
+          'remote_ld.py',
           self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'obj/main.o',
           'obj/libfoobar.a', '-o', 'main'
       ])
@@ -381,8 +382,8 @@
       ])
       with open('main.rsp', 'w') as f:
         f.write('obj/main.o\n' 'obj/foo.o\n')
-      rc = GomaLinkUnixAllowMain().main([
-          'goma_ld.py',
+      rc = RemoteLinkUnixAllowMain().main([
+          'remote_ld.py',
           self.clangxx(), '-fuse-ld=lld', '-flto=thin', '-g', '-gsplit-dwarf',
           '-Wl,--lto-O2', '-o', 'main', '@main.rsp'
       ])
@@ -391,8 +392,8 @@
       # Check debug info present, refers to .dwo file, and does not
       # contain full debug info for foo.cpp.
       dbginfo = subprocess.check_output(
-          ['llvm-dwarfdump', '-debug-info', 'main']).decode(
-              'utf-8', 'backslashreplace')
+          ['llvm-dwarfdump', '-debug-info',
+           'main']).decode('utf-8', 'backslashreplace')
       self.assertRegexpMatches(dbginfo, '\\bDW_AT_GNU_dwo_name\\b.*\\.dwo"')
       self.assertNotRegexpMatches(dbginfo, '\\bDW_AT_name\\b.*foo\\.cpp"')
 
@@ -419,8 +420,8 @@
                 '-fwhole-program-vtables\n'
                 'obj/main.o\n'
                 'obj/libfoobar.a\n')
-      rc = GomaLinkUnixAllowMain().main([
-          'goma_ld.py',
+      rc = RemoteLinkUnixAllowMain().main([
+          'remote_ld.py',
           self.clangxx(), '-fuse-ld=lld', '-flto=thin', '-m32', '-Wl,-mllvm',
           '-Wl,-generate-type-units', '-Wl,--lto-O2', '-o', 'main',
           '-Wl,--start-group', '@main.rsp', '-Wl,--end-group'
@@ -460,8 +461,8 @@
       ])
       subprocess.check_call(
           [self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o'])
-      rc = GomaLinkUnixAllowMain().main([
-          'goma_ld.py', '--no-gomacc', '-j', '16', '--',
+      rc = RemoteLinkUnixAllowMain().main([
+          'remote_ld.py', '--no-wrapper', '-j', '16', '--',
           self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o',
           'main'
       ])
@@ -485,8 +486,8 @@
       with open('main.o', 'wb') as f:
         f.write(b'\7fELF')
       with mock.patch('sys.stderr', new_callable=StringIO) as stderr:
-        rc = GomaLinkUnixAllowMain().main([
-            'goma_ld.py', '--generate', '--',
+        rc = RemoteLinkUnixAllowMain().main([
+            'remote_ld.py', '--generate', '--',
             self.clangxx(), 'main.o', '-o', 'main'
         ])
         self.assertEqual(rc, 5)
@@ -497,8 +498,8 @@
       with open('main.o', 'wb') as f:
         f.write(b'BC\xc0\xde')
       with mock.patch('sys.stderr', new_callable=StringIO) as stderr:
-        rc = GomaLinkUnixAllowMain().main([
-            'goma_ld.py', '--generate', '--',
+        rc = RemoteLinkUnixAllowMain().main([
+            'remote_ld.py', '--generate', '--',
             self.clangxx(), 'main.o', '-o', 'main'
         ])
         self.assertEqual(rc, 0)
@@ -520,8 +521,8 @@
       ])
       subprocess.check_call(
           [self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o'])
-      rc = goma_ld.GomaLinkUnix().main([
-          'goma_ld.py', '--generate', '--allowlist', '--',
+      rc = remote_ld.RemoteLinkUnix().main([
+          'remote_ld.py', '--generate', '--allowlist', '--',
           self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o',
           'main'
       ])
diff --git a/tools/clang/scripts/goma_link_test_utils.py b/tools/clang/scripts/remote_link_test_utils.py
similarity index 95%
rename from tools/clang/scripts/goma_link_test_utils.py
rename to tools/clang/scripts/remote_link_test_utils.py
index 156b649..7e320d49 100644
--- a/tools/clang/scripts/goma_link_test_utils.py
+++ b/tools/clang/scripts/remote_link_test_utils.py
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 #
-# Utility classes for testing goma_link.
+# Utility classes for testing remote_link.
 
 import contextlib
 import os
diff --git a/tools/clang/scripts/goma_link_unit_tests.py b/tools/clang/scripts/remote_link_unit_tests.py
similarity index 83%
rename from tools/clang/scripts/goma_link_unit_tests.py
rename to tools/clang/scripts/remote_link_unit_tests.py
index 30b6e6c..f177865 100755
--- a/tools/clang/scripts/goma_link_unit_tests.py
+++ b/tools/clang/scripts/remote_link_unit_tests.py
@@ -3,37 +3,37 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Unit tests for goma_link.
+# Unit tests for remote_link.
 #
 # Usage:
 #
-#   tools/clang/scripts/goma_link_unit_tests.py
+#   tools/clang/scripts/remote_link_unit_tests.py
 #
 # A coverage report combining these tests with the integration tests
-# in goma_link_integration_tests.py can be generated by running:
+# in remote_link_integration_tests.py can be generated by running:
 #
 #   env COVERAGE_FILE=.coverage.unit python3 third_party/pycoverage run \
-#     tools/clang/scripts/goma_link_unit_tests.py
+#     tools/clang/scripts/remote_link_unit_tests.py
 #   env COVERAGE_FILE=.coverage.integration python3 third_party/pycoverage \
-#     run tools/clang/scripts/goma_link_integration_tests.py
+#     run tools/clang/scripts/remote_link_integration_tests.py
 #   python3 third_party/pycoverage combine
 #   python3 third_party/pycoverage html
 #
 # The report will be available as htmlcov/index.html
 
-import goma_ld
-import goma_link
+import remote_ld
+import remote_link
 
 import os
 import unittest
 from unittest import mock
 
-from goma_link_test_utils import named_directory, working_directory
+from remote_link_test_utils import named_directory, working_directory
 
 
 class FakeFs(object):
   """
-  Context manager that mocks the functions through which goma_link
+  Context manager that mocks the functions through which remote_link
   interacts with the filesystem.
   """
 
@@ -50,9 +50,9 @@
     def is_bitcode_file(path):
       return path in self.bitcode_files
 
-    self.mock_ensure_file = mock.patch('goma_link.ensure_file', ensure_file)
+    self.mock_ensure_file = mock.patch('remote_link.ensure_file', ensure_file)
     self.mock_exists = mock.patch('os.path.exists', exists)
-    self.mock_is_bitcode_file = mock.patch('goma_link.is_bitcode_file',
+    self.mock_is_bitcode_file = mock.patch('remote_link.is_bitcode_file',
                                            is_bitcode_file)
 
   def __enter__(self):
@@ -68,20 +68,20 @@
     return exnty is None
 
 
-class GomaLinkUnitTest(unittest.TestCase):
+class RemoteLinkUnitTest(unittest.TestCase):
   """
-  Unit tests for goma_link.
+  Unit tests for remote_link.
   """
 
   def test_analyze_expanded_args_nocodegen(self):
     with FakeFs(other_files=['foo.o', 'bar.o']):
-      self.assertIsNone(goma_ld.GomaLinkUnix().analyze_expanded_args(
+      self.assertIsNone(remote_ld.RemoteLinkUnix().analyze_expanded_args(
           ['clang', 'foo.o', 'bar.o', '-o', 'foo'], 'foo', 'clang', 'lto.foo',
           'common', False))
 
   def test_analyze_expanded_args_one_codegen(self):
     with FakeFs(bitcode_files=['foo.o'], other_files=['bar.o']):
-      result = goma_ld.GomaLinkUnix().analyze_expanded_args(
+      result = remote_ld.RemoteLinkUnix().analyze_expanded_args(
           ['clang', 'foo.o', 'bar.o', '-o', 'foo'], 'foo', 'clang', 'lto.foo',
           'common', False)
       self.assertIsNotNone(result)
@@ -97,7 +97,7 @@
 
   def test_analyze_expanded_args_params(self):
     with FakeFs(bitcode_files=['foo.o']):
-      result = goma_ld.GomaLinkUnix().analyze_expanded_args([
+      result = remote_ld.RemoteLinkUnix().analyze_expanded_args([
           'clang', '-O2', '-flto=thin', '-fsplit-lto-unit',
           '-fwhole-program-vtables', '-fsanitize=cfi', '-g', '-gsplit-dwarf',
           '-mllvm', '-generate-type-units', 'foo.o', '-o', 'foo'
@@ -127,7 +127,7 @@
 
   def test_codegen_params_default(self):
     with FakeFs(bitcode_files=['foo.o'], other_files=['bar.o']):
-      result = goma_ld.GomaLinkUnix().analyze_expanded_args(
+      result = remote_ld.RemoteLinkUnix().analyze_expanded_args(
           ['clang', 'foo.o', 'bar.o', '-o', 'foo'], 'foo', 'clang', 'lto.foo',
           'common', False)
       # Codegen optimization level should default to 2.
@@ -139,7 +139,7 @@
 
   def test_codegen_params_default_cl(self):
     with FakeFs(bitcode_files=['foo.obj'], other_files=['bar.obj']):
-      result = goma_link.GomaLinkWindows().analyze_expanded_args(
+      result = remote_link.RemoteLinkWindows().analyze_expanded_args(
           ['clang-cl', 'foo.obj', 'bar.obj', '-Fefoo.exe'], 'foo.exe',
           'clang-cl', 'lto.foo', 'common', False)
       # Codegen optimization level should default to 2.
@@ -150,7 +150,7 @@
 
   def test_codegen_params_no_data_sections(self):
     with FakeFs(bitcode_files=['foo.o'], other_files=['bar.o']):
-      result = goma_ld.GomaLinkUnix().analyze_expanded_args(
+      result = remote_ld.RemoteLinkUnix().analyze_expanded_args(
           ['clang', '-fno-data-sections', 'foo.o', 'bar.o', '-o', 'foo'], 'foo',
           'clang', 'lto.foo', 'common', False)
       self.assertNotIn('-fdata-sections', result.codegen_params)
@@ -158,7 +158,7 @@
 
   def test_codegen_params_no_function_sections(self):
     with FakeFs(bitcode_files=['foo.o'], other_files=['bar.o']):
-      result = goma_ld.GomaLinkUnix().analyze_expanded_args(
+      result = remote_ld.RemoteLinkUnix().analyze_expanded_args(
           ['clang', '-fno-function-sections', 'foo.o', 'bar.o', '-o', 'foo'],
           'foo', 'clang', 'lto.foo', 'common', False)
       self.assertIn('-fdata-sections', result.codegen_params)
@@ -166,7 +166,7 @@
 
   def test_codegen_params_no_data_sections_cl(self):
     with FakeFs(bitcode_files=['foo.obj'], other_files=['bar.obj']):
-      result = goma_link.GomaLinkWindows().analyze_expanded_args(
+      result = remote_link.RemoteLinkWindows().analyze_expanded_args(
           ['clang-cl', '/Gw-', 'foo.obj', 'bar.obj', '/Fefoo.exe'], 'foo.exe',
           'clang-cl', 'lto.foo', 'common', False)
       self.assertNotIn('-fdata-sections', result.codegen_params)
@@ -176,7 +176,7 @@
 
   def test_codegen_params_no_function_sections_cl(self):
     with FakeFs(bitcode_files=['foo.obj'], other_files=['bar.obj']):
-      result = goma_link.GomaLinkWindows().analyze_expanded_args(
+      result = remote_link.RemoteLinkWindows().analyze_expanded_args(
           ['clang-cl', '/Gy-', 'foo.obj', 'bar.obj', '/Fefoo.exe'], 'foo.exe',
           'clang-cl', 'lto.foo', 'common', False)
       self.assertIn('-Gw', result.codegen_params)
@@ -186,7 +186,7 @@
 
   def test_codegen_params_explicit_data_and_function_sections(self):
     with FakeFs(bitcode_files=['foo.o'], other_files=['bar.o']):
-      result = goma_ld.GomaLinkUnix().analyze_expanded_args([
+      result = remote_ld.RemoteLinkUnix().analyze_expanded_args([
           'clang', '-ffunction-sections', '-fdata-sections', 'foo.o', 'bar.o',
           '-o', 'foo'
       ], 'foo', 'clang', 'lto.foo', 'common', False)
@@ -195,7 +195,7 @@
 
   def test_codegen_params_explicit_data_and_function_sections_cl(self):
     with FakeFs(bitcode_files=['foo.obj'], other_files=['bar.obj']):
-      result = goma_link.GomaLinkWindows().analyze_expanded_args(
+      result = remote_link.RemoteLinkWindows().analyze_expanded_args(
           ['clang-cl', '/Gy', '-Gw', 'foo.obj', 'bar.obj', '/Fefoo.exe'],
           'foo.exe', 'clang-cl', 'lto.foo', 'common', False)
       self.assertIn('-Gw', result.codegen_params)
@@ -206,17 +206,17 @@
   def test_ensure_file_no_dir(self):
     with named_directory() as d, working_directory(d):
       self.assertFalse(os.path.exists('test'))
-      goma_link.ensure_file('test')
+      remote_link.ensure_file('test')
       self.assertTrue(os.path.exists('test'))
 
   def test_ensure_file_existing(self):
     with named_directory() as d, working_directory(d):
       self.assertFalse(os.path.exists('foo/test'))
-      goma_link.ensure_file('foo/test')
+      remote_link.ensure_file('foo/test')
       self.assertTrue(os.path.exists('foo/test'))
       os.utime('foo/test', (0, 0))
       statresult = os.stat('foo/test')
-      goma_link.ensure_file('foo/test')
+      remote_link.ensure_file('foo/test')
       self.assertTrue(os.path.exists('foo/test'))
       newstatresult = os.stat('foo/test')
       self.assertEqual(newstatresult.st_mtime, statresult.st_mtime)
@@ -224,13 +224,13 @@
   def test_ensure_file_error(self):
     with named_directory() as d, working_directory(d):
       self.assertFalse(os.path.exists('test'))
-      goma_link.ensure_file('test')
+      remote_link.ensure_file('test')
       self.assertTrue(os.path.exists('test'))
-      self.assertRaises(OSError, goma_link.ensure_file, 'test/impossible')
+      self.assertRaises(OSError, remote_link.ensure_file, 'test/impossible')
 
   def test_transform_codegen_param_on_mllvm(self):
     # Regression test for crbug.com/1135234
-    link = goma_ld.GomaLinkUnix()
+    link = remote_ld.RemoteLinkUnix()
     self.assertEqual(
         link.transform_codegen_param_common('-mllvm,-import-instr-limit=20'),
         ['-mllvm', '-import-instr-limit=20'])
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 63af492..c6b702b 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -41623,6 +41623,7 @@
   <int value="4368" label="InteractiveWidgetResizesVisual"/>
   <int value="4369" label="SerivceWorkerFallbackMainResource"/>
   <int value="4370" label="GetDisplayMediaWithoutUserActivation"/>
+  <int value="4371" label="BackForwardCacheNotRestoredReasons"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
@@ -56819,6 +56820,7 @@
   <int value="-2040471724" label="CrOSComponent:disabled"/>
   <int value="-2040360427" label="DesktopScreenshots:disabled"/>
   <int value="-2040115518" label="load-media-router-component-extension"/>
+  <int value="-2039971160" label="UseNAT64ForIPv4Literal:enabled"/>
   <int value="-2039439354"
       label="OmniboxOnDeviceHeadProviderIncognito:disabled"/>
   <int value="-2039343702"
@@ -56949,6 +56951,8 @@
   <int value="-1970672551" label="CanvasContextLostInBackground:disabled"/>
   <int value="-1969636234" label="OmniboxRefinedFocusState:disabled"/>
   <int value="-1969625771" label="MessagesForAndroidOfferNotification:enabled"/>
+  <int value="-1968796101"
+      label="OmniboxRemoveExcessiveRecycledViewClearCalls:disabled"/>
   <int value="-1966445414" label="StylusBatteryStatus:disabled"/>
   <int value="-1965587041" label="omnibox-tab-switch-suggestions"/>
   <int value="-1964730371"
@@ -57056,7 +57060,6 @@
   <int value="-1913801713"
       label="UploadCrashReportsUsingJobScheduler:disabled"/>
   <int value="-1913734393" label="CrosPrivacyHub:disabled"/>
-  <int value="-1913552656" label="VCBackgroundReplace:enabled"/>
   <int value="-1912999136" label="enable-automatic-password-saving:enabled"/>
   <int value="-1911918596" label="WebviewAccelerateSmallCanvases:disabled"/>
   <int value="-1911316813" label="BlockTabUnders:disabled"/>
@@ -57304,6 +57307,7 @@
   <int value="-1766129470" label="DataSaverLiteModeRebranding:disabled"/>
   <int value="-1765004425"
       label="CertificateTransparency2022PolicyAllCerts:disabled"/>
+  <int value="-1764447174" label="UseNAT64ForIPv4Literal:disabled"/>
   <int value="-1763899404" label="LayoutNGTable:enabled"/>
   <int value="-1761695937"
       label="NtpPhotosModuleCustomizedOptInArtWork:enabled"/>
@@ -57716,7 +57720,6 @@
   <int value="-1510524610"
       label="RTCDisallowPlanBOutsideDeprecationTrial:enabled"/>
   <int value="-1508852757" label="CreditCardAutofillTouchBar:disabled"/>
-  <int value="-1508837668" label="VCPortraitRelighting:enabled"/>
   <int value="-1507722271" label="ImprovedDesksKeyboardShortcuts:enabled"/>
   <int value="-1506880454"
       label="SupervisedUserCommittedInterstitials:disabled"/>
@@ -58928,6 +58931,8 @@
   <int value="-816984237" label="OfflinePagesAsyncDownload:enabled"/>
   <int value="-816895294" label="DiscoverApp:disabled"/>
   <int value="-816404462" label="TabGroupsAutoCreate:disabled"/>
+  <int value="-815616832"
+      label="OmniboxRemoveExcessiveRecycledViewClearCalls:enabled"/>
   <int value="-815213125" label="SplitSettings:enabled"/>
   <int value="-814305011" label="BatchFetchRequests:disabled"/>
   <int value="-814097014" label="disable-session-crashed-bubble"/>
@@ -62950,7 +62955,6 @@
   <int value="1643700095" label="PermissionQuietChip:enabled"/>
   <int value="1643712769" label="PrintWithReducedRasterization:enabled"/>
   <int value="1644340731" label="NearbySharingSelfShareUI:enabled"/>
-  <int value="1644405691" label="VCPortraitRelighting:disabled"/>
   <int value="1645141340" label="DesksCloseAll:enabled"/>
   <int value="1645447927" label="MixedContentSiteSetting:disabled"/>
   <int value="1645479440" label="HistoryManipulationIntervention:disabled"/>
@@ -63192,7 +63196,6 @@
   <int value="1800509458" label="DriveFsChromeNetworking:disabled"/>
   <int value="1800603694" label="DXGIWaitableSwapChain:disabled"/>
   <int value="1801585504" label="ContextMenuShopWithGoogleLens:enabled"/>
-  <int value="1802821192" label="VCBackgroundReplace:disabled"/>
   <int value="1802874714" label="QueryTilesEnableQueryEditing:disabled"/>
   <int value="1803465156" label="enable-zero-suggest-most-visited"/>
   <int value="1803470125" label="SyncUSSSessions:enabled"/>
@@ -64611,6 +64614,14 @@
   <int value="2" label="Other failure"/>
 </enum>
 
+<enum name="ManagedModeBlockingCommand">
+  <int value="0" label="Preview"/>
+  <int value="1" label="Back"/>
+  <int value="2" label="New Tab Page"/>
+  <int value="3" label="Remote Access Request"/>
+  <int value="4" label="Local Access Request"/>
+</enum>
+
 <enum name="ManagedUserPasswordChange">
   <int value="0" label="OK_MANAGER">Changed in manager session</int>
   <int value="1" label="OK_MANGED">Changed in supervised user session</int>
diff --git a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
index 60bee55..ac38462 100644
--- a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
+++ b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
@@ -678,7 +678,7 @@
 
 <histogram name="TrustedWebActivity.QualityEnforcementViolation"
     enum="TrustedWebActivityQualityEnforcementViolationType"
-    expires_after="M104">
+    expires_after="2023-06-30">
   <owner>eirage@chromium.org</owner>
   <owner>peconn@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/families/histograms.xml b/tools/metrics/histograms/metadata/families/histograms.xml
index 3cb93108..119b7d5 100644
--- a/tools/metrics/histograms/metadata/families/histograms.xml
+++ b/tools/metrics/histograms/metadata/families/histograms.xml
@@ -498,6 +498,13 @@
   </token>
 </histogram>
 
+<histogram name="ManagedMode.BlockingInterstitialCommand"
+    enum="ManagedModeBlockingCommand" expires_after="2023-03-26">
+  <owner>agawronska@google.com</owner>
+  <owner>cros-families-eng@google.com</owner>
+  <summary>Which command was selected from the blocking interstitial.</summary>
+</histogram>
+
 <histogram name="ManagedUsers.BlockedIframeCount" units="iframes"
     expires_after="2023-03-26">
   <owner>yilkal@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/input/histograms.xml b/tools/metrics/histograms/metadata/input/histograms.xml
index f082727..0094246 100644
--- a/tools/metrics/histograms/metadata/input/histograms.xml
+++ b/tools/metrics/histograms/metadata/input/histograms.xml
@@ -649,7 +649,7 @@
 </histogram>
 
 <histogram name="InputMethod.Commit.Type2" enum="IMECommitType2"
-    expires_after="2022-05-01">
+    expires_after="2023-05-01">
   <owner>dvallet@chromium.org</owner>
   <owner>shuchen@chromium.org</owner>
   <owner>essential-inputs-team@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml
index b342d855..60aa6d1 100644
--- a/tools/metrics/histograms/metadata/webapps/histograms.xml
+++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -459,28 +459,6 @@
   </summary>
 </histogram>
 
-<histogram name="WebApp.Icon.AppsWithAppServiceFallbackIcon" units="web apps"
-    expires_after="2023-08-01">
-  <owner>alancutter@chromium.org</owner>
-  <owner>desktop-pwas-team@google.com</owner>
-  <summary>
-    Records the number of web apps that have fallback icons served by app
-    service. This gets recorded at browser profile start up in both the Lacros
-    and Ash processes.
-  </summary>
-</histogram>
-
-<histogram name="WebApp.Icon.AppsWithAppServiceMissingIcon" units="web apps"
-    expires_after="2023-08-01">
-  <owner>alancutter@chromium.org</owner>
-  <owner>desktop-pwas-team@google.com</owner>
-  <summary>
-    Records the number of web apps that have missing icons served by app
-    service. This gets recorded at browser profile start up in both the Lacros
-    and Ash processes.
-  </summary>
-</histogram>
-
 <histogram name="WebApp.Icon.AppsWithEmptyDownloadedIconSizes" units="web apps"
     expires_after="2023-08-01">
   <owner>alancutter@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 756e1e7..66871656 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "d625ef60494ca567d77d0803c9765f8120530e16",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/750df6fbf0d2bb50332cf49e00bca15dca2e6735/trace_processor_shell.exe"
+            "hash": "149ebb6934644c56b8afc439bbb8aea028c5c6d7",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/129b11632395a84eb3307d72fde9a90945e18619/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "mac": {
-            "hash": "5066d38c3b61c3e7b96bcec31e3c04a334e222bb",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/4fcf7d61f3559fdb37fefda36e272f05e40f0fef/trace_processor_shell"
+            "hash": "bdcf41f20eed52f8ec742667c872422a528047b9",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/129b11632395a84eb3307d72fde9a90945e18619/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
             "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "9d44d2f8ea3c5cc84da4a5a2c9296e9b80fd2fc4",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/750df6fbf0d2bb50332cf49e00bca15dca2e6735/trace_processor_shell"
+            "hash": "29ea2dc97e09e8e9a6ec275957ae58a58e89a5c8",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/129b11632395a84eb3307d72fde9a90945e18619/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
index ee4f27e..e0f0d7d 100644
--- a/ui/ozone/platform/wayland/BUILD.gn
+++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -345,7 +345,7 @@
     ]
   }
 
-  if (use_system_libwayland_client) {
+  if (use_system_libwayland) {
     defines += [ "USE_LIBWAYLAND_STUBS" ]
     deps += [ "//third_party/wayland:wayland_stubs" ]
   } else {
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn
index 727253b..aa2598b 100644
--- a/ui/webui/resources/BUILD.gn
+++ b/ui/webui/resources/BUILD.gn
@@ -144,7 +144,6 @@
 checked_in_dts_files = [
   "js/parse_html_subset.d.ts",
   "js/promise_resolver.d.ts",
-  "js/static_types.d.ts",
 ]
 
 # Copies checked-in .d.ts files to the preprocess folder so that they are
@@ -188,6 +187,7 @@
                "js/focus_outline_manager.ts",
                "js/keyboard_shortcut_list.ts",
                "js/plural_string_proxy.ts",
+               "js/static_types.ts",
                "js/store_ts.ts",
                "js/test_loader.ts",
                "js/test_loader_util.ts",
diff --git a/ui/webui/resources/js/BUILD.gn b/ui/webui/resources/js/BUILD.gn
index 48d1fc8..8c9ded73 100644
--- a/ui/webui/resources/js/BUILD.gn
+++ b/ui/webui/resources/js/BUILD.gn
@@ -50,6 +50,7 @@
     "keyboard_shortcut_list.ts",
     "plural_string_proxy.ts",
     "search_highlight_utils.ts",
+    "static_types.ts",
     "store_ts.ts",
     "test_loader.ts",
     "test_loader_util.ts",
@@ -82,7 +83,6 @@
     "load_time_data_deprecated.js",
     "parse_html_subset.js",
     "promise_resolver.js",
-    "static_types.js",
     "util.js",
     "webui_resource_test.js",
   ]
@@ -151,7 +151,6 @@
     ":load_time_data.m",
     ":parse_html_subset",
     ":promise_resolver",
-    ":static_types",
     ":util",
   ]
 }
@@ -184,10 +183,6 @@
   deps = [ ":assert" ]
 }
 
-js_library("static_types") {
-  deps = [ ":assert" ]
-}
-
 js_library("util") {
   deps = [
     ":assert",
diff --git a/ui/webui/resources/js/static_types.d.ts b/ui/webui/resources/js/static_types.d.ts
deleted file mode 100644
index 152e9c2..0000000
--- a/ui/webui/resources/js/static_types.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export function getTrustedHTML(literal: string[]|
-                               TemplateStringsArray): TrustedHTML|string;
-export function getTrustedScript(literal: string[]|
-                                 TemplateStringsArray): TrustedScript|string;
-export function getTrustedScriptURL(literal: string[]|TemplateStringsArray):
-    TrustedScriptURL|string;
diff --git a/ui/webui/resources/js/static_types.js b/ui/webui/resources/js/static_types.js
deleted file mode 100644
index 63205c6..0000000
--- a/ui/webui/resources/js/static_types.js
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {assertNotReached} from './assert.js';
-
-/** @typedef {!Array<string>} */
-let TaggedLiterals;
-
-/**
- * @param {!TaggedLiterals} arr
- * @return {boolean} Whether the passed tagged template literal is a valid
- *     array.
- */
-function isValidArray(arr) {
-  if (arr instanceof Array && Object.isFrozen(arr)) {
-    return true;
-  }
-
-  return false;
-}
-
-/**
- * Checks if the passed tagged template literal only contains static string.
- * And return the string in the literal if so.
- * @param {!TaggedLiterals} literal
- * @return {string}
- * @throws {Error} If the passed argument is not supported literals.
- */
-function getStaticString(literal) {
-  if (isValidArray(literal) && !!literal.raw && isValidArray(literal.raw) &&
-      literal.length === literal.raw.length && literal.length === 1) {
-    return literal.join('');
-  }
-
-  assertNotReached('Static Types only allows static Template literals');
-}
-
-/**
- * @param {string} ignore
- * @param {!TaggedLiterals} literal
- * @return {string}
- */
-function createTypes(ignore, literal) {
-  return getStaticString(literal);
-}
-
-/**
- * Rules used to enforce static literal checks.
- * @type {!TrustedTypePolicyOptions}
- * @suppress {checkTypes}
- */
-const rules = {
-  createHTML: createTypes,
-  createScript: createTypes,
-  createScriptURL: createTypes,
-};
-
-/**
- * This policy returns Trusted Types if the passed literal is static.
- * @type {!TrustedTypePolicy|!TrustedTypePolicyOptions}
- */
-let staticPolicy;
-if (window.trustedTypes) {
-  staticPolicy = trustedTypes.createPolicy('static-types', rules);
-} else {
-  staticPolicy = rules;
-}
-
-/**
- * @param {!TaggedLiterals} literal
- * @return {!TrustedHTML|string} Returns TrustedHTML if the passed literal is
- *     static.
- * @suppress {checkTypes}
- */
-export function getTrustedHTML(literal) {
-  return staticPolicy.createHTML('', literal);
-}
-
-/**
- * @param {!TaggedLiterals} literal
- * @return {!TrustedScript|string} Returns TrustedScript if the passed literal
- *     is static.
- * @suppress {checkTypes}
- */
-export function getTrustedScript(literal) {
-  return staticPolicy.createScript('', literal);
-}
-
-/**
- * @param {!TaggedLiterals} literal
- * @return {!TrustedScriptURL|string} Returns TrustedScriptURL if the passed
- *     literal is static.
- * @suppress {checkTypes}
- */
-export function getTrustedScriptURL(literal) {
-  return staticPolicy.createScriptURL('', literal);
-}
diff --git a/ui/webui/resources/js/static_types.ts b/ui/webui/resources/js/static_types.ts
new file mode 100644
index 0000000..4ff882f
--- /dev/null
+++ b/ui/webui/resources/js/static_types.ts
@@ -0,0 +1,77 @@
+// Copyright 2021 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {assert} from './assert_ts.js';
+
+/**
+ * @return Whether the passed tagged template literal is a valid array.
+ */
+function isValidArray(arr: TemplateStringsArray|readonly string[]): boolean {
+  if (arr instanceof Array && Object.isFrozen(arr)) {
+    return true;
+  }
+
+  return false;
+}
+
+/**
+ * Checks if the passed tagged template literal only contains static string.
+ * And return the string in the literal if so.
+ * Throws an Error if the passed argument is not supported literals.
+ */
+function getStaticString(literal: TemplateStringsArray): string {
+  const isStaticString = isValidArray(literal) && !!literal.raw &&
+      isValidArray(literal.raw) && literal.length === literal.raw.length &&
+      literal.length === 1;
+  assert(isStaticString, 'static_types.js only allows static strings');
+
+  return literal.join('');
+}
+
+function createTypes(_ignore: string, literal: TemplateStringsArray): string {
+  return getStaticString(literal);
+}
+
+/**
+ * Rules used to enforce static literal checks.
+ */
+const rules: TrustedTypePolicyOptions = {
+  createHTML: createTypes,
+  createScript: createTypes,
+  createScriptURL: createTypes,
+};
+
+/**
+ * This policy returns Trusted Types if the passed literal is static.
+ */
+let staticPolicy: TrustedTypePolicy|TrustedTypePolicyOptions;
+if (window.trustedTypes) {
+  staticPolicy = window.trustedTypes.createPolicy('static-types', rules);
+} else {
+  staticPolicy = rules;
+}
+
+/**
+ * Returns TrustedHTML if the passed literal is static.
+ */
+export function getTrustedHTML(literal: TemplateStringsArray): (TrustedHTML|
+                                                                string) {
+  return staticPolicy.createHTML!('', literal);
+}
+
+/**
+ * Returns TrustedScript if the passed literal is static.
+ */
+export function getTrustedScript(literal: TemplateStringsArray): (TrustedScript|
+                                                                  string) {
+  return staticPolicy.createScript!('', literal);
+}
+
+/**
+ * Returns TrustedScriptURL if the passed literal is static.
+ */
+export function getTrustedScriptURL(literal: TemplateStringsArray):
+    (TrustedScriptURL|string) {
+  return staticPolicy.createScriptURL!('', literal);
+}